Skip to content

Latest commit

 

History

History
76 lines (56 loc) · 4.59 KB

File metadata and controls

76 lines (56 loc) · 4.59 KB

PrestaShop — Cross-Domain Gotchas

Naming mismatches, identity traps, and non-obvious cross-domain relationships that affect agents working across multiple domains. Sourced from codebase exploration — verified against actual source.

Naming mismatches

What you'd expect What it actually is Where
Discount ObjectModel CartRule (2 224 lines) classes/CartRule.php
CatalogPriceRule ObjectModel SpecificPriceRule classes/SpecificPriceRule.php
CustomerService domain internals Everything named CustomerThread src/Adapter/CustomerService/, CustomerThreadRepository
AliasController SearchAliasController (under ShopParameters) src/PrestaShopBundle/Controller/Admin/
ContactController ContactsController (plural) src/PrestaShopBundle/Controller/Admin/
CmsPage adapter path src/Adapter/CMS/Page/ (not Adapter/CmsPage/)
CmsPageCategory adapter path src/Adapter/CMS/PageCategory/

Identity traps

Address — duplication on order edit

  • When an address linked to an order is modified, PrestaShop duplicates it and creates a new row with a new AddressId
  • The original address data is preserved for the existing order

Carrier — dual ID

  • CarrierId changes on every edit when it is assigned to an order (PrestaShop copies the row and increments the ID on update)
  • CarrierReferenceId is stable across edits — use this for any persistent reference to a carrier
  • Never store CarrierId long-term; always resolve via CarrierReferenceId

Module — string identity

  • Primary identity is ModuleTechnicalName (the folder name string), not ModuleId (int)
  • CQRS commands take ModuleTechnicalName; the int ID is legacy-only

Tab — class name identity

  • Tab is identified by its controller class name string (e.g. AdminProductsController), not a numeric ID
  • No Query layer — reads go through TabDataProvider directly

Cross-domain write ownership

Entity Who owns writes
CartRule (discount codes) Discount domain — not CartRule (CartRule domain is query-only)
Credit slips Order domain — CreditSlip domain is query-only
Combination Sub-entity of ProductCombinationId is always scoped to a ProductId
Order invoice / payment / product line Sub-domains inside Order (Order/Invoice/, Order/Payment/, Order/Product/)
Customer group membership Customer domain — Group is a sub-domain inside Customer

Adapter path exceptions

Most domains follow src/Adapter/{DomainName}/. Exceptions:

  • CmsPagesrc/Adapter/CMS/Page/
  • CmsPageCategorysrc/Adapter/CMS/PageCategory/
  • ImageSettings → handlers live in src/Core/Domain/ImageSettings/CommandHandler/ (no separate Adapter folder)
  • Theme → handlers live in src/Core/Domain/Theme/CommandHandler/ (Core, not Adapter — unusual)

Handlers in Core (not Adapter)

Normally: interfaces in Core, concrete implementations in Adapter. Exceptions where concrete handlers are in Core:

  • ImageSettings domain handlers
  • Theme domain handlers

When adding a handler to these domains, follow the existing pattern (Core) rather than the standard pattern. When handlers are migrated to the future persistence system (probably Doctrine), they should be moved into the Core namespace.

Translation catalog extraction

Never wrap TranslatorInterface::trans() — not in a private helper, not in a closure, not in a base-class proxy. The translation-catalog extractor scans for direct ->trans('literal string', [...], 'Domain') calls in source; anything that hides the call (e.g. $this->t(...), $t(...), $translatable->translate(...)) is invisible to the extractor and the wording will not be added to the catalog, or its domain will be lost.

Always call $this->translator->trans($message, $parameters, $domain) directly at every call site, even when it's repetitive — readability cost is real but extraction correctness is non-negotiable. If you find an existing helper, fix the helper's call sites instead of adding more.

Legacy class size warnings

Domain Legacy class Lines Risk
Discount classes/CartRule.php ~2 224 God object — never add logic
Cart classes/Cart.php ~5 000 God object — never add logic
Product classes/Product.php ~6 000+ God object — never add logic
Order classes/Order.php ~2 000+ God object — never add logic
Customer classes/Customer.php ~1 500+ Do not extend