Customization code migration to CBX 4
- Version
- 4.0 preview
- Updated
Task-oriented guides for realigning existing site customizations (data/customization/) to the
breaking changes introduced in CBX 4.
CBX 4 is a deliberate, breaking refactor of the core. Because every deployment carries its own
customization code in data/customization/ — gitignored, out-of-tree, per-site — a core change that
renames a model, drops a table column, or changes a convention will silently break that code. This area
is the running record of those breaks and the concrete before → after fixes for each.
Where these docs live. This directory ships inside the CBX component itself (
<component>/docs/migration-to-cb4/), so it travels with the code on every platform CBX runs on — Joomla (components/com_configbox), WordPress (plugins/configbox/app) and Magento 2 (cb-lib), all of which mount the same component repo — and it is included in the release package built bytools/make_packages.sh. Intended workflow: open a client project with itsdata/customization/, upgrade CBX, then point an AI at the customizations and this directory and ask it to amend the customizations. Everything an agent needs to do that is here; no platform-specific paths are assumed.
For AI agents amending customization code: load CHEATSHEET.md first — it is the flat old → new lookup for every identifier, with a grep pack to find the hits. Scan the customization for each Old token, apply the New, and heed the Status (shim = defer, manual = must edit, manual+data = also ship a data migration). Then, for anything non-mechanical (removed features, data migrations, judgement calls), read the matching playbook — the per-domain articles below carry the worked conversions and the per-file decision procedure. The breaking-changes log summarises what changed and why.
CLI tooling for the migration. CBX ships a CLI suite that carries most of the operational work of this upgrade — checking, applying and un-sticking migrations, clearing caches, and smoke-testing without a browser. On Joomla run
php cli/joomla.php configbox:<cmd>; on WordPress the same commands arewp configbox <cmd>(hyphenated;migrate --statusandmigrate:unblockare not ported there yet); on Magento 2 there is no CLI suite yet — migrations run viabin/magento setup:upgrade, and you check state with the SQL in the CHEATSHEET's sign-off.
During the upgrade you will want Command (Joomla form) "Did the migrations actually run?" — the host platform's own version/status reports say nothing about CBX's schema configbox:migrate --status(read-only; non-zero exit while work is pending)Apply outstanding core + customization update scripts, by name configbox:migrate(-vfor full failure diagnostics)A script failed and updates are frozen configbox:migrate:unblock(explains the block first;--dry-runto only look)Clear caches after amending customization code configbox:cache:clearSmoke-test a configurator page headlessly, as a given user configbox:run-task configuratorpage display page_id=<id> --user=<email>Full reference:
../technical/com_configbox_cli_commands.mdin the developer docs (docs/technical/).
How this area is organised
The running record (read first)
- CHEATSHEET.md — the consolidated old → new identifier lookup: one flat table of
every renamed/removed table, column, class, method, property, cache key, DSL token and string-key across all
domains, each tagged shim / manual / manual+data / removed, with the stacked
element→answer→questionrename already resolved to its final target. Load this first when amending a customization; it points into the playbooks for the detail. Ends with a ready-to-run grep pack to prove a customization is clean. - breaking-changes-log.md — the single running index of every breaking change: what broke, why, blast radius, and a one-line pointer to the playbook that fixes it. Append a new dated entry here whenever core work introduces another break.
Playbooks — how to fix customization code (one per customization kind, with the mechanical transform + the cases that need human/AI judgement)
-
exceptions-and-validation.md — errors are exceptions now. A custom property type's
check()should throwKenedoValidationExceptioninstead of returningfalse; callers ofvalidateData()/store()move to try/catch. Returningfalsestill works, but a custom type that returns it without setting an error reports a message nobody can act on. -
model-property-customizations.md — the mechanical recipe for
model_property_customization/files bound to the removed option/answer models, and the auto-conversion the core does for you. -
answers-collapse-deep-dive.md — the exhaustive reference for the option/answer (xref → answer) collapse: the full mental model, every DB/SQL/cache/order/string/pricing touch-point, a per-file decision procedure, worked conversions, and the external-append data migration you owe. Start here for any customization that touches the data model, not just property defs — this is the one written for a heavily-customized site where an AI is asked to make the custom code compatible.
-
assignments-lookups.md — reading the assignment relations through
ConfigboxAssignmentsHelperinstead ofConfigboxCacheHelper::getAssignments(): the full old-key → new-method table, why the undefined-key guards disappear, the two shapes that deliberately differ, and thecity_to_country/county_to_countrycorrection.getAssignments()still works — this is the better way to ask, and core no longer reads the array itself. -
element-question-rename.md — the exhaustive before → after reference for the element → question rename: DB table/columns, admin model/controller/views, pricing API, the assignment/pricing cache keys, the ionCube rules/calc engine + stored JSON, and the calc-formula DSL tokens. Full before → after tables per layer, the per-file decision procedure, worked conversions, and the shim inventory. Read this for any customization that touches the question entity.
-
customer-field-rename.md — the exhaustive before → after reference for the customer field rename:
#__configbox_users+#__cbcheckout_order_userscolumns (billing_*/shipping_*snake_case,vat_number,shipping_same_as_billing), the augmented keys, the Customer Fields configuration rows, form/DOM/JS contracts, and the operator-facing template placeholders. Read this for any customization that touches customer data, the customerform, order addresses or invoice/notification texts.
Orientation — what changed, per audience (not fixes; context for people)
- whats-new-for-devs.md — new and changed capabilities for developers.
- whats-new-for-operators.md — UI/workflow changes shop staff will see.
- operators-what-changed.md — a focused retraining brief: the concrete screen/label/behaviour changes affected staff need to be walked through.
- whats-new-for-decision-makers.md — the upgrade case: advantages and risks, aimed especially at sites still on the one-off-priced CBX 2.
Those three pages are about the jump to 4.0. What the 4.0 line has gained since is a separate track, cut by surface rather than by audience: Latest features — the storefront, the admin, the HTTP API, the CLI, the MCP server, the AI assistant, payments, catalog operations and the extension layer.
More playbooks get added here as further CBX 4 slices ship (overridden controllers/models, custom properties, engine/calc code, template overrides, DB-schema-dependent customizations, …).
The two kinds of fix
Every break falls into one of two buckets; each playbook labels its cases accordingly:
- Auto-converted by the core — CBX 4 ships compatibility shims (legacy
getModel()aliases, legacy customization-file loading, key remaps) so cleanly-written customizations keep working with no code change. You still get a deprecation line in the log telling you to update. These are called out so you know what you can safely defer. - Needs a manual edit — customizations that reference something genuinely removed (a dropped column, a deleted property, a table that no longer exists) cannot be shimmed. The core degrades gracefully (logs and skips rather than white-screening), but the feature stays broken until you apply the fix the playbook describes.
Rules for documenting a breaking change
When our work on the CBX core introduces a breaking change, follow this — it is the standing process, not just a style guide. The goal is that a future reader (human or AI) can, from these docs alone, both understand what changed and make custom code compatible without re-deriving it from the diff.
1. Log it first, in the right bucket.
Every breaking change gets a dated entry at the top of breaking-changes-log.md before anything else,
tagged with the status legend (🟢 auto-converted · 🟡 partial · 🔴 manual). The log is the index; detail
lives in a playbook it links to.
2. Classify every affected case as one of two kinds (and label it):
- Auto-converted by the core — a shim keeps cleanly-written customizations working with no code change (a deprecation is logged). Say what the shim is and where it lives, and what the log line looks like, so a reader can verify it and know what they can safely defer.
- Needs a manual edit — something was genuinely removed; no shim is possible. Give the exact before → after. State whether the core degrades gracefully (logs & skips) or fatals if left unfixed — operators need to know which breaks are silent-but-degraded vs hard.
3. Be concrete and greppable. Name the exact file, function, class, table, column, cache key. Give the
literal identifiers a reader will grep for (old → new). Include the hard-to-grep variants too
(hard-coded table prefixes, ::class string uses, minified twins).
4. Separate "code fix" from "data migration". A code-level shim (e.g. a remapped key) does not move
data. Whenever a change needs both, say so explicitly and point at how to ship the DB half (a
data/customization/updates/ migration; see ../technical/com_configbox_migrations.md). This is the most commonly
missed half on customized sites.
5. Give a decision procedure for scale. On a site with extensive customizations, a reader needs more than a list — give a per-file procedure: how to tell if a file is even loaded on this install, which bucket it falls in, what to do, and a final grep list of removed identifiers to prove the file is clean.
6. Cover all three audiences, not just developers. A breaking change usually has a human side. Note
whether operators/shop staff see a changed screen, label, or workflow (feed it into
operators-what-changed.md), and whether it's material to an upgrade decision
(whats-new-for-decision-makers.md). Don't leave retraining implicit.
7. Record why. One or two sentences on the motivation. Judgement calls during conversion resolve better when the reader knows the direction the model is moving in.
8. Verify claims before publishing. Check identifiers against the actual code, not memory. Don't state a shim exists unless you can name the method that implements it. Don't invent commercial/licensing facts in the decision-maker doc — flag them as "confirm with Rovexo" instead.