Журнал изменений
Add a dedicated test suite for the new Parser class and clean up the obsolete filterMarkdown / filterReplaceText function stubs from AdminPreviewBridgeFlowTest now that the real Parser class is available.
Core changes:
- New test suite (tests/Unit/ParserFixturesTest.php):
- Loads core/classes/parser.php directly via require_once
- Defines minimal stub functions (img_find, replace_break, is_user) required by Parser without the full CMS bootstrap
- Data-provider test cases covering safe and unsafe mode output, BB-code tags, Markdown blocks, and inline content
- Updated test (tests/Unit/AdminPreviewBridgeFlowTest.php):
- Remove filterMarkdown() and filterReplaceText() function stubs
- No longer needed: Parser class is loaded directly in the test
- Remove __test_filter_markdown global from setUp()
- Remove associated fixture setup in previewPartialHandlesHtmlContentCorrectly()
Benefits:
- Parser class is covered by fixture-based unit tests
- AdminPreviewBridgeFlowTest is cleaner without surrogate function stubs
Technical notes:
- ParserFixturesTest requires BASE_DIR to be defined; handled by bootstrap
- Removing the stubs does not affect existing test assertions — the real Parser produces identical output for the affected test cases
Replace all remaining filterMarkdown() + filterReplaceText() call pairs with $prs->filterContent() across the front-end module controllers and block scripts. Add global $prs where required.
Core changes:
- Block scripts (blocks/):
- block-links.php: 2 description tooltip call sites → $prs->filterContent()
- block-auto_links.php: 1 description tooltip → $prs->filterContent()
- Module front-end controllers (modules/*/index.php):
- account: view() signature field, last() comment snippet (4 sites)
- auto_links: description rendering
- changelog: common.php entry body
- clients, contact: text field rendering
- content: body rendering
- faq: answer body
- files, media: description fields
- forum: post body and reply content (multiple sites)
- help: article body
- jokes: joke body
- links: description fields
- main: block content rendering
- money: invoice and confirmation text fields
- news: article body and intro
- order: order detail rendering
- pages: page body
- shop: product description, body and intro fields
Benefits:
- Zero filterMarkdown/filterReplaceText calls remain anywhere in the codebase
- All public-facing content rendering uses the unified Parser API
Technical notes:
- All changes are mechanical replacements; no logic changes
- $prs is already available as a global from system.php bootstrap
Replace filterMarkdown() + filterReplaceText() with $prs->filterContent() in all admin-context module files. Add global $prs to affected function signatures.
Core changes:
- Admin panel modules (admin/modules/):
- admins.php → save(): migrate mail body rendering for admin password email
- security.php → bansave(): migrate ban notification email body
- Module admin controllers (modules/*/admin/index.php):
- account/admin: save() — migrate mail body for new-user password email
- help/admin: view help page text rendering
- money/admin: billing() call — migrate author and info text fields (2 sites)
- payment notification email body
- order/admin: order confirmation email body
- shop/admin: product preview body_b and body_c fields (2 sites)
Benefits:
- All admin module PHP files are free of filterMarkdown/filterReplaceText
- Consistent $prs->filterContent() pattern across the entire admin layer
Technical notes:
- All changes are mechanical; argument order adjusted to filterContent($src, false, $mod)
- No logic or output changes
Replace every filterMarkdown() + filterReplaceText() call pair in the core function files with $prs->filterContent(). Add global $prs to all affected function signatures.
Core changes:
- Admin helpers (core/admin.php):
- getAdminPrivateList(): add global $prs; replace filterMarkdown/filterReplaceText
- getAdminInfo(): add global $prs; replace filterMarkdown/filterReplaceText
- Template helpers (core/helpers.php):
- getTplViewFieldRows(): add global $prs; replace for type-2 custom field values
- getTplPreviewContent(): add global $prs; replace for $bodya and $bodyb
- setTplAdminInfoPage(): add global $prs; replace for $info rendering
- User helpers (core/user.php):
- setMessageShow(): add global $prs; replace for message body
- getUserBlock(): add global $prs; replace for user sidebar block
- updatePost(): add global $prs; replace for inline post rendering (2 sites)
- getPrivateMessageView(): add global $prs; replace for body and sig fields
- view() (account): add global $prs; replace for $seodesc and $sign
- last(): add global $prs; replace for comment snippet truncation
Benefits:
- All core PHP functions use the new Parser API; zero legacy calls remain
- Global $prs follows the same declaration pattern as $tpl and $db
Technical notes:
- Argument order change: filterMarkdown($src, $mod, $safe) becomes $prs->filterContent($src, $safe, $mod) — safe flag is the second arg
- No behavioral changes; pipeline logic is identical
Move the Markdown+BB-code processing pipeline out of the inline anonymous class in core/system.php into a dedicated Parser class at core/classes/parser.php. Expose a single entry point filterContent() that merges the old two-step filterMarkdown() + filterReplaceText() call into one method. Instantiate $prs globally alongside $tpl in system.php and remove the now-replaced standalone functions.
Core changes:
- New class (core/classes/parser.php):
- Parser class with filterContent(string $src, bool $safe, string $mod)
as the unified entry point
- safe=true: escapes user-injected HTML and applies URL allowlist
- safe=false: allows raw HTML blocks and admin BB tags
- Internal pipeline: filterBbBlocks → filterCode → filterBlocks → filterSafe (safe mode) → filterStash
- Per-request parse cache keyed by md5(src + safe + mod) to avoid re-parsing identical content within one request
- All logic is a direct extraction of the anonymous class from system.php; no behavioral changes
- Bootstrap (core/system.php):
- Add require_once for core/classes/parser.php
- Instantiate $prs = new Parser() immediately after $tpl
- Remove filterMarkdown() and filterReplaceText() function definitions
- Migrate all call sites inside system.php to $prs->filterContent()
- getBlocks(), scheduler mail, comment rendering, updateComment(), getUserSessionInfo() area
Benefits:
- Parser logic is testable in isolation via core/classes/parser.php
- Single filterContent() call replaces every filterMarkdown() + filterReplaceText() pair
- Removes 780-line anonymous class from system.php bootstrap
Technical notes:
- $prs is a global like $tpl and $db; callers must declare global $prs
- filterMarkdown() and filterReplaceText() no longer exist after this commit
- All remaining callers are migrated in subsequent commits
Regenerate base_fingerprint to reflect the current state of the codebase after the admin fragment namespace was flattened and all PHP callers were updated to use flat fragment paths.
Core changes:
- Config fingerprint (config/local.php):
- Update base_fingerprint from 95db252... to 67064900...
- Reflects changes across templates, core, admin modules, and module admin/public pages from the fragment refactor
Benefits:
- Fingerprint is consistent with the actual file state
- Prevents false-positive change detection on next build
Technical notes:
- No functional change; fingerprint is a build-state checksum only
Remove the new/ prefix from getHtmlFrag() calls in public-facing module controllers and replace the removed span-btn fragment with the new inline-badge fragment. Update title_tip() call sites to use the new structured array API.
Core changes:
- Content module (modules/content/index.php):
- Migrate title_tip() call to structured array: label/value/is_last pairs
- Replaces getTplAdminTipLine() helper with direct data array
- Forum module (modules/forum/index.php):
- Replace span-btn fragment calls with inline-badge across all icon rows
- topic state badges: new, old, popular, announce, hot, mod, admin, closed, pinned (9 call sites)
- forum state badges: new, nonew, closed (3 call sites)
- Fix form submit button: sl_but_blue → sl-but-blue (BEM class)
- Rename title_attr → title_text in inline-badge call signature
- Files, links, media, money, shop, users, voting (modules/*/index.php):
- Remove new/ prefix from getHtmlFrag() calls where present
- Apply BEM class name corrections where applicable
Benefits:
- Public module pages no longer reference deleted span-btn fragment
- Consistent inline-badge fragment usage across admin and front-end
- title_tip() structured API replaces ad-hoc string concatenation
Technical notes:
- inline-badge replaces span-btn 1:1 for icon-label badges; title attr key renamed from title to title_text in the new fragment signature
- sl_but_blue → sl-but-blue is a visual-only class change (no layout effect)
Remove the new/ prefix from every getHtmlFrag() call in all 23 module admin controllers (modules/*/admin/index.php). Aligns the module admin layer with the flat fragment namespace introduced in the template refactor.
Core changes:
- Account module (modules/account/admin/index.php):
- Replace new/* fragment paths with flat names throughout all views
- label-hint, input, select, select-option, checkbox, radio-group, etc.
- Auto-links, changelog, clients, contact, content (admin):
- Remove new/ prefix from getHtmlFrag() calls (input, label-hint, div-row)
- FAQ, files, forum, help, jokes, links, media (admin):
- Remove new/ prefix from all getHtmlFrag() fragment calls
- Money, news, order, pages, RSS, search, shop, sitemap (admin):
- Remove new/ prefix; shop/admin has the most call sites (select, checkbox, table-cell, table-cells, row-actions)
- Voting, whois (admin):
- Remove new/ prefix from getHtmlFrag() calls
Benefits:
- Module admin pages are fully aligned with the flat fragment API
- No new/ prefix fragment paths remain in any modules/*/admin/ file
Technical notes:
- Pure path prefix removal; no logic or behavior changes
- All 23 admin index files affected; changes are mechanical and uniform
Update admin/index.php, core/admin.php, and all 25 admin/modules/*.php to use the flat fragment namespace. Remove the new/ prefix from every getHtmlFrag() call site. Migrate admininfo() in core/admin.php from legacy getTplAdminInfoRow() to the new table-row / table-cells / row-actions-item / inline-badge fragment composition.
Core changes:
- Admin dashboard (core/admin.php):
- Rewrite admininfo() rows using table-row + table-cells + row-actions-item
- inline-badge fragments (replaces getTplAdminInfoRow() calls)
- All 16 module rows (account, faq, files, help, jokes, links, media, news, pages, shop, voting, etc.) converted to new API
- Admin entry point (admin/index.php):
- Remove new/ prefix from getHtmlFrag() calls for menu and panel fragments
- Admin modules (admin/modules/*.php — 25 files):
- Remove new/ prefix from all getHtmlFrag() calls: label-hint, input, select, select-option, checkbox, radio, radio-group, textarea, hidden, div-row, div-collapse, div, form, button, submit, move-controls, tabs-link, tabs-panel, table-cell, table-cells, table-row, inline-badge, row-actions, row-actions-item, image-preview, toggle-form-block, user-search, edit-tip, title-tip
Benefits:
- All admin panel PHP is aligned with the flat fragment namespace
- Legacy getTplAdminInfoRow() dependency removed from core/admin.php
- Consistent getHtmlFrag() call style across the entire admin layer
Technical notes:
- Pure search-and-replace of new/ prefix; no logic changes
- getTplAdminInfoRow() function can now be removed from helpers
Update all core PHP files to use the new flat fragment namespace after the new/ subdirectory was removed. Replace dedicated micro-fragments (meta-refresh, head-link-icon, pdo-query-time) with direct inline HTML to eliminate trivial fragment round-trips and reduce the fragment dependency surface.
Core changes:
- Template engine (core/classes/template.php):
- Change fallback alert path from new/alert → alert
- Removes hard-coded new/ prefix in the fragment-not-found error path
- Database logger (core/classes/pdo.php):
- Replace getHtmlFrag('pdo-query-time', ...) with direct sprintf HTML
- Eliminates pdo-query-time fragment dependency from the DB layer
- Pager and tab helpers (core/helpers.php):
- Remove new/ prefix from getHtmlFrag() calls: pager, pager-link, pager-dots
- Remove new/ prefix from tabs-link, module-head, alert calls in getTplPager() and getTplAdminTabs() / setTplAdminInfoPage()
- Legacy helpers (core/helpers-old.php):
- Add getTplFragmentName(string $name): string helper for theme-aware fragment path resolution (used by access.php, security.php, system.php)
- Remove obsolete getTplAdminTable(), getTplAdminTableRow(), getTplAdminForm(), and related wrapper functions (replaced by direct getHtmlFrag() calls in callers)
- Exit-page renderers (core/access.php, core/security.php):
- Inline meta-refresh and head-link-icon HTML directly (htmlspecialchars-safe)
- Removes fragment dependency for trivial one-liner tags
- Replace head-link-css fragment lookup with getTplFragmentName() call
- Front-end session rendering (core/system.php):
- Replace new/alert with alert in getFlashHtml()
- Replace bare 'session-row' with getTplFragmentName('session-row') in getUserSessionInfo() and getUserSessionAdminInfo() (5 call sites)
- Fix CSS class: sl_but_blue → sl-but-blue in getVotingView()
Benefits:
- Zero new/ fragment paths remain in core after this commit
- Trivial micro-fragments (meta tag, link tag, query-time span) eliminated
- getTplFragmentName() provides a single lookup point for theme-context paths
Technical notes:
- Inline HTML in access.php and security.php is equivalent to the removed fragments
- No behavior changes; only fragment-path and class-name corrections