ProductSetDetailTrait uses trait:short, trait:short, trait:short
Product set detail: gallery, price/VAT (batch, never from the entity), parameters (`ParameterDisplayBuilder`), fees/links/accessories, bundle composition (`setItems`), availability and `deliveryDays` ({@see \App\UI\Api\Eshop\Models\Managers\ProductSetManager::getAvailabilities()}), `{control rating:review}` and `{control frontBaseCommentThread}` (same pattern as Blog `ArticleDetailTrait`).
IMPORTANT: the vacation banner is the global component frontStoreVacationBanner in the
e-shop header (parts/eshop/header/default.latte); do not add it back here.
IMPORTANT: 404 guard. A deleted, inactive or out-of-publish-window set (and its owning
product for type=1) ends with $this->error(), never a 500. The front end must filter
deleted=0.
Table of Contents
Constants
- DETAIL_INCLUDES : mixed = [ 'translations', 'product.translations', 'prod...
Properties
- $checkoutManager : CheckoutManager
- Customer orders; the detail reads only one thing from them: who bought this set ("verified purchase" on reviews and the right to write a review).
- $socialsShareFactory : SocialsShareFactory
- Detail sharing to social networks; the same component as the advert detail.
- $productSet : ProductSet|null
- $variants : array<int, ProductSet>
- Variants = other sets of the same product (`product_id`), including the displayed one.
- $visibleAccessories : array<int, object>
- $visibleSetItems : array<int, object>
Methods
- actionDetail() : void
- createComponentRating() : Rating
- createComponentSocialsShare() : SocialsShare
- getProductSet() : ProductSet|null
- Returns the loaded detail set; read by the breadcrumb component ({@see \App\UI\Front\Eshop\Components\BreadcrumbComponent\Breadcrumb}), like `getCurrentCategory()` on the list. It is `null` before `actionDetail()`.
- renderDetail() : void
- decorateWithPriceAndAvailability() : void
- loadVariants() : array<int, ProductSet>
- Returns the other sets of the same product = variants switchable in the buy box.
- prepareCanonicalUrl() : void
- prepareMetaDataForDetail() : void
- resolveFeeCurrentPrices() : array<int, string>
- Returns the currently valid price of each fee of the set, for display.
Constants
DETAIL_INCLUDES
private
mixed
DETAIL_INCLUDES
= [
'translations',
'product.translations',
'product.categories.translations',
'productState',
'asset',
'assetRels.asset.translations',
'setItems.childSet.translations',
'accessories.accessorySet.translations',
'accessories.accessorySet.asset',
// The accessory card is the same as in the list (`Items/_item.latte`) and renders tags and
// state; without these includes they would be lazy-loaded per card (N+1).
'accessories.accessorySet.productState.translations',
'accessories.accessorySet.tags.translations',
'tags.translations',
'fees.translations',
// The fee is priced with the same rate as the set ({@see resolveFeeCurrentPrices()}), so
// the `fees.prices.vat` include is not needed.
'fees.prices',
'fees.feeType.translations',
'links.translations',
'links.linkType.translations',
'parameterRels.parameter.translations',
// Options = child parameters. `AbstractParameterHandler::resolveOptionLabel()` looks up
// the chosen option by the stored id there; without this include the collection is empty,
// the resolve returns null and the parameter table shows the bare id instead of the label.
'parameterRels.parameter.optionsCollection.translations',
'commentThread',
'ratingThread',
]
Properties
$checkoutManager
Customer orders; the detail reads only one thing from them: who bought this set ("verified purchase" on reviews and the right to write a review).
public
CheckoutManager
$checkoutManager
Attributes
- #[Inject]
$socialsShareFactory
Detail sharing to social networks; the same component as the advert detail.
public
SocialsShareFactory
$socialsShareFactory
Attributes
- #[Inject]
$productSet
private
ProductSet|null
$productSet
= null
$variants
Variants = other sets of the same product (`product_id`), including the displayed one.
private
array<int, ProductSet>
$variants
= []
Empty array when the product has no other set (the switcher is then not rendered).
$visibleAccessories
private
array<int, object>
$visibleAccessories
= []
accessories that pass eligibility (see actionDetail())
$visibleSetItems
private
array<int, object>
$visibleSetItems
= []
bundle items that pass eligibility (see actionDetail())
Methods
actionDetail()
public
actionDetail(int|string|null $slug, int|string|null $name, int $id) : void
Parameters
- $slug : int|string|null
- $name : int|string|null
- $id : int
createComponentRating()
public
createComponentRating() : Rating
Return values
RatingcreateComponentSocialsShare()
public
createComponentSocialsShare() : SocialsShare
Return values
SocialsSharegetProductSet()
Returns the loaded detail set; read by the breadcrumb component ({@see \App\UI\Front\Eshop\Components\BreadcrumbComponent\Breadcrumb}), like `getCurrentCategory()` on the list. It is `null` before `actionDetail()`.
public
getProductSet() : ProductSet|null
Return values
ProductSet|nullrenderDetail()
public
renderDetail(int|string|null $slug, int|string|null $name, int $id) : void
Parameters
- $slug : int|string|null
- $name : int|string|null
- $id : int
decorateWithPriceAndAvailability()
private
decorateWithPriceAndAvailability(array<string|int, ProductSet> $items) : void
Parameters
- $items : array<string|int, ProductSet>
loadVariants()
Returns the other sets of the same product = variants switchable in the buy box.
private
loadVariants(ProductSet $set) : array<int, ProductSet>
The filters are the same as for the list (ProductSetEligibilityFilters::build());
without them the switcher would offer a deleted or unpublished set that gives 404 on the
detail (same reason as for the set composition and accessories in renderDetail()).
A bundle (typeId = 2) has no variants: it groups different products, not sizes of one.
A set with a NULL product FK (migrated cards) has none either: without a product there
is nothing to look siblings up by.
Parameters
- $set : ProductSet
Return values
array<int, ProductSet>prepareCanonicalUrl()
private
prepareCanonicalUrl([array<string, mixed> $resetParams = [] ]) : void
Parameters
- $resetParams : array<string, mixed> = []
prepareMetaDataForDetail()
private
prepareMetaDataForDetail(ProductSet|null $set, int|null $languageId) : void
Parameters
- $set : ProductSet|null
- $languageId : int|null
resolveFeeCurrentPrices()
Returns the currently valid price of each fee of the set, for display.
private
resolveFeeCurrentPrices(ProductSet $set) : array<int, string>
The series is append-only and resolved per fee (unlike the ProductSet price there is no
batch resolver; a set has only a handful of fees, so no N+1 risk). The fee is
informative: the rate is the same as for the set ($set->getCurrentPriceVatPercents()),
not from the fee's own price row (fee_prices.cms_system_vats_vat_id / Vat entity).
VAT is added only when the set charges it ($set->isCurrentPriceChargeVat()); both the
rate and chargeVat are filled earlier in actionDetail()
(BatchDecorationTrait::decorateWithPriceAndAvailability()).
Parameters
- $set : ProductSet
Return values
array<int, string> —feeId => display price (numeric string)