CoolCMS API

PickerTrait

Pickers of the product set edit form.

  • productPicker(): top-level field of the owning Product (categories stay on the product; the picker only chooses which product the set sells).
  • productSetVariantPicker(): top-level variantId, the sold variant of a set with type = PRODUCT.
  • productSetItemPicker(): setItems row, a set composition item that is another set (nested sets allowed).
  • productTagPicker(), productSetFeePicker(), productSetLinkPicker(): tags, fees, links rows (many-to-many).
  • productSetAccessoryPicker(): accessories row (set to set, excludes the edited set).

IMPORTANT: displayField is required in every multiplier picker; without it the label is lost on the AJAX redraw of a row.

The label helpers (productLabel(), productSetLabel(), productTagLabel(), productSetFeeLabel(), productSetLinkLabel()) take an already loaded entity. The picker callbacks and the form trait (row prefill on edit) both call them, so their names and signatures are a stable contract.

$this->getLanguageContext() is used nullsafe (?->getLang()): on a component the context is nullable.

Requires $this->productManager, $this->productVariantManager, $this->productSetManager, $this->productTagManager, $this->productSetFeeManager and $this->productSetLinkManager (constructor injection on the host).

Table of Contents

Methods

productPicker()  : PickerConfig
Picker of the owning `Product`: a single top-level field outside the multiplier, so no `targetContainer` or `displayField`.
productSetAccessoryPicker()  : PickerConfig
Picker of an accessory in the `accessories` multiplier row (many-to-many `ProductSet` to `ProductSet`).
productSetFeePicker()  : PickerConfig
Picker of a fee in the `fees` multiplier row (many-to-many `ProductSet` to `ProductSetFee`).
productSetItemPicker()  : PickerConfig
Picker of a set composition item: `setItems` row targeting another set (a ready bundle too, i.e. nested sets). Links to `:Admin:Eshop:ProductSet` so the item detail opens from the row.
productSetLinkPicker()  : PickerConfig
Picker of a link in the `links` multiplier row (many-to-many `ProductSet` to `ProductSetLink`).
productSetVariantPicker()  : PickerConfig
Picker of the sold variant: top-level `variantId` of a set with `type = PRODUCT`. The 1:1 relation is guarded by the Api guard and a unique index.
productTagPicker()  : PickerConfig
Picker of a tag in the `tags` multiplier row (many-to-many `ProductSet` to `ProductTag`).
createProductSetLink()  : array{id: int, label: string}|null
Creates a link from the typed URL and returns it to the picker for selection.
productLabel()  : string
Returns the product name in the current language (first non-empty as fallback).
productSetAncestorIds()  : array<int, int>
Returns the ancestors of a set in the composition tree, i.e. the sets that contain it directly or indirectly.
productSetFeeLabel()  : string
Returns the fee name in the current language (first non-empty as fallback).
productSetLabel()  : string
Returns `<code> — <name>` in the current language (falls back to whichever part is non-empty).
productSetLinkLabel()  : string
Returns the link label: its URL in the current language (first non-empty address as fallback).
productTagLabel()  : string
Returns the tag name in the current language (first non-empty as fallback).
productVariantLabelsOf()  : array<int, string>
Returns the labels of all variants of a product: `variantId => "<product name> (#<variant id>)"`.
resolveProductLabel()  : string|null
resolveProductSetAccessoryLabel()  : string|null
resolveProductSetFeeLabel()  : string|null
resolveProductSetLinkLabel()  : string|null
resolveProductTagLabel()  : string|null
resolveProductVariantLabel()  : string|null
suggestProducts()  : array<int, array{id: int, label: string}>
Suggests products by a `like` match on the product name.
suggestProductSetAccessories()  : array<int, array{id: int, label: string}>
Suggests sets by a `like` match on the set name, optionally without the edited set (a set cannot be its own accessory).
suggestProductSetFees()  : array<int, array{id: int, label: string}>
Suggests fees by a `like` match on the fee name.
suggestProductSetItems()  : array<int, array{id: int, label: string}>
Suggests composition items by a `like` match on the set name, excluding `$excludeIds`.
suggestProductSetLinks()  : array<int, array{id: int, label: string}>
Suggests links by a `like` match on the URL (`translations.value`) only, not on the name: names are often identical or missing, so only the address tells links apart.
suggestProductTags()  : array<int, array{id: int, label: string}>
Suggests tags by a `like` match on the tag name.
suggestProductVariants()  : array<int, array{id: int, label: string}>
Suggests variants by a `like` match on the owning product name (a variant has no text of its own).

Methods

productPicker()

Picker of the owning `Product`: a single top-level field outside the multiplier, so no `targetContainer` or `displayField`.

protected productPicker([string $formName = 'editForm' ][, string $targetField = 'productId' ]) : PickerConfig
Parameters
$formName : string = 'editForm'
$targetField : string = 'productId'
Return values
PickerConfig

productSetAccessoryPicker()

Picker of an accessory in the `accessories` multiplier row (many-to-many `ProductSet` to `ProductSet`).

protected productSetAccessoryPicker([string $container = 'accessories' ][, string $targetField = 'accessorySetId' ][, string $displayField = 'accessorySet' ][, string $formName = 'editForm' ][, int|null $excludeId = null ]) : PickerConfig

Self-reference: $excludeId (id of the edited set) is excluded from the suggest (NotEqualFilter) and from the modal (pickerExclude), same technique as ProductCategoryPickerTrait::productCategoryParentPicker().

Parameters
$container : string = 'accessories'
$targetField : string = 'accessorySetId'
$displayField : string = 'accessorySet'
$formName : string = 'editForm'
$excludeId : int|null = null

id of the edited ProductSet (self-reference)

Return values
PickerConfig

productSetFeePicker()

Picker of a fee in the `fees` multiplier row (many-to-many `ProductSet` to `ProductSetFee`).

protected productSetFeePicker([string $container = 'fees' ][, string $targetField = 'feeId' ][, string $displayField = 'fee' ][, string $formName = 'editForm' ]) : PickerConfig
Parameters
$container : string = 'fees'
$targetField : string = 'feeId'
$displayField : string = 'fee'
$formName : string = 'editForm'
Return values
PickerConfig

productSetItemPicker()

Picker of a set composition item: `setItems` row targeting another set (a ready bundle too, i.e. nested sets). Links to `:Admin:Eshop:ProductSet` so the item detail opens from the row.

protected productSetItemPicker([string $container = 'setItems' ][, string $targetField = 'childSetId' ][, string $displayField = 'childSet' ][, string $formName = 'editForm' ][, array<int, int> $excludeIds = [] ][, int|null $excludeId = null ]) : PickerConfig

IMPORTANT: the suggest list excludes the set itself and all its ancestors ($excludeIds, see productSetAncestorIds()), otherwise a cycle A contains B contains A could be offered. The modal grid can exclude only one id (pickerExclude), so only the set itself is excluded there; the authoritative backstop is the guard in the Api ProductSetManager, which rejects the save with a clear message.

Parameters
$container : string = 'setItems'
$targetField : string = 'childSetId'
$displayField : string = 'childSet'
$formName : string = 'editForm'
$excludeIds : array<int, int> = []

the set itself plus its ancestors (suggest)

$excludeId : int|null = null

id of the edited set (modal)

Return values
PickerConfig

productSetLinkPicker()

Picker of a link in the `links` multiplier row (many-to-many `ProductSet` to `ProductSetLink`).

protected productSetLinkPicker([string $container = 'links' ][, string $targetField = 'linkId' ][, string $displayField = 'link' ][, string $formName = 'editForm' ]) : PickerConfig
Parameters
$container : string = 'links'
$targetField : string = 'linkId'
$displayField : string = 'link'
$formName : string = 'editForm'
Return values
PickerConfig

productSetVariantPicker()

Picker of the sold variant: top-level `variantId` of a set with `type = PRODUCT`. The 1:1 relation is guarded by the Api guard and a unique index.

protected productSetVariantPicker([string $formName = 'editForm' ][, string $targetField = 'variantId' ]) : PickerConfig

Outside the multiplier, so no targetContainer or displayField.

NOTE: targetPresenter is null because ProductVariant has no admin grid (it lives only as a multiplier row on the product), so the picker is suggest-only.

Parameters
$formName : string = 'editForm'
$targetField : string = 'variantId'
Return values
PickerConfig

productTagPicker()

Picker of a tag in the `tags` multiplier row (many-to-many `ProductSet` to `ProductTag`).

protected productTagPicker([string $container = 'tags' ][, string $targetField = 'tagId' ][, string $displayField = 'tag' ][, string $formName = 'editForm' ]) : PickerConfig
Parameters
$container : string = 'tags'
$targetField : string = 'tagId'
$displayField : string = 'tag'
$formName : string = 'editForm'
Return values
PickerConfig

Creates a link from the typed URL and returns it to the picker for selection.

private createProductSetLink(string $text) : array{id: int, label: string}|null

IMPORTANT: an exact, case-insensitive match of the address is looked up first (via the existing suggest) and returned as is, so the picker cannot generate duplicates in the code list. The JS check is only a courtesy; this one is binding.

The address is written to all languages because ProductSetLinkText::$value is required and a link without an address would be unusable in the other languages. The name stays empty and can be filled in on the target presenter.

Parameters
$text : string
Return values
array{id: int, label: string}|null

productLabel()

Returns the product name in the current language (first non-empty as fallback).

private productLabel(Product $product) : string
Parameters
$product : Product
Return values
string

productSetAncestorIds()

Returns the ancestors of a set in the composition tree, i.e. the sets that contain it directly or indirectly.

private productSetAncestorIds(int $setId[, int $maxDepth = 10 ]) : array<int, int>

Walks level by level (one query per level) with a depth cap and a visited set, so the picker cannot loop even if a cycle gets into the data.

The Api has the same logic in SetCompositionService (authoritative guard on save); this is only UI prevention, because the admin must not use Api services.

Parameters
$setId : int
$maxDepth : int = 10
Return values
array<int, int>

productSetFeeLabel()

Returns the fee name in the current language (first non-empty as fallback).

private productSetFeeLabel(ProductSetFee $fee) : string
Parameters
$fee : ProductSetFee
Return values
string

productSetLabel()

Returns `<code> — <name>` in the current language (falls back to whichever part is non-empty).

private productSetLabel(ProductSet $set) : string
Parameters
$set : ProductSet
Return values
string

productSetLinkLabel()

Returns the link label: its URL in the current language (first non-empty address as fallback).

private productSetLinkLabel(ProductSetLink $link) : string

The name is deliberately not used: it is often shared by several links or missing, which would make links indistinguishable in the picker and leave the text field empty.

Parameters
$link : ProductSetLink
Return values
string

productTagLabel()

Returns the tag name in the current language (first non-empty as fallback).

private productTagLabel(ProductTag $tag) : string
Parameters
$tag : ProductTag
Return values
string

productVariantLabelsOf()

Returns the labels of all variants of a product: `variantId => "<product name> (#<variant id>)"`.

private productVariantLabelsOf(Product $product) : array<int, string>
Parameters
$product : Product
Return values
array<int, string>

resolveProductLabel()

private resolveProductLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

resolveProductSetAccessoryLabel()

private resolveProductSetAccessoryLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

resolveProductSetFeeLabel()

private resolveProductSetFeeLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

resolveProductSetLinkLabel()

private resolveProductSetLinkLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

resolveProductTagLabel()

private resolveProductTagLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

resolveProductVariantLabel()

private resolveProductVariantLabel(int $id) : string|null
Parameters
$id : int
Return values
string|null

suggestProducts()

Suggests products by a `like` match on the product name.

private suggestProducts(string $query) : array<int, array{id: int, label: string}>
Parameters
$query : string
Return values
array<int, array{id: int, label: string}>

suggestProductSetAccessories()

Suggests sets by a `like` match on the set name, optionally without the edited set (a set cannot be its own accessory).

private suggestProductSetAccessories(string $query[, int|null $excludeId = null ]) : array<int, array{id: int, label: string}>
Parameters
$query : string
$excludeId : int|null = null
Return values
array<int, array{id: int, label: string}>

suggestProductSetFees()

Suggests fees by a `like` match on the fee name.

private suggestProductSetFees(string $query) : array<int, array{id: int, label: string}>
Parameters
$query : string
Return values
array<int, array{id: int, label: string}>

suggestProductSetItems()

Suggests composition items by a `like` match on the set name, excluding `$excludeIds`.

private suggestProductSetItems(string $query[, array<int, int> $excludeIds = [] ]) : array<int, array{id: int, label: string}>
Parameters
$query : string
$excludeIds : array<int, int> = []
Return values
array<int, array{id: int, label: string}>

Suggests links by a `like` match on the URL (`translations.value`) only, not on the name: names are often identical or missing, so only the address tells links apart.

private suggestProductSetLinks(string $query) : array<int, array{id: int, label: string}>
Parameters
$query : string
Return values
array<int, array{id: int, label: string}>

suggestProductTags()

Suggests tags by a `like` match on the tag name.

private suggestProductTags(string $query) : array<int, array{id: int, label: string}>
Parameters
$query : string
Return values
array<int, array{id: int, label: string}>

suggestProductVariants()

Suggests variants by a `like` match on the owning product name (a variant has no text of its own).

private suggestProductVariants(string $query) : array<int, array{id: int, label: string}>

IMPORTANT: query from the product side (productManager with includes: ['translations','variants']), not from the variant side via includes: ['product.translations']. ProductVariant::$product is a back-reference (inversedBy: 'variants') that OrmEntityHydrator always drops on reads, so getProduct() would be null and the label would fall back to a bare #7.

Parameters
$query : string
Return values
array<int, array{id: int, label: string}>
On this page

Search results