Complete the admin module migration: list()->[], setRedirect(), getVar() for all remaining admin panel modules. Includes security.php IP/ban management and statistic/uploads modules.
Core changes:
- privat.php:
- setRedirect() replaces header()+exit; pairs
- ratings.php:
- list() → [] for sql_fetchrow() destructuring
- setRedirect() replaces header()+exit; pairs
- referers.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- replace.php:
- setRedirect() replaces header()+exit; pairs
- security.php (admin module):
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- statistic.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- template.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- uploads.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
Benefits:
- All 22 admin modules now use uniform redirect and array destructuring
- No direct superglobal header() calls remain in admin module layer
Technical notes:
- Purely syntactic/convention migration; zero logic changes
- Backward compatible with existing sessions and DB state
Continue the list()->[], setRedirect(), and getVar() migration across seven more admin modules. All header()+exit; redirect pairs replaced with the centralized setRedirect() helper.
Core changes:
- favorites.php:
- setRedirect() replaces header()+exit; pairs
- fields.php:
- list() → [] for sql_fetchrow() destructuring
- setRedirect() replaces header()+exit; pairs
- groups.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- lang.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- messages.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- modules.php:
- setRedirect() replaces header()+exit; pairs
- newsletter.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
Benefits:
- Consistent redirect handling across all admin modules
- Eliminates legacy list() syntax — short array syntax throughout
Technical notes:
- Logic and DB queries unchanged
- Backward compatible
Replace deprecated list() with short array syntax [], use setRedirect() instead of header()+exit; pairs, switch $_COOKIE reads to getVar(), and fix null-default values on getVar() calls across seven admin modules.
Core changes:
- admins.php:
- list() → [] for sql_fetchrow() destructuring
- getVar('post', 'amodules[]', 'var', []) — explicit empty default
- $_COOKIE['sl_close_9'] → getVar('cookie', 'sl_close_9', 'num', 0)
- setRedirect() replaces header()+exit; pairs
- del(): guard $id > 0 before DELETE query
- blocks.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- getVar defaults corrected
- categories.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- comments.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
- config.php:
- setRedirect() replaces header()+exit; pairs
- database.php:
- setRedirect() replaces header()+exit; pairs
- editor.php:
- list() → [] throughout
- setRedirect() replaces header()+exit; pairs
Benefits:
- Eliminates silent header()/exit anti-pattern; redirects now centralized
- Short array syntax aligns with PHP 7.1+ codebase conventions
- getVar() for cookies prevents direct superglobal access
Technical notes:
- Behavior preserved; no logic changes
- Backward compatible with existing DB schema
Replace the ad-hoc plaintext error log with an AI-ready NDJSON schema (one JSON object per line). Inline closure helpers replace global named functions to avoid namespace pollution, and all sensitive fields are redacted before logging.
Core changes:
- Error log engine (core/security.php):
New schema: timestamp, level, type, message, req_id, ip, method, url, referer, ua, context (query/post/cookie_keys/session_keys), file, line, trace, mem_mb, mem_peak_mb, duration_ms, php_version, slaed_version
Inline closures: \$ls (sanitize/truncate), \$lredact (mask secrets), \$lbound (cap array size), \$lctx (bounded request context), \$lreq, \$lmem, \$lwrite (atomic file append with flock)
- HTTP error handler: logs 403/404/503 with request context + referer
- PHP error handler: logs warnings/notices/fatals with file+line+trace
- Exception handler: logs uncaught exceptions with full stack trace
- Unhandled rejection: register_shutdown_function for fatal errors
Benefits:
- Log entries are machine-parseable — compatible with log aggregators
- Sensitive keys (pass, token, auth, secret, etc.) auto-redacted
- No more log injection: \r \n \0 stripped before writing
- Atomic flock()-based writes prevent concurrent log corruption
Technical notes:
- Log format: NDJSON — one JSON per line, UTF-8, no BOM
- Max 50 GET/POST keys per entry; string values capped at 1024 chars
- Stack traces capped at 10 frames to control log size
- Replaces previous plaintext format — existing log files remain valid
Extend the SEO pipeline with two new template tokens ([headline], [author]) and align core utility functions with the codebase conventions: getVar() for input, resolved absolute paths in checkPerms(), improved getImgText() with [img] BBCode support, and the renamed head()->setHead(array \$seo).
Core changes:
- Schema.org default config (config/global.php):
- Replace "headline": "0" with "headline": "[headline]"
- Replace "name": "[site]" (author) with "name": "[author]"
- System utilities (core/system.php):
Rename head() to setHead(array \$seo = []) — accepts optional SEO fields
- New keys: title, desc, img, time, ctitle, author
- Derive \$headline from \$seo['title'] (plain text, no compound suffix)
- Add [headline] and [author] to SEO from/to replacement arrays
Refactor checkPerms(string \$fp, int \$id) to checkPerms(string \$fp)
- Callers now pass absolute path directly; no id-based base resolution
Extend getImgText() with \$check=true param and [img=…][/img] BBCode
- Supports
and
forms
- \$check=false skips file_exists() for remote/virtual images
- Supports
- Fix fields_in(): explode('|', \$fieldb ?? '') — null-safe coalesce
- Admin core (core/admin.php):
- Replace func_get_args() in getStatistic() with getVar('get', …)
- Fix checkPerms() calls: prepend BASE_DIR.'/' to construct absolute paths
- Declare getStatistic(): void return type
Benefits:
- Schema.org headline and author now populated with real article data
- setHead() API eliminates scattered global variable mutations in modules
- getImgText() handles [img] BBCode variants without regex fragility
Technical notes:
- setHead() is backward-compatible when called with empty array
- All old call sites of head()/foot() must migrate to setHead()/setFoot()
Update the SEO template variable reference string (_TPLVARS) in all six admin UI languages. The [title] description is also clarified to reflect the full composite SEO title (article + category + module + site).
Core changes:
- Language files (admin/language/de.php, en.php, fr.php, pl.php, ru.php, uk.php):
Add [headline] variable — article headline (plain text, no suffixes)
- Used in Schema.org "headline" field
Add [author] variable — article author display name
- Used in Schema.org "author.name" field
- Clarify [title] description to reflect full SEO composition
Benefits:
- Editors can now understand all available SEO tokens at a glance
- Consistent variable docs across all 6 UI languages
Technical notes:
- Change is documentation only (help text); no PHP logic altered
- Backward compatible — existing templates not affected
The regex used to extract table names from INSERT statements could match partial identifiers where a word character preceded the underscore prefix, producing false-positive table matches.
Core changes:
- tests/InsertValidationTest.php:
- Add negative lookbehind (?<!\w) before _(\w+) in INSERT pattern
- Ensures the prefix underscore is only matched at a word boundary
Benefits:
- Eliminates false-positive table name matches in test assertions
- Test results more accurately reflect actual INSERT targets
Technical notes:
- Pattern change is regex-only; test logic and assertions unchanged
- Lookbehind is zero-width and does not affect captured groups
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.)