CoolCMS API

ProductFilterBox extends ParameterForm
in package
uses LoadingTrait

Renders the parameter filter box.

Parameters are global (the eshop has no category_parameter_rel), but the filter is built only from parameters that actually occur in the current list (category intersected with eligibility), not from all global parameters; see LoadingTrait::loadParameters(). The AND facet (p[]) goes through AbstractParameterHandler::toFilters() with Parameter::getFilterMatchAll(), the same mechanism as Bazaar and Comcat.

Table of Contents

Properties

$categoryId  : int|null
$container  : Container
$onError  : array<string|int, callable(Form, static): void>
Signature: function(Form $form, self $component): void
$onSuccess  : array<string|int, callable(Form, ArrayHash, static): void>
$onValidate  : array<string|int, callable(Form, ArrayHash, static): void>
Events for the consumer (presenter / parent control). `ParameterForm` only renders and validates; business logic (save, email, redirect) belongs to whoever instantiates the component.
$routerDispatcher  : RouterDispatcher
$translator  : ITranslator
$appContext  : AppContext
$componentParameters  : array<string, mixed>
$context  : ParameterFormContext
$currencyContext  : CurrencyContext|null
$deviceDetector  : DeviceDetector|null
$itemsByGroups  : array<int, array<int, ParameterFormItem>>
$languageContext  : LanguageContext|null
$localizationContext  : LocalizationContext|null
$parameterAndOptionList  : array<int, ParameterInterface>
$parameterGroupList  : array<int, ParameterGroupInterface>
$parameterItems  : array<int, ParameterFormItem>
$registry  : ParameterHandlerRegistry
$settingContext  : SettingContext
$themeContext  : ThemeContext|null
$translatorDomain  : string|null
Translation domain is set by the module subclass (`AdvertForm`, `AdvertFilterBox`, ...).
$countsCache  : array<string, array<int, array<string|int, int>>>
$fieldBuilder  : ParameterFieldBuilder|null
$parameterGroupManager  : ParameterGroupManager
$parameterManager  : ParameterManager
$parametersInitialized  : bool
$productCategoryManager  : ProductCategoryManager
$productSetManager  : ProductSetManager
$subtreeProductIdsCache  : array<int, int>|null

Methods

__call()  : mixed
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
__construct()  : mixed
createComponent()  : IComponent|null
getActiveFilters()  : array<int, array{parameterId: int, parameter: string, label: string, remove: array|null}>
Returns active filters for the badges above the list (`.pactive`), one entry per cancelable value, so "Sony" and "Canon" are two badges, not one.
getAppContext()  : AppContext
getComponentParameter()  : mixed
Returns a component parameter, or null when it is not set.
getContainer()  : Container
getCurrencyContext()  : CurrencyContext|null
getGroupChosenCount()  : int
Returns how many options of a group are selected, shown as a badge on the collapsible heading (`.filter-box__chosen`) so a collapsed group still shows that it filters.
getLanguageContext()  : LanguageContext|null
getLocalizationContext()  : LocalizationContext|null
getRouterDispatcher()  : RouterDispatcher
getSettingContext()  : SettingContext
getSettings()  : array<int, array<string, mixed>>
getThemeContext()  : ThemeContext|null
getUploaderControlMap()  : array<string, string>
Map of form control name to uploader child name. Latte looks it up while iterating `$group->getControls()`; when an entry exists for an input, it renders the dropzone plus the classic input with a toggle.
getUploaderParameterIds()  : array<string|int, int>
Ids of parameters that have a dropzone uploader. A child may override it for different behavior (for example no uploaders: an empty array).
hasServiceByType()  : bool
Returns whether the container has a service of the given type.
initializeAllContexts()  : void
injectDeviceDetector()  : void
onCreate()  : void
render()  : void
renderActiveFilters()  : void
Renders badges of active filters above the list, not inside the filter: otherwise canceling a filter would be reachable only by scrolling back up.
renderJs()  : 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.
uploaderName()  : string
Name of the child uploader component for an upload parameter.
beforeRender()  : void
Hook: a child component may add its own template variables (for example the edited entity).
beforeSubmitButton()  : void
Hook: a child component may add its own fields before submit (recaptcha, password input, agreement checkbox and similar).
buildContext()  : void
buildRegistry()  : ParameterHandlerRegistry
Default registry covering all `ParameterType` constants. A child component may override it to add its own handlers (for example module-specific types).
createComponentForm()  : Form
extractParameterValues()  : array<int, array<int, array{value: mixed, value2?: ?string}>>
Helper that extracts form values. Returns only persistable parameters, i.e. not file/image types.
findParameterByKey()  : ParameterInterface|null
frontPresenter()  : BasePresenter|null
Returns the front presenter the component is attached to (null outside the front end or when detached).
getCurrentCategory()  : ProductCategory|null
getEntityValues()  : array<int, mixed>
Hook: map of entity values for prefill (parameterId => value | value[]).
getFieldBuilder()  : ParameterFieldBuilder
Lazy shared builder of parameter fields, initialized from the resolved engine state (items/groups/context/mode). Entity values are read at the first build (after `setAdvert()`/`setCategoryList()`), as with {@see \App\Core\Form\Parameters\Building\DefaultsTrait::applyDefaults()}.
getMode()  : string
Hook: mode that selects `getType` or `getSearchType` on a parameter.
getParameterTranslation()  : ParameterTextInterface|null
getSubmitLabel()  : string
getTranslator()  : ITranslator
hasResolvedType()  : bool
For a child component: tells whether the form contains a parameter of the given type (respecting the mode via `resolveType()`).
initParameters()  : void
isUploadParameter()  : bool
A classic `IMAGE` / `FILE` parameter has its own `<input type="file">` (via the handler); the dropzone uploader handles only the multi-upload `*_UPLOADER` variants.
loadParameterGroups()  : array<string|int, mixed>
loadParameters()  : array<string|int, ParameterFormItem>
parameterKey()  : string
Form control key of a parameter (`parameter_<id>`). Field building is done by the shared {@see \App\Core\Form\Parameters\ParameterFieldBuilder}, but the engine and its consumers (filter URL params, email/region denormalization) need the same key to look up submitted values.
processSubmit()  : void
resolveDefaultValue()  : string|null
resolveType()  : int|null
setTemplateFile()  : void
setTranslator()  : self
usesDefaultParameters()  : bool
Hook: when a child component returns true, only parameters with `getDefault()` = true (classic) or `getSearchDefault()` = true (search) are shown.
applyUrlDefaults()  : void
buildParameterAndOptionList()  : void
Returns ids of the parameters that this parameterId uses (directly or through options), for lookup from rules. Options have no per-category override, so they are read straight from the Parameter entity.
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).
fetchCounts()  : array<int, array<string|int, int>>
Returns value counts for the list narrowed by the given filters.
indexById()  : array<int, T>
indexItemsByGroups()  : void
indexItemsById()  : array<int, ParameterFormItem>
resolveActiveParameterFilters()  : array<int, array<int, object>>
Returns active filters from the URL, grouped by parameter.
resolveOptionCounts()  : array<int, array<string|int, int>>
Returns product counts per option, narrowed by active filters.
resolveRangeBounds()  : array<int, array{min: float, max: float}>
Returns slider bounds for range parameters, taken from the already loaded facet counts, so it costs no extra query.
resolveSubtreeProductIds()  : array<int, int>
Returns product ids in the category subtree, memoized because `ProductSetListTrait` and the filter box ask for the same data, which would otherwise be two raw queries per request.

Properties

$onError

Signature: function(Form $form, self $component): void

public array<string|int, callable(Form, static): void> $onError = []

$onSuccess

public array<string|int, callable(Form, ArrayHash, static): void> $onSuccess = []

$onValidate

Events for the consumer (presenter / parent control). `ParameterForm` only renders and validates; business logic (save, email, redirect) belongs to whoever instantiates the component.

public array<string|int, callable(Form, ArrayHash, static): void> $onValidate = []

Signature: function(Form $form, ArrayHash $values, self $component): void

$componentParameters

protected array<string, mixed> $componentParameters = []

component parameters set by setComponentParameter()

$parameterAndOptionList

protected array<int, ParameterInterface> $parameterAndOptionList = []

parameters together with their options (for lookup from rules)

$parameterItems

protected array<int, ParameterFormItem> $parameterItems = []

indexed by parameterId, with values resolved per form (order/required/groupId)

$translatorDomain

Translation domain is set by the module subclass (`AdvertForm`, `AdvertFilterBox`, ...).

protected string|null $translatorDomain = 'front.eshop.components.productFilterBox'

$countsCache

private array<string, array<int, array<string|int, int>>> $countsCache = []

counts memoized by filter signature

$parametersInitialized

private bool $parametersInitialized = false

$subtreeProductIdsCache

private array<int, int>|null $subtreeProductIdsCache = null

memoized category subtree product ids

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>

createComponent()

public createComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

getActiveFilters()

Returns active filters for the badges above the list (`.pactive`), one entry per cancelable value, so "Sony" and "Canon" are two badges, not one.

public getActiveFilters() : array<int, array{parameterId: int, parameter: string, label: string, remove: array|null}>

Read from request parameters (p[<parameterId>]) and from already loaded parameter entities (optionsCollection is in the filter includes), so it costs no extra query.

remove is the p value without that one option; the template turns it into a link via {plink}. When nothing remains after removal it is null and the link leads to the list without a filter.

Return values
array<int, array{parameterId: int, parameter: string, label: string, remove: array|null}>

getComponentParameter()

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
Container

getGroupChosenCount()

Returns how many options of a group are selected, shown as a badge on the collapsible heading (`.filter-box__chosen`) so a collapsed group still shows that it filters.

public getGroupChosenCount(ControlGroup $group) : int

Counted from the form values, i.e. request parameters, so it costs no extra query. A multi-value field (CheckboxList/MultiSelect) counts per item, a single-value one as 1. Buttons and hidden fields are skipped: they are not user choices.

Lives on the shared base because Style_Filter.latte serves the e-shop, advert and company catalog filters, so every child gets it at once.

Parameters
$group : ControlGroup
Return values
int

getSettings()

public getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>

getUploaderControlMap()

Map of form control name to uploader child name. Latte looks it up while iterating `$group->getControls()`; when an entry exists for an input, it renders the dropzone plus the classic input with a toggle.

public getUploaderControlMap() : array<string, string>

Assumes the child creates a child component named uploaderName() for each uploader parameter (typically via a createComponent factory). Components without uploader children override getUploaderParameterIds() to return [].

Return values
array<string, string>

getUploaderParameterIds()

Ids of parameters that have a dropzone uploader. A child may override it for different behavior (for example no uploaders: an empty array).

public getUploaderParameterIds() : array<string|int, int>
Return values
array<string|int, 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
phpstan-assert-if-true

class-string $className

Return values
bool

render()

public render([string $style = 'Style_1' ]) : void
Parameters
$style : string = 'Style_1'

renderActiveFilters()

Renders badges of active filters above the list, not inside the filter: otherwise canceling a filter would be reachable only by scrolling back up.

public renderActiveFilters() : void

Called from the list template as {control filterBox:activeFilters}. Renders nothing at all (not even an empty wrapper) when no filter is active.

setComponentParameter()

Sets a component parameter.

public setComponentParameter(string $name, mixed $value) : void
Parameters
$name : string
$value : mixed

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
template
Return values
T

uploaderName()

Name of the child uploader component for an upload parameter.

public uploaderName(ParameterInterface $parameter) : string

In Latte: {control "uploader_$parameterId"}.

Parameters
$parameter : ParameterInterface
Return values
string

beforeRender()

Hook: a child component may add its own template variables (for example the edited entity).

protected beforeRender(string $style) : void
Parameters
$style : string

beforeSubmitButton()

Hook: a child component may add its own fields before submit (recaptcha, password input, agreement checkbox and similar).

protected beforeSubmitButton(Form $form) : void
Parameters
$form : Form

extractParameterValues()

Helper that extracts form values. Returns only persistable parameters, i.e. not file/image types.

protected extractParameterValues(ArrayHash $values) : array<int, array<int, array{value: mixed, value2?: ?string}>>

The key is parameterId, the value a list of rows to persist; the handler decides (scalar: 1 row, multiselect: N rows, range: 1 row with value+value2).

Parameters
$values : ArrayHash
Return values
array<int, array<int, array{value: mixed, value2?: ?string}>>

frontPresenter()

Returns the front presenter the component is attached to (null outside the front end or when detached).

protected frontPresenter() : BasePresenter|null
Return values
BasePresenter|null

getEntityValues()

Hook: map of entity values for prefill (parameterId => value | value[]).

protected getEntityValues() : array<int, mixed>

Empty by default; a component without an entity (new record) has nothing to prefill.

Return values
array<int, mixed>

getFieldBuilder()

Lazy shared builder of parameter fields, initialized from the resolved engine state (items/groups/context/mode). Entity values are read at the first build (after `setAdvert()`/`setCategoryList()`), as with {@see \App\Core\Form\Parameters\Building\DefaultsTrait::applyDefaults()}.

protected getFieldBuilder() : ParameterFieldBuilder
Return values
ParameterFieldBuilder

getMode()

Hook: mode that selects `getType` or `getSearchType` on a parameter.

protected getMode() : string

Form by default (advert/insert); search forms return MODE_SEARCH.

Return values
string

getSubmitLabel()

protected getSubmitLabel() : string
Return values
string

getTranslator()

protected getTranslator() : ITranslator
Return values
ITranslator

hasResolvedType()

For a child component: tells whether the form contains a parameter of the given type (respecting the mode via `resolveType()`).

protected hasResolvedType(int $type) : bool
Parameters
$type : int
Return values
bool

initParameters()

protected initParameters() : void

isUploadParameter()

A classic `IMAGE` / `FILE` parameter has its own `<input type="file">` (via the handler); the dropzone uploader handles only the multi-upload `*_UPLOADER` variants.

protected isUploadParameter(ParameterInterface $parameter) : bool
Parameters
$parameter : ParameterInterface
Return values
bool

loadParameterGroups()

protected loadParameterGroups() : array<string|int, mixed>
Return values
array<string|int, mixed>

parameterKey()

Form control key of a parameter (`parameter_<id>`). Field building is done by the shared {@see \App\Core\Form\Parameters\ParameterFieldBuilder}, but the engine and its consumers (filter URL params, email/region denormalization) need the same key to look up submitted values.

protected parameterKey(ParameterInterface $parameter) : string
Parameters
$parameter : ParameterInterface
Return values
string

processSubmit()

protected processSubmit(Form $_form, ArrayHash $values) : void
Parameters
$_form : Form
$values : ArrayHash

setTemplateFile()

protected setTemplateFile(string $dir, string $filename) : void
Parameters
$dir : string
$filename : string

setTranslator()

protected setTranslator(ITranslator $translator) : self
Parameters
$translator : ITranslator
Return values
self

usesDefaultParameters()

Hook: when a child component returns true, only parameters with `getDefault()` = true (classic) or `getSearchDefault()` = true (search) are shown.

protected usesDefaultParameters() : bool
Return values
bool

buildParameterAndOptionList()

Returns ids of the parameters that this parameterId uses (directly or through options), for lookup from rules. Options have no per-category override, so they are read straight from the Parameter entity.

private buildParameterAndOptionList() : void

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|null

createStandardComponent()

Creates a standard component (not a multiplier).

private createStandardComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

fetchCounts()

Returns value counts for the list narrowed by the given filters.

private fetchCounts(ProductCategory|null $category, array<int, object> $extraFilters) : array<int, array<string|int, int>>

Filters are composed here (eligibility, category, passed facets) and sent to the Api as they are; ProductSetManager::fetchParameterValueCounts() resolves the ids of visible sets itself, because bare scalar ids would not pass the hydrator through the bridge.

Parameters
$category : ProductCategory|null
$extraFilters : array<int, object>
Return values
array<int, array<string|int, int>>

indexById()

private indexById(array<string|int, T> $items) : array<int, T>
Parameters
$items : array<string|int, T>
Tags
template
Return values
array<int, T>

indexItemsByGroups()

private indexItemsByGroups() : void

resolveActiveParameterFilters()

Returns active filters from the URL, grouped by parameter.

private resolveActiveParameterFilters() : array<int, array<int, object>>

They are built by the same handlers as the list (ParameterTrait), not by an own copy of the rules; otherwise the counts and the list could drift apart, silently.

Return values
array<int, array<int, object>>

resolveOptionCounts()

Returns product counts per option, narrowed by active filters.

private resolveOptionCounts() : array<int, array<string|int, int>>

IMPORTANT: for a facet P all active filters except the filters of P are applied. If P's own filter applied too, a single-value parameter (brand, diagonal) would show zero everywhere, because the ticked value and any other value cannot meet on one product; filter_match_all has the same trap. For other parameters all filters apply, so ticking a port option reduces processor counts to those that really have that port.

The number of queries is the number of active facets plus one, not one per option.

Return values
array<int, array<string|int, int>> —

parameterId => [value => count]

resolveRangeBounds()

Returns slider bounds for range parameters, taken from the already loaded facet counts, so it costs no extra query.

private resolveRangeBounds(array<int, array<string|int, int>> $counts) : array<int, array{min: float, max: float}>

NOTE: the upper bound is the largest value column value, i.e. the largest lower bound of a stored range (facets carry no value2). That is enough for a slider, which is a guide and not validation; the filter itself works with exact values. A module that needs an exact upper bound fills $context->rangeBounds its own way.

Parameters without numeric values are skipped, so the fields stay two plain numbers.

Parameters
$counts : array<int, array<string|int, int>>
Return values
array<int, array{min: float, max: float}>

resolveSubtreeProductIds()

Returns product ids in the category subtree, memoized because `ProductSetListTrait` and the filter box ask for the same data, which would otherwise be two raw queries per request.

private resolveSubtreeProductIds(ProductCategory $category) : array<int, int>
Parameters
$category : ProductCategory
Return values
array<int, int>
On this page

Search results