CoolCMS API

InitTrait

Table of Contents

Constants

LIST_INCLUDES  : mixed = ['translations', 'productState', 'tags.translat...
List includes; keep identical to `ProductSetListTrait::LIST_INCLUDES`.
SETTINGS_MODULE_ESHOP  : int = 4
Settings module id of the eshop.

Methods

allowsOutOfStockOrder()  : bool
Returns whether selling out-of-stock goods is allowed (`order.outOfStock.allowed = 1`); the same gate as in the catalog ({@see \App\UI\Front\Eshop\Presenters\Traits\Inits\CatalogOnlyGuardTrait:: allowsOutOfStockOrder()}).
decorateWithPrices()  : void
Fills in the current price and availability of the products.
isCatalogOnly()  : bool
Disabled purchasing (`catalog.only = 1`); the same gate as in the cart widget.
loadNewest()  : array<int, ProductSet>
Loads the `$maxNumber` newest products and decorates them with prices; the common base of {@see self::prepareItems()} and {@see self::prepareDealItem()}.
prepareDealItem()  : void
Picks the deal of the week by the behavior flag on the tag ({@see \App\Core\Base\Shared\Eshop\Models\Entities\ProductTag::$saleFlag}), not by discount.
prepareItems()  : void

Constants

LIST_INCLUDES

List includes; keep identical to `ProductSetListTrait::LIST_INCLUDES`.

private mixed LIST_INCLUDES = ['translations', 'productState', 'tags.translations', 'asset', 'ratingThread']

The product card (Templates/ProductSet/Items/_item.latte) reads translation, state, tags and the preview image; without any of them part of the card content silently goes missing. ratingThread carries denormalized aggregates (ratingCount, ratingAvg), so it is one extra join; without the include the card would touch a lazy association and the list would turn into N+1.

SETTINGS_MODULE_ESHOP

Settings module id of the eshop.

private int SETTINGS_MODULE_ESHOP = 4

Methods

allowsOutOfStockOrder()

Returns whether selling out-of-stock goods is allowed (`order.outOfStock.allowed = 1`); 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; a silently allowed oversell would be the worst possible failure.

Return values
bool

decorateWithPrices()

Fills in the current price and availability of the products.

private decorateWithPrices(array<int, ProductSet> $items) : void

IMPORTANT: without this step the card prints no price. getCurrentPrice() is not an entity column; it is filled in batches from the price list views after the list is loaded, so findAll() alone returns products with an empty price and the card falls into the "price on request" branch. The eshop presenter does the same decoration (BatchDecorationTrait).

There are two batch calls for the whole list, not one query per product, otherwise the home page would suffer N+1.

IMPORTANT: the price list is the base without VAT; the entity stores only the display price (computed by withVat of each fetchCurrentPrices() row, PriceDisplayHelper), exactly as the presenter decoration does. A difference would make the promo page show different prices than the list.

Parameters
$items : array<int, ProductSet>

isCatalogOnly()

Disabled purchasing (`catalog.only = 1`); the same gate as in the cart widget.

private isCatalogOnly() : bool
Return values
bool

loadNewest()

Loads the `$maxNumber` newest products and decorates them with prices; the common base of {@see self::prepareItems()} and {@see self::prepareDealItem()}.

private loadNewest(int $maxNumber[, array<int, object> $extraFilters = [] ]) : array<int, ProductSet>

$extraFilters (prepareDealItem(): tags.saleFlag = 1, the tag grids: tags.newFlag / tags.recommendedFlag) are added to the eligibility filters as a DB filter, not PHP filtering after loading. An EqualFilter with a dotted path through a to-many association makes JoinHelper::resolveColumn() add a left join and phase 1 of the query (GetAllTrait::fetchIdentifiers()) runs with distinct, so a product with two sale tags is not returned twice and the limit applies exactly to the filtered data.

Parameters
$maxNumber : int
$extraFilters : array<int, object> = []
Return values
array<int, ProductSet>

prepareDealItem()

Picks the deal of the week by the behavior flag on the tag ({@see \App\Core\Base\Shared\Eshop\Models\Entities\ProductTag::$saleFlag}), not by discount.

private prepareDealItem(int $lookback) : void

Priority (see LastProductList::renderDeal()):

  1. Among products with at least one sale_flag = 1 tag (DB filter through the to-many tags.saleFlag, see loadNewest()) the first one with a scheduled future price, i.e. a running sale with a known end (a countdown makes sense).
  2. Otherwise the first sale-tagged product (the sale runs, its end is unknown, no countdown).
  3. Without any sale-tagged product nothing: items = [] and the template hides the section (Deal.latte, {if $items}). A discount (original > price) is not a selection condition; a discounted product shows it on its card but that does not decide the section.

dealEndsAt is the future price time of the selected item; only priority 1 has one.

Parameters
$lookback : int

prepareItems()

private prepareItems(int $maxNumber, array<int, object> $extraFilters) : void
Parameters
$maxNumber : int
$extraFilters : array<int, object>

selection by a tag flag (tags.newFlag, tags.recommendedFlag), see loadNewest()

On this page

Search results