Download the PHP package copex/module-warranty-label without Composer
On this page you can find all versions of the php package copex/module-warranty-label. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download copex/module-warranty-label
More information about copex/module-warranty-label
Files in copex/module-warranty-label
Package module-warranty-label
Short Description Magento 2 EU harmonised notice on the legal guarantee of conformity and EU GARAN label for commercial guarantees of durability (Implementing Regulation (EU) 2025/1960)
License MIT
Homepage https://copex.io
Informations about the package module-warranty-label
CopeX_WarrantyLabel
Magento 2 extension implementing the two EU pre-contractual information tools that become mandatory on 27 September 2026 under Directive (EU) 2024/825 and Implementing Regulation (EU) 2025/1960:
- Harmonised notice on the legal guarantee of conformity (Annex I) — required of every shop selling goods to consumers in the EU.
- EU GARAN label (Annex II) — required wherever a producer offers a free commercial guarantee of durability covering the entire good for more than two years.
Compliance reference — the mapping of each legal requirement to its implementation, including the known gaps, is maintained in
docs/COMPLIANCE-DE.md(German). Hand that document to legal counsel.Asset provenance and licences — see
view/base/web/ASSETS.md.This module does not constitute legal advice.
Table of Contents
- Requirements
- Installation
- Configuration
- Product data for GARAN
- Guarantee terms attachment
- Audit command
- Themes
- Translations
- Testing
Requirements
- PHP >= 8.2 with ext-gd compiled with FreeType (the GARAN label is rendered server-side onto the official background images; without FreeType the renderer throws and no label is produced)
- Magento 2.4.x
Installation
To remove it again, use bin/magento module:uninstall CopeX_WarrantyLabel --remove-data. The flag is not
optional: without it the four GARAN attributes survive with a backend_model pointing at classes that are
gone, and every product page then fails. The uploaded guarantee terms PDF is deliberately kept.
The module is off by default. copex_warrantylabel/general/enabled = 0 is also the kill switch: setting it to
"No" removes every notice and label output for that scope.
Configuration
Stores → Configuration → Sales → EU Guarantee Notice & GARAN Label, all settings scoped per store view.
| Group | Purpose |
|---|---|
| General Settings | Kill switch, label language, Your Europe link in a new tab or the same one, nested button text, notice alt text, minimum notice width, product types without a legal guarantee |
| Legal Guarantee Notice Placements | Display mode per placement: header, footer, category, search, cart, checkout, success page; yes/no for the order confirmation email |
| EU GARAN Label | Kill switch, display mode per placement, yes/no for the email, and the guarantee terms attachment |
Every storefront placement takes one of four modes:
- Off — no output.
- Direct — the official graphic is shown inline.
- Nested — a button opens a native
<dialog>containing the full graphic, as permitted by the EU practical guidelines. Use this wherever the container is narrower than the configured minimum width; the checkout sidebar of most themes is. - Dialog only — the same dialog without the button, for shops that place their own trigger. See below.
The two email fields take an EmailMode instead, because an email cannot open a dialog: no, inline or
attachment. attachment sends the graphic as a PNG file rather than in the body, for clients that block remote
images; the GARAN labels are then attached one per labelled item, named garan-label-<sku>.png, and the notice as
legal-guarantee-notice.png.
Everything ships switched off — both kill switches and every single placement. A freshly installed module changes
nothing in the storefront until the placements are chosen deliberately; docs/EN.md section 4.2 suggests where to
start.
Your own trigger
In Dialog only the module renders the <dialog> and leaves the trigger to you. Any element carrying the class
copex-wl-trigger and an aria-controls with the dialog id opens it, wherever it sits on the page — a CMS block, the
footer, a template of your theme:
The ids are copex-wl-notice-<placement> for the notice — copex-wl-notice-header, -footer, -cart, -category,
-search, -checkout, -success — and copex-wl-garan-pdp for the GARAN label on the product page. On the success
page and in the checkout the GARAN ids carry the item id, so read them from the rendered markup.
Triggers are bound when the page loads. One added later, by a script of your own, needs to be in the DOM before that.
Label language is not the locale. general/language selects which of the 24 official language versions is shown;
it falls back to the locale language, then to English. A German-locale store view serving English-speaking customers
can therefore show the English notice.
Product data for GARAN
Four EAV attributes are added to every product type, with store view scope:
| Attribute | Notes |
|---|---|
garan_brand |
Width-validated against the label field |
garan_model_identifier |
Width-validated against the label field |
garan_duration_years |
Accepts 4,5 and 4.5; must be > 2, <= 99 and a multiple of 0.5 |
garan_terms_url |
Must be a valid http(s) URL; without it no label is rendered |
A label appears only when all four are valid. Configurable products resolve through the selected child, never before a variant is chosen; a child whose field is empty inherits it from its configurable parent. Bundles resolve across all children.
Fallbacks for empty fields. The product always wins; these only fill a gap:
| Setting | Effect |
|---|---|
garan/brand_source |
garan_attribute (default), product_attribute (any text/textarea/select attribute, chosen in garan/brand_attribute, resolved to its option label), or config_value (the fixed garan/brand_value) |
garan/model_source |
garan_attribute (default) or product_name |
garan/terms_url |
One URL for every product without its own |
model_source = product_name is width-validated like any other value: a name too long for the shared brand/model line
is rejected, not shrunk, and the product gets no label with the audit reason too_long. Spot-check with
bin/magento copex:warranty-label:audit --store=<id>.
Half-year durations: at the official font size only whole years 3–99 and 7,5 fit in front of the calendar icon.
Other ,5 values are accepted as data but produce no label and the audit reason duration_does_not_fit, because
shrinking the type or moving the icon would breach the design rules.
Guarantee terms attachment
The producer's guarantee statement must reach the consumer on a durable medium at the latest at delivery (Art. 17(2) Directive (EU) 2019/771; § 9a (3) KSchG; § 479 (2) BGB). A link on a website does not satisfy this (CJEU C-49/11, Content Services).
The module therefore attaches one configured PDF per store view to the order confirmation of every order containing a GARAN product, without any third-party email extension. Configure it under the GARAN group:
| Setting | Meaning |
|---|---|
garan/attach_terms |
Enable the attachment |
garan/terms_file |
The PDF, uploaded in the admin |
garan/terms_filename |
File name the customer sees |
The PDF must be uploaded through the admin. bin/magento config:set cannot write type="file" fields, because
the backend model expects a real upload. The stored value is scope-prefixed: a default-scope upload yields
default/file.pdf below pub/media/copex_warranty_label/terms/, a store-view upload stores/<id>/file.pdf.
One document per store view is sufficient as long as it names the goods it covers.
Audit command
Lists products whose GARAN data is incomplete or invalid, with a reason code per row. The module never invents guarantee data — deciding which products qualify and maintaining their values is the merchant's responsibility.
Themes
Luma (and Blank) is supported out of the box and is what the module is tested against. Every placement is an
ordinary Magento core container — header-wrapper, footer, content, cart.summary, product.info.main. No
third-party theme is required anywhere.
Hyvä
Supported.
Keep the shipped defaults — nested for the storefront placements: the notice graphic is 420 x 594 px and direct pushes a Hyvä header or footer apart.
The nested dialog and the GARAN variant switch need no project setup. Both hang on data-mage-init in the shared
templates, which Hyvä never initialises, so view/frontend/web/js/hyva/warranty-label.js reads the same
configuration out of the same attributes and binds the same DOM, without jQuery and without AMD.
view/frontend/layout/hyva_default.xml loads it — Hyvä adds the hyva_ prefixed handles only while a Hyvä theme
is active, so Luma keeps its AMD modules untouched.
The GARAN label on the product page is the one placement a Hyvä project has to make itself. The module's anchor resolves in Luma only, so the label otherwise renders at the bottom of the product column. Place it in the theme:
Checkout
The checkout uses two regions of Magento_Checkout:
| Output | jsLayout node | Where Luma shows it |
|---|---|---|
| Notice and the GARAN labels of all items | steps > billing-step > payment > payments-list > before-place-order |
inside the selected payment method, directly above the place order button — next to the checkout agreements |
| GARAN labels of one item | sidebar > summary > cart_items > details, region after_details |
below the item in the order summary |
Magento renders before-place-order once per payment method, so the dialog ids of the nested display are made
unique at runtime. A payment method whose template leaves that region out shows neither the checkout agreements
nor the notice — select every payment method of the shop once and look for the notice above its button.
A project theme that moves the price out of product.info.main also has to move the GARAN block, and a checkout
whose place order button lives outside the payment methods — or a payment method without the region — needs the
two checkout components somewhere else. Do that in the project, not in this module. The parent has to be a node
with a component of its own, otherwise the children are never attached; afterMethods below the payment methods
is one Magento provides:
Hyvä renders the checkout through the Luma fallback theme (Hyva_LumaCheckout, part of a standard Hyvä
installation), so RequireJS and Knockout are available and everything in this section applies there unchanged.
Only a project running Hyvä Checkout has to port the three components — contributions for that are welcome.
Translations
i18n/de_DE.csv and i18n/de_AT.csv ship with the module. Magento loads module CSVs by exact locale only, so a new
locale needs its own file rather than a language fallback.
Testing
GaranPngRendererTest exercises real GD and FreeType in a temporary directory, and FieldFitCheckerTest reads the
bundled Inter TTFs, so both need a GD build with FreeType support.
Manual checks that no unit test replaces: scanning the QR code from screen and from a printed email, operating the nested dialog by keyboard alone, and a screenshot pass per placement and store view.
License
MIT — see LICENSE. © CopeX GmbH.
The bundled EU artwork and the Inter fonts carry their own terms; LICENSE names them.
All versions of module-warranty-label with dependencies
ext-gd Version *
magento/framework Version *
magento/module-catalog Version *
magento/module-checkout Version *
magento/module-config Version *
magento/module-configurable-product Version *
magento/module-eav Version *
magento/module-quote Version *
magento/module-sales Version *
magento/module-store Version *