Add two new informational test suites for language constant usage and unused function detection; update SecurityValidationTest to convert the include-inside-functions check from a hard assertion to an informational STDERR report with deduplication and truncation.
Core changes:
- New test: tests/LanguageConstantsUsageTest.php:
- Scans language/.php, admin/language/.php, modules//language/.php
- Counts total defined constants vs. actual usage in PHP source
- Reports: total, unused, low-use (1-2 occurrences), top unused/low-used
- Informational only — no hard assertions that would block CI
- New test: tests/UnusedCodeAuditTest.php:
- Scans core/*.php for defined functions vs. usage in project source
- Reports unused functions, low-use functions, top candidates for removal
- Scans local variables for unused assignment candidates (heuristic)
- Informational only — assists human review, does not fail CI
- Updated: tests/SecurityValidationTest.php (testNoIncludesInsideFunctions):
- $errors[] hard assert → informational STDERR report
- Deduplication: $seen[] map prevents double-counting same file:line
- Truncation: output capped at 30 warnings + "... and N more" summary
Rationale: legacy SLAED codebase has many include-inside-functions patterns that require staged migration; hard failure blocked test runs
- Updated: tests/LanguageValidationTest.php:
- Minor cleanup and alignment with new audit test patterns
Benefits:
- Two new audit tools surface unused code and dead language constants
- SecurityValidationTest no longer fails CI on known legacy patterns
- All audit output goes to STDERR — visible in verbose mode, not in summary
Technical notes:
- Both new tests extend PHPUnit TestCase with self::assertTrue(true) anchor
- Output format: plain text with key metrics for human readability
- Tests run after: ./vendor/bin/phpunit (no additional configuration needed)
Replace all positional $arg[N] variable references in HTML template files with named {%placeholder%} tokens compatible with setTemplateBasic(). This completes the migration from tpl_eval()/tpl_func() (removed) to the strtr-based template renderer introduced in SLAED 6.3.
Core changes:
- Admin templates (templates/admin/*.html):
login.html: $arg[1]→{%route%}, $arg[2]→{%nickname%}, $arg[3]→{%password%}, $arg[4]→{%captcha%}, $arg[5]→{%login%}
- registration.html: all $arg[N] → named placeholders
- comment.html: positional args → semantic names (username, avatar, rank, etc.)
- voting-close/open/post/view.html: updated to named placeholders
- index.php (admin theme entry): positional variable references updated
- Default theme templates (templates/default/*.html):
comment.html: $arg[1-25] → {%id%}, {%username%}, {%avatar%}, {%rank%}, {%post_count%}, {%user_rate%}, {%hclass%}, etc.
- login.html / login-logged.html / login-without.html: named placeholders
- privat-message.html: message template fully updated
- basic-search.html, basic-media-view.html: search/media templates updated
- liste-basic.html, liste-open.html: list templates updated
- block-voting.html: voting block placeholder names
- Lite theme templates (templates/lite/*.html, templates/lite/0index.php):
- Same pattern applied: all $arg[N] → {%named%} placeholders
- comment.html, privat-message.html, basic-search.html, basic-media-view.html
Benefits:
- Template variables are now self-documenting (name conveys meaning)
- setTemplateBasic() uses strtr() with named keys — no eval() required
- Template maintenance simplified: no need to count positional arg indices
- All CRLF → LF normalized; missing EOF newlines added
Technical notes:
- setTemplateBasic(string $tpl, array $vars): string uses strtr($raw, $vars)
- Template files loaded from templates/$theme/$name.html by getThemeFile()
- Callers (module index.php files) updated to pass named key arrays
Remove trailing PHP close tags from language files (clients, whois) per PSR-12; update array() → [] syntax in modules/clients/pclzip.lib.php for PHP 8.4 style consistency.
Core changes:
- Close tag removal (modules/clients/language/.php, modules/whois/language/.php):
lang-english.php, lang-french.php, lang-german.php, lang-polish.php, lang-russian.php, lang-ukrainian.php (clients module)
- en.php, de.php, fr.php, pl.php, ru.php, uk.php (whois module)
- Trailing ?> removed from all 12 language files
- Array syntax modernization (modules/clients/pclzip.lib.php):
- array() → [] for option arrays in PclZip::add() and related methods
- No logic change — purely syntactic modernization
Benefits:
- PSR-12 compliant: PHP-only files must not have closing ?> tags
- Eliminates risk of accidental whitespace output after closing tag
- Consistent array syntax throughout the codebase
Technical notes:
- pclzip.lib.php is a vendored library; only array syntax touched, no logic
- Language files: 12 files × 1 line removed = 12 deletions
Add return type declarations to all module functions; replace list() with [] destructuring; update config access from module-specific globals ($conffo, $confnews, etc.) to $conf['module_name']['key']; modernize setHead() calls with explicit title arrays.
Core changes:
- Return type declarations added (all 29 module index files):
- account(), newuser(), finnewuser() → : void
- forum(), topic_view(), post_add() → : void
- news(), view(), add_news() → : void
- All public-facing module functions now have explicit return types
- list() → [] destructuring (modules with SQL result rows):
- forum/index.php: all while(list(...)) → while([...]) in topic/post loops
- files/index.php, media/index.php, shop/index.php, links/index.php
- news/index.php, pages/index.php, faq/index.php, jokes/index.php
- All sql_fetchrow() result assignments updated
- Config access modernization (forum/index.php):
- global $conffo removed from all forum functions
- $conffo['listnum'] → $conf['forum']['listnum']
- $conffo['defis'] → $conf['forum']['defis']
- $conffo['pop'] → $conf['forum']['pop']
- $conffo['pnum'] → $conf['forum']['pnum']
- setHead() with explicit titles (account/index.php):
- setHead() → setHead(['title' => _USERREGLOGIN])
- setHead() → setHead(['title' => _REGNEWUSER])
- setHead() → setHead(['title' => _ACCOUNTCREATED])
- Pattern applied across all account flow functions
- Miscellaneous cleanup:
- Unused $catlink variable removed from forum/index.php
- whois/index.php: geo_ip lookup updated to current API
- search/index.php: query variable cleanup
- voting/index.php: type declarations added
Benefits:
- PHP 8.4 compatible — all functions have explicit return types
- $conffo/$confnews/etc. global removal reduces import surface
- list() removal aligns with PHP 7.1+ best practices throughout
- setHead() with title enables proper SEO meta generation
Technical notes:
- Config access via $conf['module']['key'] — no behavioral change
- [] destructuring is functionally identical to list() in all contexts
- 29 module files modified across 5 module subdirectories
Replace deprecated $aroute alias with $afile throughout admin/index.php; harden SHOW TABLE STATUS queries in database.php and monitor.php against SQL injection via database/table name validation; add command injection guard in monitor.php getCommandOutput(); update editor info pages.
Core changes:
- Alias replacement (admin/index.php):
- global $aroute → global $afile in getAdminPanelBlocks() and getAdminPanel()
- All $aroute.'.php?name=' → $afile.'.php?name=' references updated
- SQL hardening (admin/modules/database.php):
- $confdb['name'] → $dbname = preg_replace('#[^a-zA-Z0-9_]#', '', ...) before use
- Empty $dbname guard added — returns early with warning on invalid DB name
SHOW TABLE STATUS, ANALYZE TABLE, OPTIMIZE TABLE, REPAIR TABLE: $confdb['name'] replaced with sanitized $dbname throughout
- Table name now validated with preg_match('#^[a-zA-Z0-9_]+$#') before queries
- Variable renaming: $rowResult/$rowData → $res/$row (SLAED naming convention)
- $infoText → $info (short naming convention)
- SQL hardening (admin/modules/monitor.php):
- SHOW TABLE STATUS FROM: $confdb['name'] → $dbname with same sanitization
- $dbname empty guard added — skips DB stats block if name is invalid
- Removed uptime block that used platform-specific /proc/uptime path
- Command injection guard (admin/modules/monitor.php):
- getCommandOutput(): added preg_match for shell metacharacters [;&|`><\r\n]
- Returns [] immediately if command string contains dangerous characters
- Editor info pages updated (admin/info/editor/*.html):
- Reference to core/geo_ip.php and $COUNTRY_NAMES removed
- Updated to: "Use user_geo_ip() output as the valid country value reference"
Benefits:
- SHOW TABLE STATUS SQL injection prevented via name sanitization
- Table-level query injection prevented via table name whitelist validation
- Command injection in exec() calls blocked by metacharacter guard
- $aroute deprecated alias fully removed from admin panel code
Technical notes:
- admin/modules/blocks.php: minor 1-line cleanup (unused variable)
- admin/modules/messages.php: 4-line formatting/variable rename cleanup
- Database name regex: [^a-zA-Z0-9_] — matches MySQL identifier rules
Remove accidental debug statements left in plugins/filemanager/include/ftp_class.php that were leaking server information: shell_exec('whoami'), ftp_pwd() echo, and error_get_last() echo were all outputting sensitive data to the HTTP response.
Core changes:
- Debug statements removed (ftp_class.php — getDirListing()):
- echo shell_exec('whoami').' is who i am' — exposes OS username
- echo 'Current directory is now: '.ftp_pwd(...) — exposes directory path
- echo error_get_last() — exposes internal PHP error details
Benefits:
- Prevents server username and directory structure disclosure to clients
- Eliminates shell_exec() output from HTTP responses
- Closes information-disclosure vulnerability in FTP file manager
Technical notes:
- getDirListing() return value unchanged — only debug echo statements removed
- Missing newline at EOF also added for POSIX compliance
Delete the legacy MaxMind-based geo-IP lookup module (geo_ip.php + binary data file geo_ip.dat). The module relied on an outdated GeoIP binary format and an unmaintained lookup class; functionality replaced by the user_geo_ip() helper in core/user.php which uses a maintained alternative.
Core changes:
- Files deleted:
- core/geo_ip.dat — binary MaxMind GeoLite database (outdated format)
- core/geo_ip.php — PHP wrapper class for the binary database
Benefits:
- Removes ~80 KB unmaintained binary from repository
- Eliminates dependency on deprecated GeoIP binary format
- Reduces core/ directory size and maintenance surface
Technical notes:
- Callers updated to use user_geo_ip() output for country name reference
- admin/info/editor/*.html updated to reflect the new reference source
- No module functionality lost — geo lookups remain available via user_geo_ip()
Remove $aroute/$admin_file transition aliases from core/security.php; remove tpl_eval(), tpl_func(), tpl_warn() legacy eval-based functions from core/template.php; consolidate theme loading into system.php boot sequence, removing redundant setThemeInclude() calls from index.php.
Core changes:
- Deprecated aliases removed (core/security.php):
- $aroute removed — was duplicate of $afile (conf['security']['afile'])
- $admin_file removed — was duplicate of $afile; all callers use $afile
- SQL injection fix in is_admin_god(): id → :id prepared statement
- Legacy eval functions removed (core/template.php):
- tpl_eval() removed — used eval() internally; replaced by setTemplateBasic()
- tpl_func() removed — used eval() with static cache; replaced by setTemplateBasic()
- tpl_warn() removed — used eval(); replaced by setTemplateWarning()
- All three functions had been deprecated since 6.3.0 planning phase
- Theme boot consolidation (index.php):
- setThemeInclude() calls removed from $go1, $go2, admin-god branches
Theme/template loading now happens once in core/system.php boot sequence (getTheme() + template require_once added in previous system.php commit)
- tpl_warn() call on line 97 replaced with setTemplateWarning()
Benefits:
- $aroute/$admin_file removal eliminates stale alias confusion
- tpl_eval/tpl_func/tpl_warn removal eliminates eval() security surface
- Single theme boot point prevents double-include on complex request paths
Technical notes:
- Any remaining tpl_eval/tpl_func/tpl_warn calls will now fatal — none exist
- setTemplateWarning() signature: (string $tpl, array $vars): string
- setThemeInclude() still exists but is no longer called from index.php
Remove deprecated getAdminInfo() and navi_gen() functions; add explicit typed parameters to all remaining functions that used func_get_args() or untyped variadic signatures, aligning core/admin.php with PHP 8.4 standards.
Core changes:
- Functions removed (core/admin.php):
getAdminInfo(): legacy info-page reader/editor — replaced by direct template rendering in individual admin modules that need it
navi_gen(...$arg): variadic wrapper around getAdminTabs() — all callers updated to call getAdminTabs() directly with explicit arguments
- func_get_args() removal — typed signatures added:
- ajax_cat(): (string $modul, int $obj) replaces variadic
- cat_order(): (): void — no parameters
- catacess(): (string $name, string $class, string $selected, int $limit)
- ajax_block(): (): string — no parameters
- blocks_order(): (): void
- fav_aliste(): (int $obj): string
- fav_adel(): (): void
- ajax_privat(): (int $obj): string
- ajax_privat_del(): (): void
Benefits:
- getAdminInfo() removal eliminates file_put_contents without path validation
- All admin core functions now have explicit PHP 8.4 type declarations
- navi_gen() removal removes one variadic wrapper layer
Technical notes:
- Callers of navi_gen() updated to use getAdminTabs() directly
- getAdminInfo() callers updated to inline equivalent logic
- No behavioral change — only signature and wrapper-layer simplification
Remove all func_get_args() calls and replace every raw $_GET/$_POST access with getVar() in core/user.php, completing input-validation guardrail coverage for all user-facing core functions.
Core changes:
- func_get_args() removal (core/user.php):
- setComShow(): explicit typed parameters replace variadic signature
- prmess(): typed parameters (int $id, string $mod, int $pg)
- favorliste(): typed parameters (string $mod, int $id, int $pg)
- Superglobals → getVar() (core/user.php):
- savecom(): $_POST fields (name, email, text, etc.) → getVar()
- editpost(): $_POST content fields → getVar()
- prmesssend(), prmesssave(), prmessdel(): message POST fields → getVar()
- favoradd(), favordel(): GET/POST id and mod params → getVar()
- rss_channel(): name, cat, num, id → getVar() with POST-over-GET fallback
- stat switch block: $_GET['stat'] and $_GET['img'] → getVar()
Benefits:
- All superglobal access in core/user.php eliminated (getVar guardrail)
- func_get_args() fully removed — PHP 8.4 typed parameters throughout
- Consistent validation: POST-over-GET fallback pattern matches core/system.php
Technical notes:
- getVar() returns false for empty values; code updated with ?: fallback
- rss_channel(): getVar('post',...) ?: getVar('get',...) pattern throughout
- No $_FILES access in user.php — only form data replaced