CoolCMS API

ProductSetListTrait uses trait:short, trait:short, trait:short, trait:short

Category list: category tree (sidebar component), pagination by `4/product.perPage`, sorting by the denormalized `price` column or by name, fulltext search and the `p[]` parameter facet.

The displayed price always goes through BatchDecorationTrait; the denormalized column is only a sort key.

Table of Contents

Constants

LIST_INCLUDES  : mixed = ['translations', 'productState', 'tags.translat...
`ratingThread`: the rating on the product card. The thread carries denormalized aggregates (`ratingCount`, `ratingAvg`), so it is one extra join, not a product query; without the include the card would touch a lazy association and the list would get N+1.

Methods

actionList()  : void
paginationInit()  : Paginator|null
renderList()  : void
requirePagination()  : Paginator
Works like `paginationInit()`, but the paginator is required; a missing component is a wiring error.
decorateWithPriceAndAvailability()  : void
extractBaseParameterIds()  : array<string|int, int>
Extracts the unique base parameterId values from URL keys (strips the `_from` / `_to` suffixes).
prepareCanonicalUrl()  : void
prepareFilters()  : array<int, Filter>
prepareOrderBy()  : array<string, bool>
prepareParameterFilter()  : void
preparePerPage()  : int
prepareSearchFilter()  : Filter
Applies the fulltext through Elasticsearch (id -> `SearchIdFilter`); visibility, pagination and publish window stay in DB phase 1 (`ProductSetEligibilityFilters` are always applied). With ES off, an outage (circuit breaker) or a short query it falls back transparently to MySQL `MATCH_AGAINST`, with identical behavior to the original. Same as Blog `ArticleListTrait` / Bazaar `ParameterTrait`.
prepareSearchFilters()  : array<int, Filter>
Builds the filters for the search endpoint = everything except fulltext (handled on the Api side): `ProductSetEligibilityFilters`, category and parameter filters.
searchViaApi()  : ProductSet>, 1: int, 2: bool, 3: array>}|null
Searches through the Api endpoint `api/eshop/product-set/search`. Three states (only the search path is handled for the e-shop; facets stay unchanged):

Constants

LIST_INCLUDES

`ratingThread`: the rating on the product card. The thread carries denormalized aggregates (`ratingCount`, `ratingAvg`), so it is one extra join, not a product query; without the include the card would touch a lazy association and the list would get N+1.

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

Methods

actionList()

public actionList([int $page = 1 ][, string|int|null $category = null ][, string|null $search = null ][, int $order = 0 ]) : void
Parameters
$page : int = 1
$category : string|int|null = null
$search : string|null = null
$order : int = 0

renderList()

public renderList([int $page = 1 ][, string|int|null $category = null ][, string|null $search = null ][, int $order = 0 ]) : void
Parameters
$page : int = 1
$category : string|int|null = null
$search : string|null = null
$order : int = 0

requirePagination()

Works like `paginationInit()`, but the paginator is required; a missing component is a wiring error.

public requirePagination(int $perPage) : Paginator
Parameters
$perPage : int
Return values
Paginator

extractBaseParameterIds()

Extracts the unique base parameterId values from URL keys (strips the `_from` / `_to` suffixes).

private extractBaseParameterIds(array<string|int, mixed> $urlParams) : array<string|int, int>
Parameters
$urlParams : array<string|int, mixed>
Return values
array<string|int, int>

prepareCanonicalUrl()

private prepareCanonicalUrl([array<string, mixed> $resetParams = [] ]) : void
Parameters
$resetParams : array<string, mixed> = []

prepareOrderBy()

private prepareOrderBy() : array<string, bool>
Return values
array<string, bool>

prepareParameterFilter()

private prepareParameterFilter(array<int, Filter> &$filters) : void
Parameters
$filters : array<int, Filter>

preparePerPage()

private preparePerPage(int $count[, int $defaultCount = 20 ]) : int
Parameters
$count : int
$defaultCount : int = 20
Return values
int

prepareSearchFilter()

Applies the fulltext through Elasticsearch (id -> `SearchIdFilter`); visibility, pagination and publish window stay in DB phase 1 (`ProductSetEligibilityFilters` are always applied). With ES off, an outage (circuit breaker) or a short query it falls back transparently to MySQL `MATCH_AGAINST`, with identical behavior to the original. Same as Blog `ArticleListTrait` / Bazaar `ParameterTrait`.

private prepareSearchFilter(string $search) : Filter
Parameters
$search : string
Return values
Filter

prepareSearchFilters()

Builds the filters for the search endpoint = everything except fulltext (handled on the Api side): `ProductSetEligibilityFilters`, category and parameter filters.

private prepareSearchFilters() : array<int, Filter>
Return values
array<int, Filter>

searchViaApi()

Searches through the Api endpoint `api/eshop/product-set/search`. Three states (only the search path is handled for the e-shop; facets stay unchanged):

private searchViaApi(string $search, bool $orderChosen, Paginator|null $paginator) : ProductSet>, 1: int, 2: bool, 3: array>}|null

(a) search without a manual sort choice: orderBys = null, ES sorts and paginates by score (fromEs: true); eligibility is still held by the DB, (b) search with a manual choice (o-N): orderBys from prepareOrderBy(), the DB sorts, paginates and counts over the ES id set, so the price still sorts exactly, (c) without search this path is not taken at all and nothing changes.

Sorting by price (o-2 / o-3) is essential for the e-shop and stays fully working; it is state (b), where relevance yields to DB sorting.

null means use the plain DB path (DENY, bridge outage or ES unavailable).

Parameters
$search : string
$orderChosen : bool
$paginator : Paginator|null
Return values
ProductSet>, 1: int, 2: bool, 3: array>}|null
On this page

Search results