Magento2.x Cmash Connector
Cmash Connector — Marketing Overview
Personalized print products in Magento, from editor to order, in one flow
Cmash Connector brings the Cmash Web2Publish editor into your Magento store. Customers design business cards, flyers or any template-based product right on the product page, put the result into the cart and order it — while the shop keeps the exact artwork that was ordered.
The Problem It Solves
Selling personalized print products usually means juggling a separate design tool, e-mailed proofs and manual file handling. Designs get lost between editor and checkout, and if a customer keeps editing after ordering, nobody knows which version is the one that was actually bought.
Key Benefits
For Customers
- Design where you shop — open the editor in a modal or on its own page directly from the product, no extra account or tool needed.
- Only design what needs a design — for products with several variants, the editor appears only for variants that are personalized; all others go straight into the cart as usual.
- Pre-filled with your data — name, e-mail, address and other selected profile details are placed into the template automatically.
- Nothing gets lost — values typed right before "Add to Cart" are saved with the design.
- Edit from the cart — reopen and change a design that is already in the cart.
- Keep working safely — after ordering you can continue editing your design; the ordered version stays exactly as it was.
- Download your files — get the rendered output (single item or complete batch) from the order view.
For Store Operators
- Order-safe artwork — every order gets its own frozen copy of the design, so production always prints what was ordered.
- Flexible product setup — assign a design template to a whole product or to individual variants; mix personalized and standard variants in one product.
- No orders without a design — personalized products without a design cannot be checked out or ordered, in the shop or via API.
- Clean project housekeeping in Cmash — designs are automatically marked as draft when they go into the cart and as finished when they are ordered; abandoned checkout attempts leave no orphaned copies.
- Traceable designs — Cmash shows which shop, customer and cart or order a design belongs to; multi-shop setups are told apart by a configurable system name.
- Robust checkout — communication problems with Cmash are logged but never block cart or checkout.
- Control which data is shared — decide per product or customer attribute whether it is sent to the editor, kept private, or not shared at all.
- Downloads in the admin — fetch production files straight from the order view.
How It Works
- The customer opens a product that is linked to a Cmash template (or selects a personalized variant) and clicks "Start Configuration".
- The editor opens, pre-filled with product and customer data; the customer designs the product.
- "Add to Cart" saves the design, places the product in the cart and marks the design as a draft.
- At checkout the ordered design is frozen as a separate copy and marked as finished.
- Customer and shop staff download the rendered files from the order.
Feature Highlights
| Feature | Description |
|---|---|
| Embedded editor | Modal or full-page Cmash editor on the product page |
| Variant-aware | Template per product or per variant; editor only for personalized variants, regular Add to Cart for all others |
| Data pre-fill | Product, customer, address and account-relation attributes sent as visible or private template data |
| Cart integration | Design linked to the cart item, editable from the cart and the wishlist |
| Order protection | Checkout and order placement require a design for every personalized item |
| Design lifecycle | Automatic status tracking: new → draft (cart) → finished (ordered) |
| Frozen order artwork | Each order line references its own copy of the design |
| Project references | Shop, customer, status (draft / quote / order) and cart or order number are stored with every design in Cmash |
| Downloads | Rendered files and batch ZIPs for customers and admins |
| Security | API token stays on the server, encrypted in the configuration; Cmash host whitelisted in the Content Security Policy |
| Translations | German, French and Italian storefront texts |
Technical Highlights for Integrators
- No core overrides: plugins, observers and declarative schema only.
- Works with Luma and, together with the Hyvä companion module, with Hyvä themes.
- Compiled-DI safe; editor page excluded from full page cache.
- Dedicated log file for all Cmash API communication.
- Reusable project state service for companion modules (e.g. drafts and wishlists).
Requirements
- Magento Open Source / Adobe Commerce 2.4.x, PHP 8.2, 8.3 or 8.4
- Enobis Cmash Core module
- Access to a Cmash Web2Publish instance with API token (a version that supports project references; app.cmash.io does)
What's New in 1.0.37
- Know when a saved design is gone — the shop can now check whether a design still exists in Cmash, so saved drafts whose design was removed there can be flagged instead of failing when the customer opens them (used by the Cmash Drafts module).
- No false alarms — a design is only reported as missing when Cmash clearly says so; connection problems never mark a design as deleted.
What's New in 1.0.36
- Every design knows where it belongs — Cmash projects now carry the shop, the customer and whether they are a draft, in a cart or ordered, plus the cart or order number, so designs can be matched with shop data in Cmash.
- Several shops, one Cmash account — give each shop its own system name in the configuration (default: the shop's host name) to tell them apart.
- Privacy-friendly — only the internal customer number is shared, no e-mail address; guests are simply left without a customer reference.
- Safe for checkout — if Cmash cannot be reached, the references are skipped and logged; cart and checkout keep working.
What's New in 1.0.35
- Personalized and standard variants in one product — each variant can have its own design template or none; customers see the editor only where it is needed and buy standard variants with the normal Add to Cart.
- Reliable variant switching — the editor always uses the design of the variant the customer just picked; changing a cart item to a variant with another design starts a fresh design.
- Safer cart — variants without a template can no longer be added as a design.
- No orders without a design (1.0.34) — personalized items without a design are sent back to the cart before checkout and cannot be ordered via storefront or API.
- Edit from cart and wishlist (1.0.34) — the existing design reopens reliably when editing an item.
Pricing & Licensing
For licensing information, pricing, and enterprise bundles, contact:
enobis GmbH www.enobis.de
Cmash Connector — Technical Documentation
Version 1.0.37. Keep this file in sync with the code; omit sections that do not apply.
Features
- Product page editor — "Start Configuration" opens the Cmash editor in a modal (
cmash/editor/create) or on its own page (cmash/editor/index) for products with a template (cmash_document_uuid); requirescmash/general/enabled. - Configurable products per variant (1.0.35) — the template is resolved per variant: the child's
cmash_document_uuidwins, the parent's is the fallback. If every variant has a template, the standard Add to Cart box is hidden. For mixed configurables (some variants without template) the editor button appears only once a variant with a template is fully selected; otherwise the regular Add to Cart is shown. - Add to Cart from the editor — the project is linked to the quote item (
cmash_project_uuidcustom option), editor values are synced to the project first.cmash/cart/addrejects variants/products without a template (1.0.35). - Edit from cart / wishlist — the cart or wishlist configure page reopens the item's project (1.0.34: project UUID kept in the preconfigured values). When a configurable item is reconfigured to a variant with a different template, a new project is started instead (1.0.35).
- Project required for ordering (1.0.34) — checkout and multishipping redirect to the cart, order placement (storefront, REST, GraphQL) fails and wishlist-to-cart is blocked while a Cmash product has no project.
- Project state sync — forward-only
temp→draft(cart) →finished(ordered), see below. - Frozen order artwork — each Cmash order item gets its own project copy at checkout; the source UUID is kept in
sales_order_item.cmash_source_project_uuid. - Project references (1.0.36) — every Cmash project carries external reference fields (shop, customer, owner type, quote/order ID), see "Project references" below. Requires a Cmash version that supports them (app.cmash.io does). Writes are best effort: failures are logged to
cmash.logand never break cart or checkout. - Downloads — rendered output per order item or as batch ZIP, frontend (customer) and admin order view.
- Attribute data — product, customer, address and account-relation attributes flagged "Used For Cmash Document" are sent to the editor.
- No list add to cart — Cmash products are not added to the cart directly from category/search lists; the add URL points to the product page.
- CSP — the Cmash host is added to
script-srcandframe-src.
Module Dependencies
| Module | Why |
|---|---|
| Magento_Catalog | cmash_document_uuid product attribute, product page button, used_for_cmash_document on catalog_eav_attribute |
| Magento_Customer | Customer/address attribute values sent to Cmash, used_for_cmash_document on customer_eav_attribute |
| Magento_Checkout | Cart add, cart item configure, checkout_cart_product_add_after |
| Magento_Store | Store-scoped configuration |
| Magento_Sales | sales_order_item columns, quote submit events, order view download buttons (used, not declared in composer.json/module.xml) |
| Magento_ConfigurableProduct | Child product resolution and per-variant templates (Model\Product\DocumentResolver) (used, not declared) |
| Magento_Quote | QuoteValidator plugin, cart project validation (used, not declared) |
| Magento_Wishlist | Wishlist-to-cart plugin (used, not declared) |
| Magento_Csp | CompositePolicyCollector entry for the Cmash host (used, not declared) |
| enobis/module-cmash-core | Composer requirement >=1.0.1 |
| Enobis_AccountRelationSwitcher | Optional; active relation attributes are sent to Cmash when the module is enabled |
Database Schema
etc/db_schema.xml adds to sales_order_item:
| Column | Type | Since | Purpose |
|---|---|---|---|
cmash_project_uuid |
varchar(255), nullable | — | Cmash project of the order item. From 1.0.33 this is the frozen copy made at checkout (falls back to the source UUID if copying failed). |
cmash_source_project_uuid |
varchar(255), nullable | 1.0.33 | Customer's original (draft/cart) project the copy was made from. |
Patches:
Setup/Patch/Data/AddCmashDocumentUuidAttribute— product attributecmash_document_uuid(varchar, store scope, group "Cmash Connector").Setup/Patch/Schema/AddUsedForCmashDocumentColumn—used_for_cmash_document(smallint) oncatalog_eav_attributeandcustomer_eav_attribute.
etc/catalog_attributes.xml adds cmash_document_uuid to the quote_item group so cart validation can read it on quote item products (1.0.34).
Configuration Paths
| Path | Scope | Default | Purpose |
|---|---|---|---|
cmash/general/enabled |
store | 0 |
Enables the connector (button, editor, cart add, downloads, CSP entries) |
cmash/general/system_identifier |
store | empty (shop host of web/unsecure/base_url) |
Value of reference_system on every project (max. 255 characters); Config::getSystemIdentifier(). Use different values if several shops share one Cmash account (1.0.36) |
cmash/api/base_url |
store | https://cmash.enobis.de |
Cmash host; API calls go to <base_url>/api/... |
cmash/api/token |
store | — | Sanctum bearer token (encrypted) |
ACL: Enobis_CmashConnector::config. Admin section: Stores > Configuration > Cmash > Cmash Connector (incl. module/composer version display).
Routes & Controllers
| URL | Class | Method | Notes (AJAX/JSON, login required, FPC) |
|---|---|---|---|
cmash/editor/index |
Controller\Editor\Index |
GET | Editor page; creates an embed project (or opens project_uuid), sending reference_system and reference_user (1.0.36); cmash.editor block not cacheable |
cmash/editor/create |
Controller\Editor\Create |
POST | JSON; form key; creates an embed project for the selected child (by super_attribute, template child-first/parent fallback via DocumentResolver) or returns the editor URL of an existing project_uuid; new projects get reference_system and reference_user (1.0.36) |
cmash/cart/add |
Controller\Cart\Add |
POST | Form key; rejects with "The selected option cannot be customized. Please add it to the cart without a design." and redirects back when the selected variant/product has no template (1.0.35); then syncs project_data, adds the product with cmash_project_uuid (custom option and buy request), super_attribute and options; replaces cart item item when editing and then redirects to the cart; invalidates cart section |
cmash/download/options |
Controller\Download\Options |
GET | JSON; login required; renderers of a project |
cmash/download/file |
Controller\Download\File |
POST | Login required; streams the rendered file |
cmash/download/batchFile |
Controller\Download\BatchFile |
POST | Login required; streams the batch ZIP |
admin cmash/download/options |
Controller\Adminhtml\Download\Options |
GET | ACL Magento_Sales::sales |
admin cmash/download/file |
Controller\Adminhtml\Download\File |
POST | ACL Magento_Sales::sales |
admin cmash/download/batchFile |
Controller\Adminhtml\Download\BatchFile |
POST | ACL Magento_Sales::sales |
DI: Preferences, Plugins, Virtual Types
| Type | Target | Class | Area | Purpose |
|---|---|---|---|---|
| argument | Model\Api\Client::$logger |
Enobis\CmashConnector\Logger\VirtualLogger |
global | API errors go to var/log/cmash.log |
| argument | Model\ProjectReference::$logger |
Enobis\CmashConnector\Logger\VirtualLogger |
global | Reference write errors go to var/log/cmash.log (1.0.36) |
| virtualType | Magento\Framework\Logger\Monolog |
Enobis\CmashConnector\Logger\VirtualLogger / VirtualHandler |
global | Dedicated log file |
| argument | Magento\Csp\Model\CompositePolicyCollector |
Model\Csp\CmashCollector\Proxy |
global | Adds the Cmash host to script-src and frame-src |
| plugin | Magento\Catalog\Model\Product\Type\AbstractType::isPossibleBuyFromList |
Plugin\DeactivateBuyFromListPlugin |
frontend | No direct "Add to Cart" from lists for Cmash products |
| plugin | Magento\Checkout\Helper\Cart::getAddUrl |
Plugin\FixAddToCartUrlPlugin |
frontend | Returns the product page URL (?options=cart) for Cmash products (Hyvä lists) |
| plugin | Magento\Catalog\Helper\Product::prepareProductOptions |
Plugin\KeepProjectUuidInPreconfiguredValuesPlugin |
frontend | Keeps cmash_project_uuid in the preconfigured values of cart/wishlist configure pages (1.0.34) |
| plugin | Magento\Quote\Model\QuoteValidator::validateBeforeSubmit |
Plugin\RequireProjectBeforeSubmitPlugin |
frontend, graphql, webapi_rest | Refuses order placement while a Cmash item has no project (1.0.34) |
| plugin | Magento\Wishlist\Model\Item::addToCart |
Plugin\RequireProjectForWishlistCartPlugin |
global | Blocks wishlist-to-cart of Cmash products without project ("Please customize the product before adding it to the cart."); core redirects to the wishlist configure page (1.0.34) |
Note: ProjectState, CopyProjectUuidToOrderItem and DeleteOrderedProjectCopies log via the default Psr\Log\LoggerInterface (system.log/exception.log); only Model\Api\Client writes to cmash.log.
Events & Observers
| Event | Observer | Area | Purpose |
|---|---|---|---|
checkout_cart_product_add_after |
Observer\AddCustomOptionToOrder |
frontend | Copies additional_options and cmash_project_uuid from the product to the quote item |
checkout_cart_product_add_after |
Observer\MarkProjectDraftOnCartAdd |
frontend | Sets the project from the cmash_project_uuid custom option to draft (all editor cart-add controllers, Luma and Hyvä) and queues it in ProjectReference for its quote reference (1.0.36) |
checkout_cart_save_after |
Observer\AssignQuoteProjectReference |
frontend | Once the cart is saved the quote has an ID: writes reference_status=quote and reference3=<quote ID> (plus reference_system, reference_user for customers) to the queued projects (enobis_cmash_assign_quote_project_reference, 1.0.36) |
controller_action_predispatch_checkout_index_index, controller_action_predispatch_multishipping |
Observer\RedirectToCartWithoutProject |
frontend | Redirects to the cart with an error while a Cmash item has no project (1.0.34) |
sales_model_service_quote_submit_before |
Observer\CopyProjectUuidToOrderItem |
global | Copies each ordered project (POST embed/projects/{uuid}/copy with state=temp plus the order references reference_status=order, reference3=<order increment ID>, reference_user for customers, 1.0.36); order item gets the copy UUID in cmash_project_uuid and the original in cmash_source_project_uuid; on copy failure the source UUID is used and an error is logged |
sales_model_service_quote_submit_success |
Observer\MarkOrderedProjectsFinished |
global | Sets each order item project (the copy) to finished |
sales_model_service_quote_submit_failure |
Observer\DeleteOrderedProjectCopies |
global | Deletes the copies and resets cmash_project_uuid to the source UUID |
adminhtml_catalog_product_attribute_edit_frontend_prepare_form |
Observer\ProductAttributeEditFrontendFormObserver |
adminhtml | "Used For Cmash Document" select on product attributes |
adminhtml_customer_attribute_edit_frontend_prepare_form |
Observer\CustomerAttributeEditFrontendFormObserver |
adminhtml | Same for customer attributes |
Project state lifecycle (1.0.33)
States in Cmash: temp (default on create) → draft → finished. Model\ProjectState only moves forward: it reads the current state (GET embed/projects/{uuid}) and sends PUT embed/projects/{uuid} {"state": ...} only when the target ranks higher (Cmash answers 422 on downgrades of finished projects). Unknown states rank as temp. All errors are logged, never thrown.
| Trigger | Project | Resulting state |
|---|---|---|
| Editor creates project | new project | temp (Cmash default) |
| Add to cart | cart project | draft |
| Quote submit before | new copy of the cart project | temp |
| Quote submit success | copy | finished (source stays draft) |
| Quote submit failure | copy | deleted |
Order cancellation does not change the state. Draft/wishlist states (save, finish) are handled by companion modules via Model\ProjectState.
Project references (1.0.36)
Model\ProjectReference builds and writes the external reference fields so Cmash can tell which shop, customer and owner a project belongs to. The existing reference (product-<id>) is unchanged.
| Field | Value |
|---|---|
reference_system |
cmash/general/system_identifier, default: host of web/unsecure/base_url; omitted when empty |
reference_user |
Magento customer ID; omitted for guests, never a placeholder |
reference_status |
Owner type: draft, quote or order |
reference2 |
Draft ID, only for type draft; otherwise null |
reference3 |
Quote ID for type quote, order increment ID for type order; otherwise null |
For an owner type, reference2 and reference3 are always sent (null clears values inherited from a copy); reference_user is only sent when known, so an existing value is never cleared.
| Trigger | Project | Fields written |
|---|---|---|
Editor creates project (Controller\Editor\Create, Index) |
new project | reference_system, reference_user (no owner yet; via Api\Client::createEmbedProject) |
Add to cart + checkout_cart_save_after |
cart project | reference_status=quote, reference3=<quote ID>, reference_system, reference_user (via PUT); queued on add because a new quote has no ID yet |
| Quote submit before | copy of the cart project | reference_status=order, reference3=<order increment ID>, reference_system, reference_user (customers only); sent with the copy request |
The cart project itself keeps its quote reference; only the frozen copy carries the order. Api\Client::createEmbedProject() forwards reference2, reference3, reference_system, reference_status and reference_user (null values are dropped). Updates and copies pass the fields through updateEmbedProject() / copyEmbedProject() overrides. Failures of ProjectReference::assign() are logged (cmash.log) and swallowed.
Layout Handles & Templates
| Handle | Block / Template | Purpose |
|---|---|---|
catalog_product_view |
Block\Product\View\CustomizeButton / product/view/customize_button.phtml |
Start/Edit Configuration button, modal editor, Cmash bridge script. Rendered when the product or at least one configurable child has a template. Hides .box-tocart (class cmash-hide-addtocart) only when isAlwaysCustomized(); otherwise the button wrapper starts hidden and modal-editor toggles both per selected variant |
cmash_editor_index |
Block\Editor / editor.phtml (cacheable="false") |
Full-page editor with Add to Cart form |
sales_order_view (frontend) |
Block\Sales\Order\View\Item\Download / sales/order/view/item/download.phtml |
Download button per order item (uses cmash_project_uuid, i.e. the frozen copy from 1.0.33) |
sales_order_view (adminhtml) |
Block\Adminhtml\Sales\Order\Item\Extra\Download / sales/order/item/extra/download.phtml |
Download in admin order view |
Frontend JavaScript
Enobis_CmashConnector/js/modal-editor— opens the editor in a modal (cmash/editor/create), reads editor values via the Cmash bridge and posts them asproject_datawith the cart form; dispatchescmash:toolbarondocument.- Config (x-magento-init from
CustomizeButton::getJsConfig(), 1.0.35):isConfigurable,alwaysCustomized,childDocumentUuids(child ID → template, parent fallback,''for regular variants),existingDocumentUuid(template of the cart item being reconfigured). super_attributeis read from thesuper_attribute[...]inputs of#product_addtocart_form(swatchdata-option-selectedattributes only as fallback; jQuery.data()returns stale cached swatch values).- Selected child: swatch widget
.data('mage-SwatchRenderer').getProduct()or.data('mage-configurable').simpleProduct, only when all options are selected. - For mixed configurables it listens to
changeandswatch.initializedon#product_addtocart_formand switches between editor button and regular Add to Cart; the button does nothing for variants without template. - The existing project of a reconfigured cart item is only reused when the selected variant has the same template; the project UUID input is cleared before create and on close.
- Config (x-magento-init from
Enobis_CmashConnector/js/editor—postMessagelistener for the full-page editor iframe.Enobis_CmashConnector/js/download-modal— loads renderers (cmash/download/options) and posts file/batch downloads withform_key.- External:
<base_url>/vendor/cmash-embed/js/cmash-bridge.js.
Customer Data Sections
etc/frontend/sections.xml: cmash/cart/add invalidates cart.
Key Classes
| Class | Responsibility |
|---|---|
Model\Config |
Config access (enabled, base URL, decrypted token, API endpoint, getSystemIdentifier() since 1.0.36) |
Model\Api\Client |
Cmash REST client: create/get/update/copy/delete embed projects (create forwards the reference* fields since 1.0.36), existence check embedProjectExists() (1.0.37), editor URL, render, documents, download options, file/batch download |
Model\ProjectReference |
Builds (forCreation(), forDraft(), forQuote(), forOrder()) and writes (assign(), queueForQuote()/flushQuote()) the project reference fields; best effort, logged to cmash.log (1.0.36) |
Model\ProjectState |
Forward-only project state sync (markDraft(), markFinished()), errors logged only |
Model\ProjectDataSync |
Merges editor form values into the project data; only for the customer whose e-mail is stored in the project |
Model\CmashAttributeDataBuilder |
Collects product/customer/address/account-relation attributes flagged used_for_cmash_document into data/private_data |
Model\DownloadService |
Shared download logic for frontend and admin controllers |
Model\Product\DocumentResolver |
Template per product (1.0.35): resolveChild() by super_attribute, getDocumentUuid() child-first/parent fallback, getChildDocumentUuids() |
Model\Cart\ProjectValidator |
Finds quote items of Cmash products (product or selected child has a template) without cmash_project_uuid (1.0.34) |
Block\Product\View\CustomizeButton |
Product page button state: isVisible(), isAlwaysCustomized(), getJsConfig(), getExistingProjectUuid() |
Model\Csp\CmashCollector |
CSP whitelist for the Cmash host |
Extension Points
Model\ProjectState(publicmarkDraft()/markFinished(), constantsTEMP/DRAFT/FINISHED) for other modules that save or finish projects.Model\ProjectReference(public) for other modules that own a project:forDraft(draftId, customerId)/forQuote()/forOrder()build the fields (merge into create/copy options),assign(uuid, fields)writes them to an existing project without throwing.forDraft()is not used by this module itself (1.0.36).Model\Api\Clientpublic methods incl.copyEmbedProject(uuid, overrides)(overrides:state,name,data, and thereference*fields since 1.0.36; withoutstatethe copy inherits the source state) anddeleteEmbedProject(uuid).Model\Api\Client::embedProjectExists(uuid): ?bool(1.0.37) —GET embed/projects/{uuid};truefor 2xx,falseonly for HTTP 404 (project deleted or unknown in Cmash),nullfor any other status or an exception (exceptions are logged tocmash.log). Callers must treatnullas "unknown", not as "missing". Not used by this module itself;enobis/module-cmash-draft1.0.7 uses it to flag drafts whose Cmash project no longer exists.Block\Editor::isAddToCartVisible()andBlock\Product\View\CustomizeButton::getExistingProjectUuid()are plugged by companion modules;CustomizeButton::getJsConfig()/isAlwaysCustomized()can be reused by theme adaptations.Model\Product\DocumentResolver(public, constantATTRIBUTE) for any code that needs the template of a product or variant.Model\Cart\ProjectValidator::getItemsWithoutProject()/getErrorMessage()for further checkout guards.- Observers can be disabled per name in
events.xml(e.g.enobis_cmash_mark_project_draft,enobis_cmash_assign_quote_project_reference,enobis_cmash_mark_ordered_projects_finished,enobis_cmash_delete_ordered_project_copies,enobis_cmash_redirect_to_cart_without_project).
Translations
i18n/de_DE.csv contains the German storefront phrases, including the Hyvä-only phrases of Enobis_CmashConnectorHyva (e.g. "Checking…"). Phrases already translated by the core or the splendidinternet/mage2-locale-de-de language pack are not repeated. Backend labels are not translated yet. i18n/en_US.csv lists the same phrases 1:1 as a reference for translators; i18n/fr_FR.csv and i18n/it_IT.csv contain the same phrases in French and Italian.
Changelog
1.0.37 (2026-10-30)
2026-10-30Add Client::embedProjectExists() to detect deleted Cmash projects, bump 1.0.37 (2b4fb44)
1.0.36 (2026-10-29)
-
2026-10-29Send Cmash project reference fields (system, customer ID, draft/quote/order), bump 1.0.36 (765f18f)Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
1.0.35 (2026-10-28)
2026-10-28Per-variant Cmash editor for configurable products, cart/add variant guard, bump 1.0.35 (3b96336)
1.0.34 (2026-10-27)
-
2026-10-27Require cmash project before cart/checkout (0c0d42c)Prevent ordering cmash products that were never customized in the document editor.
- Add ProjectValidator to find quote items whose product (or configurable child) has a cmash_document_uuid but no cmash_project_uuid option; load the attribute on quote item products via catalog_attributes.xml.
- Redirect onepage and multishipping checkout back to the cart with an error, and block order placement in QuoteValidator (frontend, REST, GraphQL).
- Block wishlist-to-cart for uncustomized cmash products so core redirects to the wishlist configure page.
- Store cmash_project_uuid in the buy request and keep it in preconfigured values so cart/wishlist configure pages reopen the existing project despite FPC.
- Cart add controller now forwards custom options and always redirects to the cart after updating an item.
- modal-editor.js: validate required options via mage/validation, collect product fields at submit time and preserve custom button labels.
- Add translations and bump version to 1.0.34.
1.0.33 (2026-10-25)
2026-10-25Sync Cmash project state (draft on cart add, finished on order) and freeze ordered projects as copies, bump 1.0.33 (ce21a54)
1.0.32 (2026-10-21)
-
2026-10-21Add de/fr/it translations and bump to 1.0.32 (cfabd72)Add German, French and Italian storefront translations (i18n/de_DE.csv, fr_FR.csv, it_IT.csv), including the Hyvä-only phrases.
Rebuild i18n/en_US.csv 1:1 with de_DE.csv as a translator reference. Unused, backend-only and language-pack phrases are removed.
Add a README describing the module's features, translations and changelog.
Bump the module version to 1.0.32 in composer.json and etc/module.xml.
1.0.31 (2026-10-20)
-
2026-10-20Add CSP collector and move editor toolbar to header (27aa71b)Add a CSP policy collector that whitelists the configured cmash host for script-src and frame-src, so the CmashBridge script and editor iframe load under Magento's CSP.
Rework the editor modal: replace the floating toolbar overlay with a header bar above the iframe, with a Cancel button on the left and actions on the right. Buttons now use the theme's
.action/.action.primarystyles, and Add to Cart gets a cart icon. Thecustom_toolbar_widthURL parameter is no longer needed and is removed.Remove README.md and bump the version to 1.0.31.
1.0.30 (2026-10-20)
-
2026-10-20Sync editor data to cmash project on add to cart (8388ee2)The cmash editor only autosaves ~2s after a field loses focus, so values entered right before Add to Cart were lost on navigation.
The editor values are now read via CmashBridge::getVariables() and sent as
project_data. The new Model\ProjectDataSync persists them to the project in Cart\Add. It only writes when the logged-in customer's email matches the project'scustomer_email, and skips unchanged data.Also added:
cmash:toolbarJS hook in modal-editor.js, with postForm/postAjax/preflight helpers- Preflight check and data sync for header forms on the editor page
- Block\Editor::isAddToCartVisible() plugin point and getCmashBridgeUrl()
- CustomizeButton::getQuoteItemId(), which resolves the item ID only on checkout_cart_configure, since the wishlist configure page uses
idfor a different entity - README documenting features and extension points
- Version bump to 1.0.30
1.0.23 (2026-07-22)
-
2026-07-22Version 1.0.23 (a62761b)Add batch/compilation download to order and digital output "download button"
-
2026-07-22Add batch/compilation download to order and digital output "download button" (e5d42a6)
1.0.22 (2026-07-22)
-
2026-07-22Version 1.0.22 (8276dbf)Add preflight check
-
2026-07-22Add preflight check (1bdbada)
1.0.21 (2026-07-16)
-
2026-07-16Version 1.0.21 (5c675a5)Add better select-attribute option handling for "used-for-cmash" attributes, use global-scope e.g. "EN", and also add attribute + '_label' for store_view scope option value e.g. "english"
1.0.20 (2026-07-16)
-
2026-07-16Support configurable product UUID resolution (a7b9599)The customize button logic now supports configurable products by rendering when child variants contain
cmash_document_uuidvalues, adding child UUID mapping helpers, and trimming UUID values to avoid whitespace-only data. The editor create controller now also trims UUIDs and keeps child-first, parent-fallback resolution for reliable template selection. Module and package versions were bumped to 1.0.20, and the README was removed.
1.0.19 (2026-07-15)
-
2026-07-15Validate product form before opening editor (be9321e)Adds a mandatory custom options check before opening the modal editor. Uses reportValidity() on the add-to-cart form to surface validation errors to the user early, preventing the editor from opening when required fields are missing. Also bumps version to 1.0.19.
1.0.18 (2026-07-02)
-
2026-07-02Version 1.0.18 (bb7cc4d)Add relation/relation-address attributes with standard/private data support
-
2026-07-02Version 1.0.18 (0a5bb38)Add relation/relation-address attributes with standard/private data support
1.0.17 (2026-07-02)
-
2026-07-02Version 1.0.17 (e391612)Add address attributes with standard/private data support
-
2026-07-02Add address attributes with standard/private data support (7b559a8)
1.0.16 (2026-07-02)
-
2026-07-02Version 1.0.16 (19d5934)Optimize standard/private data
-
2026-07-02Optimize standard/private data (80a5896)
1.0.15 (2026-07-01)
-
2026-07-01Version 1.0.15 (a20367b)Add functionality for standard/private data
-
2026-07-01Add functionality for standard/private data (1548e6a)
1.0.14 (2026-06-26)
-
2026-06-26Redirect add-to-cart URL to PDP for cmash (6bb6cb1)Add FixAddToCartUrlPlugin to intercept Magento\Checkout\Helper\Cart::getAddUrl() and return the product detail page URL (with ?options=cart) when the product has a cmash_document_uuid and the module is enabled. Register the plugin in etc/frontend/di.xml and bump module and composer versions to 1.0.14. This ensures themes that call the low-level Cart helper (e.g. Hyvä) send customers to the PDP before adding configured cmash products to cart; Luma/Blank remain unaffected due to existing checks and the DeactivateBuyFromListPlugin.
1.0.13 (2026-06-10)
-
2026-06-10Version 1.0.13 (cb2fe60)Disable possibility to buy from lists
-
2026-06-10Version 1.0.13 (9d4e0c7)Disable possibility to buy from lists
1.0.12 (2026-06-10)
-
2026-06-10Version 1.0.12 (863272d)Add download in order frontend and backend
-
2026-06-10Version 1.0.12 (342df5c)Add download in order frontend and backend
-
2026-06-10Add cmash_project_uuid to order_item table (efd8c6d)and persist from quote option
1.0.11 (2026-06-10)
-
2026-06-10Version 1.0.11 (d6785d1)Optimize standard buttons to magento2 add to cart button style
-
2026-06-10Version 1.0.11 (8d1b8de)Optimize standard buttons to magento2 add to cart button style
1.0.10 (2026-06-09)
-
2026-06-09Version 1.0.10 (490f76e)fast fix 2
1.0.9 (2026-06-09)
-
2026-06-09Version 1.0.9 (998966d)fast fix
1.0.8 (2026-06-09)
-
2026-06-09Version 1.0.8 (8c2425c)Add support for "unified toolbar" Fix configurable product and configure bugs
-
2026-06-09Version 1.0.8 (0849e73)Add support for "unified toolbar" Fix configurable product and configure bugs
1.0.7 (2026-06-09)
-
2026-06-09Version 1.0.7 (b2c72a4)Add support for configurable products Add user_for_cmash_document Optimize product detail buttons
-
2026-06-09Version 1.0.7 (e5293dd)Add support for configurable products Add user_for_cmash_document Optimize product detail buttons
1.0.6 (2026-06-09)
-
2026-06-09Version 1.0.6 (a1c48e1)Add support for child html buttons e.g. datachooser
-
2026-06-09Add support for child html buttons e.g. datachooser (3f9a9c2)
1.0.5 (2026-06-08)
-
2026-06-08Version 1.0.5 (242a216)Optimize
1.0.4 (2026-06-08)
-
2026-06-08Version 1.0.4 (31b781b)Rename enobis/module-web2print to enobis/module-cmash-connector
1.0.3 (2026-06-08)
-
2026-06-08Version 1.0.3 (dea7df0)Remove w2p_template_id
-
2026-06-08Remove w2p_template_id (b974abd)
1.0.2 (2026-05-26)
-
2026-05-26Bump module version to 1.0.2 (a4a6f74)Prepare a patch release by updating the module version. Incremented version in composer.json and setup_version in etc/module.xml for Enobis_Web2Print to 1.0.2.
1.0.1 (2026-05-17)
-
2026-05-17Version 1.0.1 (937b2fb)Fix "Customize with Web2Print" always created a new project, (e.g. in card configure mode, the associated project is now loaded correctly instead of creating always a new one)
-
2026-05-17Fix "Customize with Web2Print" always created a new project, (e.g. in card configure mode, the associated project is now loaded correctly instead of creating always a new one) (99edddc)
1.0.0 (2026-04-30)
-
2026-04-30Add Enobis Web2Print Magento module (6193a4c)Introduce a new Enobis_Web2Print Magento 2 module that integrates Magento with a Web2Publish (W2P) REST API for Typst-based product customization. Key additions:
- Core: Model/Config (admin config access) and Model/Api/Client (HTTP client for W2P endpoints with create/get/update project, render, documents).
- Frontend/controllers: Editor (Index, Create) and Cart/Add for creating embed projects and adding customized products to cart.
- Blocks and templates: Editor block and product customize button block plus editor and button templates, iframe-based editor page, CSS and JS scaffolding.
- Admin: system.xml + acl.xml entries, admin field renderers for module/composer version, etc/config defaults, di.xml logger virtual types.
- Setup patches: AddW2pTemplateAttribute and AddW2pDocumentUuidAttribute to create product attributes for linking templates/documents.
- Observer: AddCustomOptionToOrder to persist custom options (project UUID / additional options) from quote to order.
- Module metadata: composer.json, registration.php, module.xml, i18n strings, README and .instructions.md docs.
The module ensures the API token remains server-side and provides server-side endpoints to create projects, fetch editor URLs and add project metadata to cart items.
README.md
Cmash Connector — Enobis_CmashConnector
Overview
Connects Magento 2 to the Cmash Web2Publish system. Customers personalize template-based products (simple products or individual variants of configurable products) in the Cmash editor on the product page and add the resulting project to the cart. Shop admins and customers download the rendered files from the order.
Installation
composer require enobis/module-cmash-connector
bin/magento module:enable Enobis_CmashConnector
bin/magento setup:upgrade # required from 1.0.33 (new column sales_order_item.cmash_source_project_uuid)
bin/magento setup:di:compile # production / compiled DI
bin/magento cache:flush
Configuration
- Stores > Configuration > Cmash > Cmash Connector: enable the module, set the Cmash API base URL and the API token.
- Stores > Configuration > Cmash > Cmash Connector > General > System Identifier (
cmash/general/system_identifier, optional): name of this shop sent to Cmash with every project so Cmash can tell which shop a project belongs to. Leave empty to use the shop host name; use different values if several shops share one Cmash account. - Product attribute "CmashConnector Document UUID" (
cmash_document_uuid, group "Cmash Connector"): assigns the Cmash template. On configurable products it can be set on the parent (applies to all variants) or per variant (child value wins); variants without a template are sold with the regular Add to Cart. - Product and customer attributes: "Used For Cmash Document" controls whether an attribute value is sent to the editor (visible or private).
Compatibility
| Component | Version |
|---|---|
| Magento Open Source / Adobe Commerce | 2.4.x |
| PHP | ~8.2.0 | ~8.3.0 | ~8.4.0 |
| magento/framework | ^103.0 |
| enobis/module-cmash-core | >=1.0.1 |
| Cmash Web2Publish | version with project reference fields (reference2, reference3, reference_system, reference_status, reference_user); app.cmash.io supports them (since 1.0.36) |
Technical Documentation
Features and technical details are described in DOCUMENTATION.md.