Skip to main content
Version: 3.x

The customer field rename — before → after reference

Version
3.x
Updated
View markdown

The exhaustive reference for the CBX 4 rename of the customer record's fields (#__configbox_users and the frozen per-order snapshot #__cbcheckout_order_users). Read this for any customization that touches customer data — the customer model, the customerform (checkout/quotation/profile/save-order), order addresses, invoice/notification placeholders, PSP bridges, or raw SQL against either table.

This is the sibling of element-question-rename.md. Same playbook shape: the full before → after tables, then the per-file decision procedure.


Why this change

The customer record carried three naming families at once:

  1. Glued-together billing* columnsbillingfirstname, billingcompanyname, billingzipcode
  2. UN-prefixed columns that actually meant the shipping addressfirstname, city, country … (labelled "Delivery" in the UI; the bare name looked like the primary field and was not)
  3. Odd onesvatin, samedelivery, references without _id (country, state held ids)

CBX 4 renames all of it to one convention, aligned with the commerce2 (#__cbx_*) vocabulary: snake_case, billing_ / shipping_ prefixes, _id suffix on references, postal_code, address_line_1/2, vat_number. The un-prefixed set is now explicitly shipping_* — the counterintuitive "bare name = shipping" trap is gone.

The mental-model swap: wherever code said billingfirstname it now says billing_first_name; wherever it said a bare firstname/city/country about a customer or order address, it now says shipping_first_name/shipping_city/shipping_country_id. Record ids are unchanged — customers, orders and their links all keep pointing at the same rows. Only names changed.

Not touched (do not "fix" these — they are not customer fields):

  • The geo tables' own columns: #__configbox_cities.county_id, #__configbox_counties.state_id, … and the tax-rate table's county_id/city_id columns.
  • The cascade AJAX request params of the customerform controller: country_id, state_id, county_id.
  • The registration form's POST field names (firstname, lastname, email in views/user/tmpl/register.php) — form-local names, mapped to billing_* in the controller.
  • custom_1..4, group_id, platform_user_id, language_tag, newsletter, is_temporary, created, password, id, order_id — already fine, unchanged.
  • Presentational CSS classes inside invoice/quotation/order-slip templates (class="firstname", class="zipcode" …) — DOM styling hooks, not field keys.
  • The commerce2 schema (#__cbx_party, #__cbx_address, …) — it already used the target vocabulary.

The DB migration ships with the core

helpers/updates/3.7.0.php (runs on init and via php cli/joomla.php configbox:migrate) does four things, idempotently:

  1. Renames every column below on both #__configbox_users and #__cbcheckout_order_users (precedent: the element→question rename also renamed frozen order history). Indexes named after the old columns are renamed alongside. Data, ids and FKs are untouched.
  2. Drops gender and billinggender on both tables (dead since 2.6.0 replaced them with salutation_id; see "Removed" below).
  3. Rewrites the #__configbox_user_field_definitions.field_name rows (the Customer Fields configuration) to the new names — keyed on field_name, since row ids are not stable.
  4. Rewrites {placeholder} tokens in stored #__configbox_strings texts (notification subjects/bodies) from the old vocabulary to the new — including the legacy alias tokens ({country}{shipping_country_name} etc., see the placeholder table).

It does not touch data/customization/ — custom SQL, custom columns and custom code are yours to realign using the tables below.


Before → after — DB columns

Applied identically to #__configbox_users and #__cbcheckout_order_users (per-table column types are preserved). Status for customization code: 🔴 manual — there are no shims; raw SQL, model overrides and template overrides referencing old names break until edited.

Billing address

BeforeAfter
billingcompanynamebilling_company_name
billingsalutation_idbilling_salutation_id
billingfirstnamebilling_first_name
billinglastnamebilling_last_name
billingaddress1billing_address_line_1
billingaddress2billing_address_line_2
billingzipcodebilling_postal_code
billingcitybilling_city
billingcountrybilling_country_id
billingstatebilling_state_id
billingcounty_idbilling_county_id
billingcity_idbilling_city_id
billingemailbilling_email
billingphonebilling_phone

Shipping address (was the UN-prefixed set, "Delivery" in the UI)

BeforeAfter
companynameshipping_company_name
salutation_idshipping_salutation_id
firstnameshipping_first_name
lastnameshipping_last_name
address1shipping_address_line_1
address2shipping_address_line_2
zipcodeshipping_postal_code
cityshipping_city
countryshipping_country_id
stateshipping_state_id
county_idshipping_county_id
city_idshipping_city_id
emailshipping_email
phoneshipping_phone

Other

BeforeAfterNote
vatinvat_number
samedeliveryshipping_same_as_billingSemantics unchanged: 1 = billing gets copied over shipping
gender, billinggenderremovedSee "Removed" below

Before → after — computed (augmented) keys

ConfigboxUserHelper::augmentUserRecord() adds derived keys to every user/order-address record (ConfigboxUserData). Templates and placeholders use them heavily. 🔴 manual.

BeforeAfter
countryname / country_2_code / country_3_codeshipping_country_name / shipping_country_2_code / shipping_country_3_code
billingcountryname / billingcountry_2_code / billingcountry_3_codebilling_country_name / billing_country_2_code / billing_country_3_code
statename / statecode / statefipsshipping_state_name / shipping_state_code / shipping_state_fips
billingstatename / billingstatecode / billingstatefipsbilling_state_name / billing_state_code / billing_state_fips
county / billingcountyshipping_county / billing_county
salutation / billingsalutationshipping_salutation / billing_salutation
gender / billinggender (augmented)shipping_gender / billing_gender — now augment-only, derived from the salutation (configbox_salutations.gender); the DB columns are gone

language_name and order_id are unchanged.


Before → after — template placeholders (operator-facing) 🟠

Invoice and email-notification texts substitute {key} tokens generated from the order-address record, so the rename changes the placeholder vocabulary operators typed into their own templates. The core migration rewrites stored texts in #__configbox_strings (notification subjects/bodies, all languages) — that is the 🟠 part: the data moved; anything of yours that writes or documents these tokens did not.

Every column and augmented key above maps 1:1 ({billingfirstname}{billing_first_name}, …). Additionally, four legacy alias tokens resolved to the name of a place while sharing the raw column's key — they map to the *_name tokens, and the explicit alias lines in models/invoice.php are gone (the generic record loop covers the new names):

BeforeAfter
{country}, {countryname}{shipping_country_name}
{billingcountry}, {billingcountryname}{billing_country_name}
{state}, {statename}{shipping_state_name}
{billingstate}, {billingstatename}{billing_state_name}
{salutation}{shipping_salutation}
{billingsalutation}{billing_salutation}

The gendered-variation syntax in notifications ({Sehr geehrter|Sehr geehrte}) is unchanged — it keys off the (now augment-derived) billing_gender.


Before → after — the Customer Fields configuration (data!)

#__configbox_user_field_definitions.field_name holds these names as row values; the migration rewrites all 30 rows. If your customization queries this table, or your code calls ConfigboxUserHelper::getUserFields() / getUserFieldTranslations() and branches on field names, apply the same column tables above. The two synthesized runtime-only keys are now shipping_city_id / billing_city_id (cloned from shipping_city / billing_city rows).


Before → after — HTTP, DOM and JS contracts

The customerform posts field names as input names, and validation issues come back keyed by field name. All of it follows the rename. 🔴 manual for template overrides and custom JS.

ContractBeforeAfter
Form input name/id attributesbillingfirstname, firstname, samedelivery, vatin, …billing_first_name, shipping_first_name, shipping_same_as_billing, vat_number, …
Field wrapper CSS classes.customer-field-billingcity, .customer-field-city.customer-field-billing_city, .customer-field-shipping_city
Admin Customer Fields rows.cb-userfield-billingemail.cb-userfield-billing_email
getCustomerFormData() payload keysold namesnew names
Validation issue fieldName valuesold namesnew names
Admin orders list sort keysa.billinglastname, a.lastnamea.billing_last_name, a.shipping_last_name

Prefix arithmetic is gone. The billing→shipping pairing used to be substr($fieldName, 7) / 'billing' + field_name in three places. It is now an explicit prefix map — if your code paired fields the old way, mirror this:

// PHP (ConfigboxModelCustomers::prepareForStorage)
if (strpos($fieldName, 'billing_') === 0) {
$pendant = 'shipping_'.substr($fieldName, strlen('billing_'));
}
// JS (customerform.js)
if (fieldName.indexOf('billing_') === 0) {
let pendant = fieldName.replace(/^billing_/, 'shipping_');
}

Removed ⛔

  • gender / billinggender columns (both tables). Dead storage since 2.6.0 introduced salutation_id — nothing could write anything but the column default. The behaviour survives: augmentUserRecord() derives shipping_gender / billing_gender from the selected salutation's gender column at read time, so notification gender variations keep working. Code that selected the columns in SQL must switch to the augmented keys (or join #__configbox_salutations).
  • Dead validation arms for county / billingcounty in ConfigboxModelCustomers::validateData() (unreachable since 2.6.14 renamed the rows to *county_id).
  • disabledValidation list in adminUserFields.js — targeted inputs the admin table stopped rendering long ago.

Behaviour fixes shipped with the rename

Latent bugs in the code being renamed, fixed in the same commit (behaviour changes, not renames):

  1. Checkout city snapshot: setOrderAddress() gated the billing-city geo snapshot on billingcounty_id and compared the shipping city against billingcounty_id (copy-paste bug) — city data could be missing from order snapshots.
  2. Billing country fallback: augmentUserRecord()'s non-order path resolved the billing country from the shipping country id.
  3. Tax lookup: ConfigboxPricesHelper::getTaxRate() passed $user->county (the county name, intval 0) where the county id belongs — county-level tax rules never matched through this path.
  4. Email salutation: the invoice/registration emails greeted with the shipping salutation next to the billing name; they now use billing_salutation.

Per-file decision procedure (for customization code)

For every file in data/customization/ (and any template/model override):

  1. Grep for the old tokens — the CHEATSHEET grep pack covers them. The glued names (billingfirstname, vatin, samedelivery, …) are unambiguous: rename on sight.
  2. Bare firstname/city/country/state/county_id/city_id/email/phone/salutation_id need a judgement call: about a customer, an order address or the customerform → shipping_*. About the geo tables, the tax tables, a platform user, or an unrelated form → leave alone.
  3. Raw SQL against #__configbox_users / #__cbcheckout_order_users: apply the column tables. SELECT * consumers break at the reading site, not the query — check what property names the result is used with.
  4. Stored texts your customization writes (notification bodies, invoice fragments): emit the new placeholder vocabulary. The core migration converted existing rows; your writers must not re-introduce old tokens.
  5. Custom columns you added to either table are untouched — but if your column names collide with the new vocabulary (e.g. you added your own billing_email), resolve that before running the migration; the rename is guarded and will skip a rename whose target name already exists, leaving the old column in place.
  6. After editing: php cli/joomla.php configbox:cache:clear, then walk checkout once with shipping_same_as_billing checked and once unchecked, and render one invoice + one notification.