CartWidget
extends BaseComponent
in package
uses
CartPreviewTrait, InitTrait, MiniCartTrait
Renders the header cart: a count badge plus a dropdown mini cart.
Rendered in the eshop header on every page of the purchase flow; ComponentTrait resolves
it from {control frontEshopCartWidget} through the DI factory.
IMPORTANT: on websites without an eshop (catalog.only = 1) it renders nothing and the
mini cart signals end with 404; the same gate guards the add-to-cart buttons and the cart
and checkout presenters.
Snippets:
cartWidget: the whole widget, redrawn by add-to-cart from the catalog (AddToCartTrait).cartCount: the badge inside the link.cartDetail: the panel content.
IMPORTANT: a quantity change from the panel redraws only cartCount and cartDetail, never
cartWidget. Bootstrap keeps the dropdown instance on the toggle element; replacing it under
an open panel closes the panel. For the same reason the panel has data-bs-auto-close="outside".
The panel content is loaded on first open (signal loadDetail!), because the total needs a
full server recalculation (api/eshop/order/checkout) that must not run on every page load.
render() does not call the Api while the panel is closed (InitTrait::prepareDetail()).
Table of Contents
Constants
- COUNT_DISPLAY_MAX : int = 99
- Highest quantity the badge prints as a number; above it the badge shows "99+".
- SETTINGS_MODULE_ESHOP : int = 4
- Settings module id of the eshop.
Properties
- $container : Container
- $routerDispatcher : RouterDispatcher
- $translator : ITranslator
- $appContext : AppContext
- $componentParameters : array<string, mixed>
- $currencyContext : CurrencyContext|null
- $deviceDetector : DeviceDetector|null
- $languageContext : LanguageContext|null
- $localizationContext : LocalizationContext|null
- $settingContext : SettingContext
- $themeContext : ThemeContext|null
- $translatorDomain : string|null
- $cart : CartManager
- $checkoutManager : CheckoutManager
- $detailLoaded : bool
- Whether the panel content was loaded by `loadDetail!` ({@see MiniCartTrait}); until then a loading state is rendered.
- $preview : array<string, mixed>|null
- Api preview, filled by `render()` and shared by submit handlers for messages.
- $productSetManager : ProductSetManager
Methods
- __call() : mixed
- Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
- __construct() : mixed
- createComponent() : IComponent|null
- getAppContext() : AppContext
- getComponentParameter() : mixed
- Returns a component parameter, or null when it is not set.
- getContainer() : Container
- getCurrencyContext() : CurrencyContext|null
- getLanguageContext() : LanguageContext|null
- getLocalizationContext() : LocalizationContext|null
- getRouterDispatcher() : RouterDispatcher
- getSettingContext() : SettingContext
- getSettings() : array<int, array<string, mixed>>
- getThemeContext() : ThemeContext|null
- handleDecrease() : void
- handleIncrease() : void
- handleLoadDetail() : void
- First panel open; the only request allowed to trigger the Api cart recalculation.
- handleRemove() : void
- hasServiceByType() : bool
- Returns whether the container has a service of the given type.
- initializeAllContexts() : void
- injectDeviceDetector() : void
- onCreate() : void
- render() : void
- setAppContext() : $this
- setComponentParameter() : void
- Sets a component parameter.
- setCurrencyContext() : $this
- setLanguageContext() : $this
- setLocalizationContext() : $this
- setSettingContext() : $this
- setThemeContext() : $this
- setup() : void
- setupAppContext() : void
- typedComponent() : T
- Returns a subcomponent with a verified type.
- frontPresenter() : BasePresenter|null
- Returns the front presenter the component is attached to (null outside the front end or when detached).
- getTranslator() : ITranslator
- setTemplateFile() : void
- setTranslator() : self
- allowsOutOfStockOrder() : bool
- Returns whether goods that are not in stock may be ordered (`order.outOfStock.allowed`); the same gate as in the catalog ({@see \App\UI\Front\Eshop\Presenters\Traits\Inits\CatalogOnlyGuardTrait::allowsOutOfStockOrder()}).
- blockedSetIds() : array<int, int>
- Returns the set ids that block the continue-to-order button: rows the stock does not cover in the requested quantity (or that cannot be ordered at all) and sets without a price in the cart currency, which only the server preview knows (otherwise they would reach checkout and fail with a generic error). The server strict reservation on submit remains the last authority.
- buildRows() : array<int, array<string, mixed>>
- Merges session rows (setId and quantity) with preview data (name, price, uncovered stock) and catalog availability.
- createMultiplierComponent() : Multiplier<string|int, IComponent>
- Creates a multiplier for the component.
- createNewComponentInstance() : IComponent|null
- Creates a new component instance without adding it to the presenter; used by the multiplier.
- createStandardComponent() : IComponent|null
- Creates a standard component (not a multiplier).
- guardEnabled() : void
- A disabled eshop (`catalog.only = 1`) has no cart or panel; the same gate as `addToCart!`.
- hasUnavailableRow() : bool
- Returns whether anything in the cart blocks submitting the order.
- int() : int
- isCatalogOnly() : bool
- loadPreview() : array<string, mixed>
- Returns the Api preview, computed once per request and shared by `render()` and handlers (otherwise the same recalculation would run twice).
- num() : numeric-string
- openDetail() : void
- Keeps the panel open and redrawn after each change.
- prepareDetail() : void
- Called only with the panel open; the only place where the widget touches the Api.
- prepareWidget() : bool
- rowFees() : array<int, array{name: string, price: numeric-string}>
- Returns informational row fees in the display price column (see `buildRows()`).
- str() : string
- DBAL/Api scalar (mixed) → string, guarded.
- unpricedItems() : array<int, string>
- Returns sets the Api omitted from the preview because they have no price in the cart currency.
- vatNoteMode() : bool|null
- Returns the VAT note variant for cart templates: `null` means the order charges no VAT and VAT is not mentioned; `true` means prices are shown with VAT. The Api sends `showPricesWithVat` equal to `withVat` (the VAT engine treatment; the seller switch `show_prices_with_vat` is no longer read), so `false` does not occur today. A preview without an Api response gives `null`, because silence is safer than a false claim.
Constants
COUNT_DISPLAY_MAX
Highest quantity the badge prints as a number; above it the badge shows "99+".
private
int
COUNT_DISPLAY_MAX
= 99
The badge is two characters wide and a four-digit count would stretch it across the header.
The exact count is kept in data-cart-count (read by JS) and in the screen reader label.
SETTINGS_MODULE_ESHOP
Settings module id of the eshop.
private
int
SETTINGS_MODULE_ESHOP
= 4
Properties
$container
public
Container
$container
Attributes
- #[Inject]
$routerDispatcher
public
RouterDispatcher
$routerDispatcher
$translator
public
ITranslator
$translator
Tags
$appContext
protected
AppContext
$appContext
$componentParameters
protected
array<string, mixed>
$componentParameters
= []
component parameters set by setComponentParameter()
$currencyContext
protected
CurrencyContext|null
$currencyContext
= NULL
$deviceDetector
protected
DeviceDetector|null
$deviceDetector
= NULL
$languageContext
protected
LanguageContext|null
$languageContext
= NULL
$localizationContext
protected
LocalizationContext|null
$localizationContext
= NULL
$settingContext
protected
SettingContext
$settingContext
$themeContext
protected
ThemeContext|null
$themeContext
= NULL
$translatorDomain
protected
string|null
$translatorDomain
= 'front.eshop.components.cartWidget'
$cart read-only
private
CartManager
$cart
$checkoutManager read-only
private
CheckoutManager
$checkoutManager
$detailLoaded
Whether the panel content was loaded by `loadDetail!` ({@see MiniCartTrait}); until then a loading state is rendered.
private
bool
$detailLoaded
= false
$preview
Api preview, filled by `render()` and shared by submit handlers for messages.
private
array<string, mixed>|null
$preview
= null
$productSetManager read-only
private
ProductSetManager
$productSetManager
Methods
__call()
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
public
__call(string $name, array<string|int, mixed> $args) : mixed
Called only when the component has no renderXyz() method of its own.
Parameters
- $name : string
- $args : array<string|int, mixed>
__construct()
public
__construct(CartManager $cart, CheckoutManager $checkoutManager, ProductSetManager $productSetManager) : mixed
Parameters
- $cart : CartManager
- $checkoutManager : CheckoutManager
- $productSetManager : ProductSetManager
createComponent()
public
createComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullgetAppContext()
public
getAppContext() : AppContext
Return values
AppContextgetComponentParameter()
Returns a component parameter, or null when it is not set.
public
getComponentParameter(string $name) : mixed
Parameters
- $name : string
getContainer()
public
getContainer() : Container
Return values
ContainergetCurrencyContext()
public
getCurrencyContext() : CurrencyContext|null
Return values
CurrencyContext|nullgetLanguageContext()
public
getLanguageContext() : LanguageContext|null
Return values
LanguageContext|nullgetLocalizationContext()
public
getLocalizationContext() : LocalizationContext|null
Return values
LocalizationContext|nullgetRouterDispatcher()
public
getRouterDispatcher() : RouterDispatcher
Return values
RouterDispatchergetSettingContext()
public
getSettingContext() : SettingContext
Return values
SettingContextgetSettings()
public
getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>getThemeContext()
public
getThemeContext() : ThemeContext|null
Return values
ThemeContext|nullhandleDecrease()
public
handleDecrease(int $setId) : void
Parameters
- $setId : int
handleIncrease()
public
handleIncrease(int $setId) : void
Parameters
- $setId : int
handleLoadDetail()
First panel open; the only request allowed to trigger the Api cart recalculation.
public
handleLoadDetail() : void
handleRemove()
public
handleRemove(int $setId) : void
Parameters
- $setId : int
hasServiceByType()
Returns whether the container has a service of the given type.
public
hasServiceByType(string $className) : bool
The name is composed dynamically (module plus component), so class_exists() runs first, and
a true result guarantees a valid type.
Parameters
- $className : string
Tags
Return values
boolinitializeAllContexts()
public
initializeAllContexts() : void
injectDeviceDetector()
public
injectDeviceDetector(DeviceDetector $detector) : void
Parameters
- $detector : DeviceDetector
onCreate()
public
onCreate() : void
render()
public
render([string $style = 'widget' ]) : void
Parameters
- $style : string = 'widget'
setAppContext()
public
setAppContext(AppContext $appContext) : $this
Parameters
- $appContext : AppContext
Return values
$thissetComponentParameter()
Sets a component parameter.
public
setComponentParameter(string $name, mixed $value) : void
Parameters
- $name : string
- $value : mixed
setCurrencyContext()
public
setCurrencyContext(CurrencyContext|null $currencyContext) : $this
Parameters
- $currencyContext : CurrencyContext|null
Return values
$thissetLanguageContext()
public
setLanguageContext(LanguageContext|null $languageContext) : $this
Parameters
- $languageContext : LanguageContext|null
Return values
$thissetLocalizationContext()
public
setLocalizationContext(LocalizationContext|null $localizationContext) : $this
Parameters
- $localizationContext : LocalizationContext|null
Return values
$thissetSettingContext()
public
setSettingContext(SettingContext $settingContext) : $this
Parameters
- $settingContext : SettingContext
Return values
$thissetThemeContext()
public
setThemeContext(ThemeContext|null $themeContext) : $this
Parameters
- $themeContext : ThemeContext|null
Return values
$thissetup()
public
setup(BasePresenter|BasePresenter $presenter) : void
Parameters
- $presenter : BasePresenter|BasePresenter
setupAppContext()
public
setupAppContext(AppContext $appContext) : void
Parameters
- $appContext : AppContext
typedComponent()
Returns a subcomponent with a verified type.
public
typedComponent(string $name, T> $type) : T
Use it instead of an inline @var above $this['x'] (which does not narrow the type) and
instead of the generic IComponent that $this['x'] returns. See
Form::typedComponent().
Parameters
- $name : string
- $type : T>
Tags
Return values
TfrontPresenter()
Returns the front presenter the component is attached to (null outside the front end or when detached).
protected
frontPresenter() : BasePresenter|null
Return values
BasePresenter|nullgetTranslator()
protected
getTranslator() : ITranslator
Return values
ITranslatorsetTemplateFile()
protected
setTemplateFile(string $dir, string $filename) : void
Parameters
- $dir : string
- $filename : string
setTranslator()
protected
setTranslator(ITranslator $translator) : self
Parameters
- $translator : ITranslator
Return values
selfallowsOutOfStockOrder()
Returns whether goods that are not in stock may be ordered (`order.outOfStock.allowed`); the same gate as in the catalog ({@see \App\UI\Front\Eshop\Presenters\Traits\Inits\CatalogOnlyGuardTrait::allowsOutOfStockOrder()}).
private
allowsOutOfStockOrder() : bool
A missing key means disabled.
Return values
boolblockedSetIds()
Returns the set ids that block the continue-to-order button: rows the stock does not cover in the requested quantity (or that cannot be ordered at all) and sets without a price in the cart currency, which only the server preview knows (otherwise they would reach checkout and fail with a generic error). The server strict reservation on submit remains the last authority.
private
blockedSetIds(array<int, array{setId: int, quantity: int}> $lines) : array<int, int>
Parameters
- $lines : array<int, array{setId: int, quantity: int}>
Return values
array<int, int> —setIds of blocking rows
buildRows()
Merges session rows (setId and quantity) with preview data (name, price, uncovered stock) and catalog availability.
private
buildRows(array<int, array{setId: int, quantity: int}> $lines, array<string, mixed>|null $order) : array<int, array<string, mixed>>
A row unknown to the Api (a deleted set) is kept with an empty price, because the customer
must see it to be able to remove it. unitPriceDisplay and totalPriceDisplay carry the
display price: the order snapshot has both (price is the base, priceWithVat includes
VAT; identical for a non-payer) and vatNoteMode() picks the column. Cart summaries
do not follow it; they always show the amount actually paid (*WithVat).
Parameters
- $lines : array<int, array{setId: int, quantity: int}>
- $order : array<string, mixed>|null
Return values
array<int, array<string, mixed>>createMultiplierComponent()
Creates a multiplier for the component.
private
createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
- $name : string
Return values
Multiplier<string|int, IComponent>createNewComponentInstance()
Creates a new component instance without adding it to the presenter; used by the multiplier.
private
createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
- $baseName : string
- $uniqueKey : int|string|null = null
Return values
IComponent|nullcreateStandardComponent()
Creates a standard component (not a multiplier).
private
createStandardComponent(string $name) : IComponent|null
Parameters
- $name : string
Return values
IComponent|nullguardEnabled()
A disabled eshop (`catalog.only = 1`) has no cart or panel; the same gate as `addToCart!`.
private
guardEnabled() : void
hasUnavailableRow()
Returns whether anything in the cart blocks submitting the order.
private
hasUnavailableRow(array<int, array<string, mixed>> $rows) : bool
It is computed from the composed rows (buildRows()), not from the Api response: besides
goods without a stock card (notInStock) it covers plain sell-out, which the Api preview does
not know (the cart reserves nothing). Without it the customer would reach checkout and be
rejected only by the strict reservation, with no explanation.
Parameters
- $rows : array<int, array<string, mixed>>
Return values
boolint()
private
int(mixed $value) : int
Parameters
- $value : mixed
Return values
intisCatalogOnly()
private
isCatalogOnly() : bool
Return values
boolloadPreview()
Returns the Api preview, computed once per request and shared by `render()` and handlers (otherwise the same recalculation would run twice).
private
loadPreview() : array<string, mixed>
Return values
array<string, mixed>num()
private
num(mixed $value) : numeric-string
Parameters
- $value : mixed
Return values
numeric-stringopenDetail()
Keeps the panel open and redrawn after each change.
private
openDetail() : void
A disappearing row is feedback enough, so the mini cart sends no flash message (the full cart does, because the whole page is redrawn after the redirect).
prepareDetail()
Called only with the panel open; the only place where the widget touches the Api.
private
prepareDetail() : void
prepareWidget()
private
prepareWidget() : bool
Return values
bool —whether the eshop is enabled (catalog.only = 0); with false nothing is rendered
rowFees()
Returns informational row fees in the display price column (see `buildRows()`).
private
rowFees(array<string, mixed>|null $item, string $priceKey) : array<int, array{name: string, price: numeric-string}>
Parameters
- $item : array<string, mixed>|null
- $priceKey : string
Return values
array<int, array{name: string, price: numeric-string}>str()
DBAL/Api scalar (mixed) → string, guarded.
private
str(mixed $value) : string
Parameters
- $value : mixed
Return values
stringunpricedItems()
Returns sets the Api omitted from the preview because they have no price in the cart currency.
private
unpricedItems(array<string|int, mixed>|null $order) : array<int, string>
Parameters
- $order : array<string|int, mixed>|null
Return values
array<int, string> —setId mapped to the set name
vatNoteMode()
Returns the VAT note variant for cart templates: `null` means the order charges no VAT and VAT is not mentioned; `true` means prices are shown with VAT. The Api sends `showPricesWithVat` equal to `withVat` (the VAT engine treatment; the seller switch `show_prices_with_vat` is no longer read), so `false` does not occur today. A preview without an Api response gives `null`, because silence is safer than a false claim.
private
vatNoteMode(array<string, mixed>|null $order) : bool|null
Parameters
- $order : array<string, mixed>|null