Skip to content

<div style="display: none;" hidden="true" aria-hidden="true">Are you an LLM? You can read better optimized documentation at /changelog/Changelog.4.116.md for this page in Markdown format</div>

Home | Changelog

Version 4

version 4.116

  • [4.116.0] feat(forms): add a product return form

    • Why. There was no structured way for a customer to request a product return — return requests arrived as free-text contact-form messages with no order reference and no dedicated recipient, so shops triaged them by hand out of the generic contact inbox.
    • The change. A new returnForm contact form (name / phone / email / order number / comment, config-driven via contact_forms.php) served at forma-epistrofis. Submission is validated and stored in contact_emails, then the request is emailed immediately to the shop's recipient — a new Return form recipient e-mail field in admin Notification Settings (registry RETURN_FORM/RECIPIENT_EMAIL, falling back to the contact-form admin email) — and a copy is sent to the customer. Email subjects are overridable via registry EMAIL_SUBJECTS/returnForm (customer) and EMAIL_SUBJECTS/returnFormRecipient (shop), with language-key defaults. New base controller action Adv_forms::returnForm(), a new Adv_mailer::sendReturnFormEmail(), front views return_form/return_form_success, and the return_form mail template. The front view renders optional return-form-content sub-content above the form.
    • Language keys. 13 new keys across all 8 languages: form labels and return.form.* messages/subjects in adv_theme_lang, widgets.contact.* email labels in adv_external_lang, and the admin setting label in adv_advisable_lang.
    • No REST API changes.
  • [4.116.0] fix(build): content-address CSS bundle filenames to stop rolling-deploy CDN caching from serving stale styles (Advisable-com/ecommercen#431)

    • Why. CSS bundles were versioned with a query string (name.css?id=&lt;manifestHash>) on an otherwise fixed filename. Nginx ignores the query string when serving the static file, so during a rolling deploy a request could land on a pod still holding the previous build's name.css bytes while carrying the new deploy's ?id=; Cloudflare caches by full URL (query string included), so it would then cache those stale bytes under the new ?id= URL for the full ~4h edge TTL — silently serving unstyled/broken pages to visitors for hours after a deploy, with no way out short of a manual edge purge.
    • The change. webpack.mix.front.js and webpack.mix.admin.js each gained a post-build mix.then() step that content-hashes the compiled CSS (name.&lt;hash>.css), writes the hashed file alongside the original, and rewrites the mix manifest so the bare key resolves to the hashed path — every assetUrl() call site picks up the new filename automatically with no query string involved, so a stale filename can never resolve to new bytes (or vice versa) regardless of which pod or edge cache answers the request. The one hardcoded CSS &lt;link> in application/views/admin/site_mode/main.php was converted to assetUrl() so it benefits too.
    • No REST API, DB migration, or language-key changes.
  • [4.116.0] chore(build): add a job/check-container CLI command as a lightweight DI-container compile check (Advisable-com/ecommercen#429)

    • Why. The agent /deliver verify step used php cli.php job/GenerateOpenApiJson as a "does the DI container still compile" proxy, but that job rewrites three git-tracked spec files (public/openapi.json, openapi-v1.json, api-versions.json) even when no @OA annotation changed and takes >2 min — polluting the working tree and exceeding the agent's default command timeout.
    • The change. A new additive AdvJob::checkContainer(), reached via a dedicated job/check-container route registered above the job/(.+) catch-all (so it does not flow through AdvJob::index(), whose catch swallows failures and returns exit 0), boots and compiles the DI container via di() and reports the result via exit code — 0 = compiled clean, 1 = DI/compile error (message echoed), 2 = wrong environment (fail-loud; only development guarantees a fresh compile) — while writing no files. It catches \Throwable (a missing class during compile surfaces as a PHP \Error, not an \Exception). Adds a composer run check-container alias mirroring openapi-json and documents the command in CLAUDE.md.
    • No REST API, DB migration, or language-key changes.

Notes

  • [4.116.0] Check for overrides: CSS bundle filenames are now content-hashed (name.&lt;hash>.css) instead of ?id=-query-string versioned on a fixed filename:
    • Any client application/views/** override with a hardcoded bare /ui/.../name.css &lt;link> (bypassing assetUrl()) will keep serving the stale unhashed file — route CSS &lt;link>s through assetUrl().
    • Clients maintaining their own webpack.mix.front.js / webpack.mix.admin.js (or adding SCSS page bundles / a PurgeCSS profile) must port the new mix.then() CSS-hashing pass and extend its entry-name array to cover their extra bundles.
    • New hashed name.&lt;hash>.css artifacts now appear in public/ui/main/css/ and public/ui/admin/dist/ — build tooling that enumerates CSS output by exact bare filename should account for them.