Two menu links pointed to deprecated HTTP URLs on old domains.
Core changes:
- templates/lite/index.php:
- http://www.slaed.in -> https://slaed.de (themes/templates link)
- http://www.slaed.info -> https://slaed.info (PHP guide link)
Benefits: - Eliminates mixed-content warnings on HTTPS sites - Reflects current domain structure
Technical notes: - No logic or structural changes; text labels unchanged
Two issues in the auto_links admin add() function corrected.
Core changes:
- auto_links/admin/index.php:
- Add \$stop = \$stop ?? []; guard before first use to prevent undefined var
Remove save_text() wrapper around getVar() calls for a_sitename and a_description: input encoding should happen at save time, not on read
Benefits: - Prevents PHP notice/warning on fresh add form where \$stop is undefined - Separates input retrieval from output encoding responsibility
Technical notes: - save_text() is called correctly in the save handler; reading back raw values from getVar() is the expected pattern for form pre-population
Two consistent patterns updated across nine admin modules to reduce boilerplate and align with the new voting URL routing scheme.
Core changes:
- Anonym author display (8 modules: faq, files, help, jokes, links, media, news, pages):
Replace ($user_name) ? ... : (($uname) ? $uname : ($confu['anonym'] ?? 'Anonym')) with $user_name ?: ($uname ?: $confu['anonym'])
- Removes redundant ?? 'Anonym' fallback; $confu['anonym'] is the canonical default
- Voting admin links (news/admin/index.php, shop/admin/index.php):
- Update ?op=voting_add&id= to ?name=voting&op=add&id=
- Aligns with the new op-based routing in the modernized voting admin module
Benefits: - Consistent null-coalescing style across all content admin modules - Voting edit links work correctly after voting admin module was refactored
Technical notes: - $confu['anonym'] value comes from user config; no hardcoded fallback needed - Encoding pattern for copyright fixed in affected files (faq, files, etc.)
Four admin modules used is_admin_god() as their access guard, allowing only super-admins in. Replaced with is_admin_modul() so module access can be delegated to non-god administrators via the modules config.
Core changes:
- Access guard replacement (four files):
- modules/account/admin/index.php: is_admin_god() -> is_admin_modul('account')
- modules/changelog/admin/index.php: is_admin_god() -> is_admin_modul('changelog')
- modules/rss/admin/index.php: is_admin_god() -> is_admin_modul('rss')
- modules/sitemap/admin/index.php: is_admin_god() -> is_admin_modul('sitemap')
- Additional fixes in the same files:
- account: rename users() to account() to match op dispatch convention
- changelog: remove @ suppressor from file_get_contents()
- sitemap: remove @ suppressor from fopen(); remove BOM from file header
Benefits: - Delegated admin access works correctly for these modules - Error suppression removed; failures are now visible in error logs
Technical notes: - is_admin_modul() reads from $conf['modules'] so no DB query needed - Behavior for god-level admins is unchanged (they pass all module checks)
Renames internal helpers to camelCase, extracts platform detection, and renames template placeholders to snake_case for consistency.
Core changes:
- Monitor module (admin/modules/monitor.php):
- Rename navi() to getMonitorTabs() to avoid collision with module navs
- Extract isWindows() and getServerSoftware() helpers
- Rename get_server_load_data() to getServerLoadData()
Rename template placeholders: ramP/offR/dashD/offD/diskP/pathUp/pathDown to ram_p/off_r/dash_d/off_d/disk_p/path_up/path_down
- Monitor template (templates/admin/basic-monitor.html):
- Update all SVG and chart placeholder tokens to match new snake_case names
Benefits: - Consistent naming convention across admin module helpers - Snake_case template tokens match the broader SLAED template convention
Technical notes: - Placeholder rename is a coordinated change across PHP and HTML - No logic changes; all monitoring metrics and rendering preserved
Rewrites whois admin module to match current SLAED coding standards: typed functions, single-quoted strings, and modern navigation API.
Core changes:
- Navigation (modules/whois/admin/index.php):
- Replace whois_navi() / func_get_args() with typed navi()
- Switch to getAdminTabs() and name=whois&op= URL scheme
- All handler functions:
- Add void return type declarations
- Replace double-quoted strings with single-quoted throughout
- Replace list() with [] destructuring in fetchrow loops
- Replace $admin_file with $afile
Benefits: - Consistent style with other modernized admin modules - Cleaner navigation registration via getAdminTabs()
Technical notes: - Copyright year updated to 2026 - No functional logic changes; all CRUD operations preserved
Rewrites voting admin module to align with the current SLAED admin architecture: typed functions, modern API calls, and clean URL routing.
Core changes:
- Navigation (modules/voting/admin/index.php):
- Replace voting_navi() / func_get_args() pattern with typed navi()
- Use getAdminTabs() and name=voting&op= URL scheme
- All handler functions:
- Add void return type declarations
- Replace $admin_file with $afile, tpl_eval() with setTemplateBasic()
- Replace double-quoted heredoc style with single-quoted strings
- Replace list() with [] destructuring in fetchrow loops
- Admin links:
- Update op=voting_add/delete to name=voting&op=add/delete throughout
Benefits: - Consistent with other modernized admin modules - Typed API reduces silent failures from wrong argument types - URL routing aligned with new op-based dispatch scheme
Technical notes: - Copyright year updated to 2026 - No functional logic changes; all CRUD operations preserved
UNIQUE KEY mid_modul_uid (mid, modul, uid) blocked all guest votes after the first one, because all guests share uid=0. The application already enforces one-vote-per-IP in PHP; the DB key now mirrors that.
Core changes:
- Schema for fresh installs (setup/sql/table.sql):
- Drop UNIQUE KEY mid_modul_uid (mid, modul, uid)
- Add UNIQUE KEY mid_modul_host (mid, modul, host)
- Migration for 6.2 > 6.3 upgrade (setup/sql/table_update6_3.sql):
- Same key replacement applied to the ALTER TABLE block
- Setup wizard (setup/index.php):
- Append deduplication DELETE and key migration queries to update6_3 branch
- DELETE removes duplicate (mid, modul, host) rows keeping earliest id
- ALTER TABLE DROP INDEX IF EXISTS mid_modul_uid (safe if already absent)
- ALTER TABLE ADD UNIQUE KEY mid_modul_host
- Fix unused $key => $val in language() foreach loop
- getInfo() output added to report migration result in the UI
Benefits: - Multiple guests from different IPs can now vote in the same poll - DB-level uniqueness still enforces one vote per IP per item per module - Race-condition protection preserved via $inserted guard (see prev commit)
Technical notes: - host column is VARCHAR(45), covers both IPv4 and IPv6 - PHP duplicate check logic (by host for guests, by uid for users) unchanged - Migration is idempotent: IF EXISTS prevents error on already-applied runs
The voting list page exposed raw $stitle in HTML attribute and JS onclick context, and fetched an unused column from the database.
Core changes:
- voting() (modules/voting/index.php):
- Apply htmlspecialchars($stitle, ENT_QUOTES) in title="" attribute
Apply htmlspecialchars($stitle, ENT_QUOTES) in JS DelCheck() argument to prevent apostrophes from breaking the inline event handler string
- Remove unused 'questions' column from SELECT and list() destructuring
- Remove unused $confv from global declaration in view()
- Replace foreach ($langlist as $key => $val) with $val only
Benefits: - Eliminates attribute-injection risk for admin-authored titles with quotes - Prevents JS syntax error in moderator delete confirmation for special chars - Reduces SELECT payload by one unused column
Technical notes: - $stitle is already HTML-entity encoded at save time via save_text() - htmlspecialchars() adds a second encoding layer safe for attribute context - Behavior preserved; no template or route changes
Previously, if the INSERT into _rating failed (e.g. due to a DB constraint violation), code continued and updated vote counters anyway, causing silent count inflation across all rating-enabled modules.
Core changes:
- Rating function (core/system.php):
- Capture sql_query() result into $inserted
- Wrap all module UPDATE statements and update_points() calls in if ($inserted)
- SELECT + echo ajax_rating() still runs to return current state to client
- avoting_save() (core/system.php):
- Same guard applied to the voting-specific INSERT path
- Vote answer array update and update_points(42) skipped on INSERT fail
- getVoting() result still returned so UI shows current results
Benefits: - Vote counters stay consistent with actual _rating table rows - Eliminates data corruption on duplicate-key or race-condition failures - getVoting() / ajax_rating() always return a response, preserving UX
Technical notes: - sql_query() returns false on PDOException (caught internally) and logs - Fix covers both rating() and avoting_save() code paths - No schema changes in this commit





