The vote action used hx-get without a token, so it hit the index.php CSRF gate ("Illegal file access"); htmx also does not include form fields on GET, so the chosen options were never sent. Switch the vote to an htmx POST that carries a hidden CSRF token, matching the admin token pattern.
Core changes:
- Voting view (core/system.php):
- getVotingView(): vote button uses hx-post via an is_post flag
- Pass the poll id and ajax token into the voting form
- Templates:
- comment-action-ajax: add is_post flag (hx-post instead of hx-get)
- voting-widget: hidden id and token fields inside the form
Benefits:
- Voting passes the CSRF gate and records the selected options
- Reuses the established hidden-token contract, no global shim
Technical notes:
- POST lets htmx include the enclosing form (body[] + token)
- Backward compatible: other comment-action-ajax callers stay on GET
Array form fields must be read via the name[] key suffix; getVar() never
supported a type='array' argument, so ~20 callers that passed it fell
through to the scalar path where filter_input() returns false on an array,
crashing with "count(): ... false given" (e.g. admin poll save).
Core changes:
- Input reader (core/security.php):
- Revert getVar() to detect arrays only by the key[] / key[n] syntax
- Drop the unsupported 'array' type branch
- Callers migrated to key[] (raw, indexes preserved):
- voting/admin: body[], answer[] (keeps body<->answer alignment)
- news/admin, shop/admin: associated[], id[]
- media, media/admin: links[]
- money, money/admin: intro[]
- forum, pages/admin: id[]
Benefits:
- Fixes admin poll save and other multi-value form handlers
- Single canonical way to read arrays, matching existing key[] callers
Technical notes:
- Empty filter type returns the raw array (no element stripping)
- Behavior-preserving: previously these calls returned false (broken)
Mirror the plugin analysis in Russian (identifiers, code and JSON stay English per project rules) so it matches the team's working language.
Core changes:
- Plugin analysis (docs/PLUGINS.md):
- Translate the prose to Russian; keep manifest examples and identifiers in English
Benefits:
- Documentation in the team's working language
Technical notes:
- Documentation only; no code change
Document SLAED's existing extension mechanisms and a safe direction for an admin-managed plugin layer based on the editor manifest/driver pattern.
Core changes:
- Plugin analysis (docs/PLUGINS.md):
- Survey current mechanisms (modules, editor plugins, captcha provider, vendored libs)
- Recommend generalizing the manifest + driver + registry pattern
- Propose a managing (not installing) admin page; warn against remote PHP install
Benefits:
- Shared reference for unifying SLAED's extension points
Technical notes:
- Documentation only; no code change
Style the ALTCHA captcha checkbox like the theme form controls (size, border, radius, shadow) with a green success state and a single centered check mark, in both the admin and frontend themes.
Core changes:
- Admin theme (templates/admin/assets/css/theme.css):
- Replace the earlier glyph-suppression hack with a full captcha checkbox style
18px box using --sl-color-border-strong / --sl-radius-control / --sl-shadow-input, green --sl-color-success when checked; ALTCHA's own SVG check, centered
- Frontend theme (templates/lite/assets/css/theme.css):
- Same captcha checkbox style resolved through the lite theme tokens
Benefits:
- Consistent, on-brand captcha checkbox in both themes
- Single, centered, green check mark (no double, not crooked)
Technical notes:
Scoped to .sl-captcha .altcha-checkbox; keeps ALTCHA's SVG centered by syncing --altcha-checkbox-size with the box size
The admin theme draws its own checkbox glyph via a background-image, which stacked on top of the ALTCHA widget's own SVG check mark (rendered in light DOM), so the verified captcha showed two check marks.
Core changes:
- Admin theme (templates/admin/assets/css/theme.css):
Suppress the admin checkbox background glyph on .altcha-checkbox inputs (:checked / :indeterminate), leaving only ALTCHA's own check mark
Benefits:
- Single, correct check mark in the admin login captcha
Technical notes:
- CSS only; scoped to .sl-admin-shell .altcha-checkbox; the lite theme was unaffected
Adjust the Russian captcha verified message word order to the preferred phrasing.
Core changes:
- Captcha strings (lang/ru.php):
- _CAPTCHA_VERIFIED: "Проверка успешно завершена!" -> "Проверка завершена успешно!"
Benefits:
- More natural Russian phrasing for the success confirmation
Technical notes:
- Text only; no behavior change; mapped to the ALTCHA i18n key "verified"
Replace the terse "Verified" label with a clear confirmation sentence in the captcha verified state, across all shipped languages.
Core changes:
- Captcha strings (lang/*.php):
_CAPTCHA_VERIFIED now reads as a full success sentence
- ru: "Проверка успешно завершена!"
- de/en/fr/pl/uk: equivalent wording, kept in sync
Benefits:
- Clearer feedback to the user right after solving the captcha
Technical notes:
- Text only; no behavior change; mapped to the ALTCHA i18n key "verified"
Turn on the ALTCHA captcha and the database-backup and dynamic error logs in the shipped security configuration.
Core changes:
- Security config (config/security.php):
- captcha.active 0 -> 1 (enable the ALTCHA captcha)
- log_b 0 -> 1 (database backup log)
- log_d 0 -> 1 (dynamic error log)
Benefits:
- Spam protection and operational logging are on by default
Technical notes:
- No secret is committed; the security secret stays empty in the tracked config
Explain in the security admin help that the captcha proof-of-work worker is self-hosted (same-origin), so it works under a strict CSP without blob:.
Core changes:
- Security help (admin/info/security/ru.md):
Add a note that the PoW worker loads from the site origin (plugins/altcha/altcha-sha.js), so default-src 'self' is enough
- Mention that an explicit worker-src directive must include 'self'
Benefits:
- Admins find the captcha CSP behavior documented in-product
Technical notes:
- Russian help file; code samples and identifiers stay in English