Eliminate all func_get_args() usage and replace every raw $_GET/$_POST/$_REQUEST access with getVar(); add filterMarkdown() Markdown parser and bb_decode() as a unified text-processing orchestrator; harden SQL with prepared statements.
Core changes:
- func_get_args() removal (core/system.php):
getcat(), catlink(), catids(), catmids() — explicit typed parameters
- catlink($id, $mod, $cat) replaces variadic signature
- getVoting(), num_ajax(), ad_save(), rss_select(), addBackupDb()
- setPageNumbers(), preview(), get_user_search(), url_types()
- addmail(), textarea(), cat_modul(), ashowcom(), numcom(), update_points()
- Superglobals → getVar() (core/system.php):
- goto_url(): $_REQUEST → isset($_GET[..]) || isset($_POST[..]) (presence-only)
- getThemeFile(): $_GET['cat'] → getVar('get', 'cat', 'num', 0)
- save_datetime(): dynamic key → getVar('post'/$name, 'raw', '')
- add_kasse() / del_kasse(): $_GET['id'] → getVar('get', 'id', 'num', 0)
- show_files(): 4 superglobals → getVar() with appropriate types
- fields_in(): $_POST['field'] → getVar('post', 'field', 'raw', '')
- get_user(): $_GET['term'] → getVar('get', 'term', 'text', '')
- ajax_rating(): 5 superglobals (id, typ, mod, rate, stl) → getVar()
- upload(): $_POST['token'], $_POST['sitefile'] → getVar(); $_FILES unchanged
editcom() / closecom() / avoting_save(): redundant isset() → getVar()
- avoting_save(): $_POST['questions'] (array) handled with isset+is_array guard
- SQL prepared statements (core/system.php):
setCategories(): $mod/$locale/$id → named placeholders :mod/:loc/:pid
- catid IN clause now uses dynamic :c0/:c1/... placeholders
- New functions added (core/system.php):
filterMarkdown(string $src, bool $safe, string $mod): string
- Safe Markdown→HTML parser; $safe=true blocks dangerous constructs
- bb_decode(): updated to delegate inline processing to filterMarkdown()
setRedirect(string $url, bool $refer, int $code): never
- Auto-upgrades 302→303 on POST; replaces inline header()+exit patterns
- Theme boot sequence moved to system.php:
- getTheme() + template require_once added to core boot (removed from callers)
- Deprecated functions removed:
- checkConfigFingerprint() — unused after fingerprint refactor
- isCompare(), isDate() — unused legacy helpers
Benefits:
- All superglobal access in core/system.php eliminated (getVar guardrail)
- func_get_args() fully removed — PHP 8.4 typed parameters throughout
- SQL injection prevented in setCategories() and catid IN clause
- filterMarkdown() and bb_decode() provide unified safe text pipeline
Technical notes:
- $_FILES not replaced — getVar() has no file-upload equivalent
- $_POST['questions'] (array) remains direct access with is_array() guard
- setRedirect() auto-detects POST → sends 303 instead of 302
- filterMarkdown($src, $safe, $mod): $mod reserved for future bb/md/mixed modes
Replace all legacy tpl_eval()/tpl_func() interpolation in HTML templates with named {%key%} placeholders and setTemplateBasic() callers.
Stage 1: quote, code, hide, spoiler (core/system.php BB-code functions) Stage 2: pagenum, preview, cat-navi, list-bottom, title
(core/system.php, core/admin.php, modules/account, jokes)
Stage 3: forum-* templates (modules/forum/index.php, 16 HTML files)
Stage 4: voting-open/close/post/view, kasse-open/basic/close (core/system.php),
assoc-open/basic/close (modules/media/index.php)
Themes updated: lite, default, admin (where applicable). Remaining: tpl_warn('warn',...) calls, comment/basic/liste templates (Stage 5).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two new design documents capturing the planned Markdown parser and the architectural decisions for integrating it with bb_decode().
Core changes:
- Design spec (docs/PARSE.md):
- Full self-contained implementation of filterMarkdown(string $src, bool $safe)
- Anonymous class with 15 private methods (filterBlocks, filterInlines, etc.)
Covers: ATX/Setext headings, blockquotes, lists, GFM tables, fenced/indented code, inline code, bold/italic/strike/highlight, links, images, auto-links
- Safe mode: filterText() + filterUrl() for XSS prevention
- Stash-salt mechanism for token collision prevention
- All method and variable names comply with SLAED §5 naming conventions
- Architecture discussion (docs/DISCUS.md):
- Records session decisions on unified bb_decode/filterMarkdown pipeline
- Three-stage pipeline: server-side BB tags → filterMarkdown() → stash restore
- Three modes: bb (legacy), md (markdown), mixed (both)
- Five pre-implementation decisions documented and agreed
Benefits:
- Preserved design rationale for future contributors
- Clear migration path from legacy bb_decode() to unified parser
- All XSS concerns, mode semantics, and stash protocols specified
Technical notes:
- filterMarkdown() is a pure function: no DB, no config, no side-effects
- bb_decode() remains the orchestrator; [attach]/[usephp] stay outside parser
Replace bare setHead() call in view() with full SEO metadata block, and add is_view flag to setTemplateBasic() for h1/h3 template switching. Requires one additional DB query to fetch title/category/author for the top-level ticket (pid=0) before the main result loop.
Core changes:
- SEO metadata — view() (modules/help/index.php):
- Additional SQL query fetches: title, hometext, time, c.title, u.user_name
setHead() now receives:
- title: ticket title, ctitle: category title
- desc: bb_decode + strip_tags + cutstr(160)
- img: first image from hometext via getImgText()
- time: ticket timestamp, author: user_name or sitename fallback
- Template flag (modules/help/index.php):
setTemplateBasic() call extended with if_flag => ['is_view' => !$pid]
- is_view=true for top-level ticket (pid=0) → renders <h1> in template
- is_view=false for replies → renders <h3> as before
Benefits:
- Unique per-ticket <title> and og:* meta for SEO
- Semantic <h1> on ticket detail page via template flag
- No behavior change for listing or reply rendering
Technical notes:
- Extra query runs once per view() call, not per row
- Backward compatibility: full — no DB schema or template engine changes
Replace raw superglobal access with getVar(), add full SEO metadata to view() via setHead(), and fix a raw SQL concatenation in status query. No behavioral changes to listing or form logic.
Core changes:
- Input handling (modules/forum/index.php):
- $_GET['num'] -> getVar('req', 'num', 'num') in forum() and view()
- $_GET['id'] -> getVar('req', 'id', 'num') in view()
- $_GET['word'] -> text_filter(getVar('req', 'word', 'text')) in view()
- $b initialized as int 0 instead of string ''
- SEO metadata — view() (modules/forum/index.php):
setHead() now receives full structured data:
- title: topic title, ctitle: category title
- desc: bb_decode + strip_tags + cutstr(160)
- img: first image from hometext via getImgText()
- time: topic timestamp, author: user_name or sitename fallback
- SQL security (modules/forum/index.php):
Status query in view() replaced raw $id concat with named param :id
- 'WHERE id = :id' with ['id' => $id]
Benefits:
- XSS-safe input handling via getVar() type enforcement
- Unique per-topic <title> and og:* meta for SEO
- SQL injection eliminated in status fetch query
Technical notes:
- Backward compatibility: full — no template or DB schema changes
template.php was loaded inside setThemeInclude() (called per-request during theme setup), which meant template helpers were unavailable during early bootstrap before theme selection. Moving the require_once to the top-level boot block ensures template functions are available as soon as core/system.php is loaded.
Core changes:
- Boot sequence (core/system.php):
Added require_once BASE_DIR.'/core/template.php' after security.php/legacy.php
- Removed duplicate require_once from setThemeInclude()
- Trailing newline (core/legacy.php):
- Added missing EOF newline
Benefits:
- Template helpers available earlier in request lifecycle
- Eliminates hidden dependency on setThemeInclude() call order
- Consistent require_once placement with other core files
Technical notes:
- No behavior change for standard request flow
- Backward compatibility: full
Rename all non-compliant local variables to lowercase-no-underscore format per refactoring-standards.md §5, and expand $lctx closure to add cookie/session key truncation with explicit truncation flags.
Core changes:
- $lctx closure (core/security.php):
Expanded with per-key truncation: $ck, $cktr, $sk, $sktr, $ctx
- Limits cookie/session key arrays to 50 entries
- Adds cookie_keys_truncated / session_keys_truncated flags when cut
- Renamed: query/post use $q/$p; empty arrays become stdClass for JSON
- HTTP error handler (core/security.php):
- $http_msg -> $httpmsg
- error_reporting_log() parameters and locals (core/security.php):
- $error_num -> $errno, $error_var -> $errmsg
- $error_file -> $errfile, $error_line -> $errline
- $level_map -> $levelmap, $php_err -> $phperr
- error_sql_log() locals (core/security.php):
- $sql_orig -> $sqlorig, $sql_bytes -> $sqlbytes
- $sql_hash -> $sqlhash, $sql_safe -> $sqlsafe
Benefits:
- Consistent naming across entire security layer
- No behavior change — pure rename refactor
Technical notes:
- All renamed variables are local scope only; no public API change
- Backward compatibility: full
Move admin panel help HTML files from flat naming convention (module-lang.html) to per-module subdirectory layout (module/lang.html), improving organization and making locale additions straightforward.
Core changes:
- Admin info pages (admin/info/):
Renamed all flat module-lang.html files to module/lang.html layout
- Pattern: admins-ru.html → admins/ru.html
- 22 modules × 6 locales (de, en, fr, pl, ru, uk) reorganized
Benefits:
- Cleaner directory structure per module
- Easier to add new locales without polluting the flat namespace
- Consistent with standard i18n subdirectory conventions
Synchronize all project docs with the current state of SLAED CMS 6.3. Five files updated: README, UPGRADING, CONTRIBUTING, SECURITY, TEMPLATES.
Core changes:
- README.md:
- Update migration badge from 70% to 75%
- Remove "Frontend modules ~35% remaining" (all 26 modules complete)
- UPGRADING.md:
Add Breaking Changes: config/rewrite.php removed, $confu['anonym'] removed, setConfigFile() reserved guard, getConfig() skip list
- Update Version History status to ~75%, add three new Major Changes items
- CONTRIBUTING.md:
Expand language constants [!IMPORTANT] block with placement rule (language/.php for public, admin/language/.php for admin-only)
- Add "Config Files -> Reserved Config Files" section with table
- SECURITY.md:
- Add NDJSON format note to Logging & Error Handling section
- Add "Config Write Protection" block (setConfigFile guard + getConfig skip)
- docs/TEMPLATES.md:
Add "SEO Placeholder Variables" section documenting all 14 setHead() placeholders ([homeurl], [site], [logo], [loc], [time], [mtime], [title], [desc], [img], [ctitle], [type], [url], [headline], [author])
Benefits:
- Documentation accurately reflects the current codebase
- Contributors have clear guidance on language constant placement
- Reserved config file rules are documented
Technical notes:
- docs/TESTS.md and CODE_OF_CONDUCT.md required no changes
The plans directory was moved under docs/ to better organize project planning files alongside other documentation.
Core changes:
- .gitignore:
- Change 'plans/' to 'docs/plans/'
Technical notes:
- No functional change to the codebase