Field types
CDA Custom Fields supports 15 input types covering every common form pattern.
Text inputs
Section titled “Text inputs”| Type | HTML | Storage | Notes |
|---|---|---|---|
text | <input type="text"> | varchar (≤64KB) | Single-line. Use for short fields like VAT IDs, names, codes. |
textarea | <textarea> | text | Multi-line. Default 3 rows × 40 cols, customizable per template. |
email | <input type="email"> | varchar | Browser-level email validation. |
phone | <input type="tel"> | varchar | No format restriction — store as user typed. |
url | <input type="url"> | varchar | Browser-level URL validation. |
number | <input type="number"> | varchar | Numeric input, mobile keyboards show numeric pad. |
Select inputs
Section titled “Select inputs”| Type | HTML | Storage | Notes |
|---|---|---|---|
select | <select> single | varchar | Define options on the field form. First option is empty / “Please select…” |
multiselect | <select multiple> | JSON array | Stored as JSON; queried as LIKE '%"val1"%' or via cda_custom_field_value parsing. |
checkbox | Group of <input type="checkbox"> | JSON array | Same storage as multiselect but rendered as checkboxes. |
radio | Group of <input type="radio"> | varchar | One selected value. |
yesno | Two-option <select> (Yes / No) | varchar (1/0) | Binary toggle. Shortcut over manually defining a 2-option select. |
Date & time
Section titled “Date & time”| Type | HTML | Storage | Notes |
|---|---|---|---|
date | <input type="date"> | varchar (ISO 8601 YYYY-MM-DD) | Native browser date picker. |
datetime | <input type="datetime-local"> | varchar (YYYY-MM-DDTHH:MM) | Native browser datetime picker. No timezone — store local. |
File uploads
Section titled “File uploads”| Type | HTML | Storage | Notes |
|---|---|---|---|
file | <input type="file"> + drag-drop | JSON metadata | See secure upload section. |
image | <input type="file" accept="image/*"> | JSON metadata | Same as file but client-side limited to image/*. MIME still validated server-side. |
Secure file uploads
Section titled “Secure file uploads”File and image fields stream the upload to pub/media/cda_custom_fields/<yyyy>/<mm>/<32-hex>.ext via a hardened endpoint:
- Magic-byte MIME detection —
finfo_file(FILEINFO_MIME_TYPE)reads the file’s actual content type, ignoring the extension and$_FILES['type'](both client-controlled). - Extension reverse-mapped from MIME — the saved filename’s extension comes from our server-side MIME→ext table, not from the user.
- Filename randomization —
bin2hex(random_bytes(16))ensures storage paths are unguessable. - HMAC-SHA256 signed download URLs — every download link includes a signature derived from a per-installation secret (Magento crypt key, salted). URLs expire after 24h by default (configurable).
- 4-tier authorization — even with a valid signature, downloads check: admin session → owned-order match → current-quote match → session-pinned upload. No bearer-token-only access.
Default allowed MIME types
Section titled “Default allowed MIME types”image/jpeg, image/png, image/webp, image/gif, application/pdf,application/msword, application/vnd.openxmlformats-...wordprocessingml.document,application/zipConfigure under Stores → Configuration → CDA → Custom Fields → File & Image Uploads.
Default max file size
Section titled “Default max file size”10 MB per file. Configurable per store. Magento’s own upload_max_filesize / post_max_size PHP limits still apply.
Orphan cleanup
Section titled “Orphan cleanup”A daily cron job (cda_customfields_cleanup_orphans at 03:15 UTC) deletes uploaded files that aren’t referenced by any cart or order. Default retention: 7 days, configurable.
Storage shape
Section titled “Storage shape”Most fields store their value as a plain string in the value column of the appropriate _value table:
| Surface | Table |
|---|---|
| Cart / Checkout | cda_custom_field_quote_value |
| Order (denormalised at place-order) | cda_custom_field_order_value |
| Customer registration / profile | cda_custom_field_customer_value |
| Customer address book | cda_custom_field_address_value |
| Contact form | cda_custom_field_contact_value |
| Product review | cda_custom_field_review_value |
| Newsletter | cda_custom_field_subscriber_value |
| Wishlist item | cda_custom_field_wishlist_item_value |
file and image field values are stored as a JSON blob:
{ "path": "2026/05/abc123def456...12char.jpg", "name": "customer-original-filename.jpg", "mime": "image/jpeg", "size": 245678}multiselect and checkbox values are stored as JSON arrays of selected values.
Everything else is plain string storage. This keeps querying simple — no joins to look up an option’s label.
How values flow
Section titled “How values flow”- Customer submits a form (POST).
- The relevant observer (e.g.
cart_save_after,customer_register_success) reads thecda_*_custom_fields[code]POST keys. - Values insert into the surface-specific
_valuetable, keyed by quote/customer/order/etc. - On Place Order, a
sales_model_service_quote_submit_successobserver copies cart values fromquote_valueintoorder_value, preserving them for historical orders even if you later delete the field definition.