CoolCMS API

ProductSetManager extends Manager
in package
uses ElasticReindexTrait

Abstract admin manager generic over the entity type and its service.

Tags
extends

Table of Contents

Properties

$service  : ProductSetService
$appContext  : AppContext
$cacheTagInvalidator  : CacheTagInvalidator|null
Post-commit invalidator of the wire-payload query cache (tag bump per entity class).
$languageContext  : LanguageContext|null
$paramsConfig  : Config|null
Neon parameters (`%params%`: server paths and directories), set by the decorator (`decorators.neon`) like `setAppContext()`.
$presenterContext  : PresenterContext
$settingContext  : SettingContext
$esDocumentSource  : ProductSetDocumentSource
$esIndexer  : EsEntityIndexer

Methods

__construct()  : mixed
delete()  : Result
deleteAll()  : Result
deleteOrHide()  : Result
Deletes from the grid: a set without history is hard deleted; a set referenced by an order, complaint or gift is only hidden (`deleted=1`). The history gate lives in the Api ({@see \App\UI\Api\Eshop\Models\Managers\ProductSetManager::findHistoryBlockers()}); here a `PRODUCT_SET_DELETE_BLOCKED` rejection is converted to a soft delete. Ids are processed one by one and the result follows {@see ProductManager::deleteOrHide()}.
deletePriceSnapshot()  : array{success: bool, code: string}
Deletes a whole price snapshot through the bridge action `.../delete-price-snapshot`.
duplicateCurrentPriceSnapshot()  : bool
Duplicates a variant: copies the currently valid price snapshot of the source set as the first and only row of the target set.
fetchAvailability()  : array<int, array{availableSets: ?int, inStock: bool, deliveryDays: ?int, labelWarehouseId: ?int, infoText: ?string, attributeClass: ?string, unmappedVariantIds: list, unresolvedSetIds: list}>
Returns the availability of product sets in a batch, for the grid decoration and the stock panel in the edit form. `available` and `availableSets` are never cached.
fetchCurrentPrices()  : array<int, array{price: string, originalPrice: string, points: int, fromAmount: int, currencyId: int, vat: string, withVat: bool}>
Returns the currently valid prices of product sets in a batch, for the grid decoration (`DataGrid::setRowDecorator`) and the "currently valid price" panel in the edit form.
fetchDefaults()  : array{userGroupId: int, currencyId: int, paymentRegionId: int}
Returns the default catalog axes (base user group, default currency, default payment region) needed when the admin writes a price (inline variant price in the product pivot form).
find()  : SingleQuery<string|int, T>
Finds one entity by id (returns a `SingleQuery` object).
findAll()  : Query<string|int, T>
Finds all entities (returns a `Query` object).
findBy()  : SingleQuery<string|int, T>
Finds one entity by filters (returns a `SingleQuery` object).
getAppContext()  : AppContext
getLanguageContext()  : LanguageContext|null
getPresenterContext()  : PresenterContext
getSettingContext()  : SettingContext
getSettings()  : array<int, array<string, mixed>>
getTotalCount()  : int|null
Returns the total count of the last `findAll()` of this manager's service, computed only when the query asked for it (`findAll(..., computeTotalCount: true)`); otherwise the last stored value.
initializeAllContexts()  : void
save()  : Result
savePriceSnapshot()  : array{success: bool, code: string}
Saves or replaces a price snapshot (price list tab) through the bridge action `.../save-price-snapshot`.
setAppContext()  : $this
setCacheTagInvalidator()  : static
setLanguageContext()  : $this
setParamsConfig()  : static
setPresenterContext()  : $this
setSettingContext()  : $this
softDelete()  : Result
Soft deletes sets without a cascade (`deleted=1` instead of deleting rows) through the bridge action `.../soft-delete`. Has the same `int|array` signature as the generic {@see delete()} (group deletion in the grid sends an array of ids).
updateColumn()  : Result
updateColumns()  : Result
bumpCacheTags()  : void
Bumps cache tags for the entity after commit: its class, the owned-cascade classes from metadata and the optional `additionalCacheTags()` of the manager.
bumpCacheTagsExplicit()  : void
Bumps the given classes explicitly (raw-DBAL paths with a cross-entity effect).
bumpCacheTagsForClass()  : void
Bumps cache tags by class name when there is no instance (bulk delete, `updateColumns()`, raw DBAL, tree operations).
classCacheTags()  : array<string|int, string>
Returns extra tags for a bump that has no entity, typically tree operations ({@see \App\Core\Traits\Api\Models\Managers\TreeTrait::treeTransaction()}) that rewrite `lft`/`rgt` on many rows.
esReindexBestEffort()  : void
Catches ES up after an admin mutation; it never breaks a write that is already in the database.
getService()  : TService
Returns the service for the traits.
touchForEsWatermark()  : void
Bumps `updateTime` for the watermark sync ({@see ElasticReindexTrait::save()}). Nothing else sets this column for product sets, so the sync would miss admin edits.

Properties

$cacheTagInvalidator

Post-commit invalidator of the wire-payload query cache (tag bump per entity class).

protected CacheTagInvalidator|null $cacheTagInvalidator = null

Set by the decorator (decorators.neon) like setParamsConfig(). Nullable and fail-open: without wiring (or without Redis) a bump is a no-op.

$paramsConfig

Neon parameters (`%params%`: server paths and directories), set by the decorator (`decorators.neon`) like `setAppContext()`.

protected Config|null $paramsConfig = null

Write logic (asset directories) reads paths from here, not from getSettings() or the setting context, which may be filled by the client without server paths. The property cannot be named $config: it collides with the promoted $config in some managers.

Methods

deleteAll()

public deleteAll([array<string|int, mixed> $filters = [] ]) : Result
Parameters
$filters : array<string|int, mixed> = []
Return values
Result

deleteOrHide()

Deletes from the grid: a set without history is hard deleted; a set referenced by an order, complaint or gift is only hidden (`deleted=1`). The history gate lives in the Api ({@see \App\UI\Api\Eshop\Models\Managers\ProductSetManager::findHistoryBlockers()}); here a `PRODUCT_SET_DELETE_BLOCKED` rejection is converted to a soft delete. Ids are processed one by one and the result follows {@see ProductManager::deleteOrHide()}.

public deleteOrHide(int|array<int, int> $id) : Result
Parameters
$id : int|array<int, int>
Return values
Result

deletePriceSnapshot()

Deletes a whole price snapshot through the bridge action `.../delete-price-snapshot`.

public deletePriceSnapshot(int $id, string $publishedTime) : array{success: bool, code: string}
Parameters
$id : int
$publishedTime : string
Return values
array{success: bool, code: string}

duplicateCurrentPriceSnapshot()

Duplicates a variant: copies the currently valid price snapshot of the source set as the first and only row of the target set.

public duplicateCurrentPriceSnapshot(int $sourceSetId, int $targetSetId) : bool

Runs admin-side over the existing bridge, with no extra Api action: findAll with includes ['prices'] (same channel as PriceSnapshotTrait::loadSnapshotSet()), takes the rows with publishedTime = MAX(<= now) across all axes, then calls savePriceSnapshot() with publishedTime=null (the bridge resolves it to "now", so the copy is a new row, not a copy of the original date). History and VAT rows are not copied; the static vatId fallback is copied by the set object graph. Returns false (no-op) when the source does not exist or has no currently valid snapshot.

Parameters
$sourceSetId : int
$targetSetId : int
Return values
bool

fetchAvailability()

Returns the availability of product sets in a batch, for the grid decoration and the stock panel in the edit form. `available` and `availableSets` are never cached.

public fetchAvailability(array<string|int, int> $ids[, int|null $languageId = null ]) : array<int, array{availableSets: ?int, inStock: bool, deliveryDays: ?int, labelWarehouseId: ?int, infoText: ?string, attributeClass: ?string, unmappedVariantIds: list, unresolvedSetIds: list}>
Parameters
$ids : array<string|int, int>
$languageId : int|null = null
Return values
array<int, array{availableSets: ?int, inStock: bool, deliveryDays: ?int, labelWarehouseId: ?int, infoText: ?string, attributeClass: ?string, unmappedVariantIds: list, unresolvedSetIds: list}>

fetchCurrentPrices()

Returns the currently valid prices of product sets in a batch, for the grid decoration (`DataGrid::setRowDecorator`) and the "currently valid price" panel in the edit form.

public fetchCurrentPrices(array<string|int, int> $ids[, int|null $userGroupId = null ][, int|null $currencyId = null ][, int $amount = 1 ]) : array<int, array{price: string, originalPrice: string, points: int, fromAmount: int, currencyId: int, vat: string, withVat: bool}>

IMPORTANT: do not use the denormalized column product_sets.price; it is only a sort key and does not hold the displayed price.

Parameters
$ids : array<string|int, int>
$userGroupId : int|null = null
$currencyId : int|null = null
$amount : int = 1
Return values
array<int, array{price: string, originalPrice: string, points: int, fromAmount: int, currencyId: int, vat: string, withVat: bool}>

fetchDefaults()

Returns the default catalog axes (base user group, default currency, default payment region) needed when the admin writes a price (inline variant price in the product pivot form).

public fetchDefaults() : array{userGroupId: int, currencyId: int, paymentRegionId: int}
Return values
array{userGroupId: int, currencyId: int, paymentRegionId: int}

find()

Finds one entity by id (returns a `SingleQuery` object).

public find(int $id[, string|array<string|int, mixed> $includes = [] ]) : SingleQuery<string|int, T>
Parameters
$id : int

entity id

$includes : string|array<string|int, mixed> = []

relations to load (['translations', 'routes'] or '*' for all)

Return values
SingleQuery<string|int, T>

findAll()

Finds all entities (returns a `Query` object).

public findAll([array<string|int, mixed>|null $filters = [] ][, array<string|int, mixed>|null $orderBy = null ][, int|null $offset = null ][, int|null $limit = null ][, array<string|int, mixed>|null $columns = null ][, string|array<string|int, mixed> $includes = [] ][, bool $computeTotalCount = false ]) : Query<string|int, T>
Parameters
$filters : array<string|int, mixed>|null = []

filters for the where conditions

$orderBy : array<string|int, mixed>|null = null

ordering ['column' => 'ASC/DESC']

$offset : int|null = null

offset for pagination

$limit : int|null = null

result limit

$columns : array<string|int, mixed>|null = null

specific columns to load

$includes : string|array<string|int, mixed> = []

relations to load (['translations', 'routes.translations'] or '*' for all)

$computeTotalCount : bool = false

whether to compute the total count for pagination

Return values
Query<string|int, T>

findBy()

Finds one entity by filters (returns a `SingleQuery` object).

public findBy([array<string|int, mixed> $filters = [] ][, string|array<string|int, mixed> $includes = [] ]) : SingleQuery<string|int, T>
Parameters
$filters : array<string|int, mixed> = []

filters for the where conditions

$includes : string|array<string|int, mixed> = []

relations to load (['translations', 'routes'] or '*' for all)

Return values
SingleQuery<string|int, T>

getSettings()

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

getTotalCount()

Returns the total count of the last `findAll()` of this manager's service, computed only when the query asked for it (`findAll(..., computeTotalCount: true)`); otherwise the last stored value.

public getTotalCount() : int|null

Same value as Query::getTotalCount() of that query.

Return values
int|null

savePriceSnapshot()

Saves or replaces a price snapshot (price list tab) through the bridge action `.../save-price-snapshot`.

public savePriceSnapshot(int $id, string|null $publishedTime, array<int, array{fromAmount: int, userGroupId: int, currencyId: int, price: string|float, originalPrice: string|float|null, points: int}> $rows[, string|null $replaceTime = null ]) : array{success: bool, code: string}

replaceTime is the publishedTime of the edited snapshot (null adds a new one).

Parameters
$id : int
$publishedTime : string|null
$rows : array<int, array{fromAmount: int, userGroupId: int, currencyId: int, price: string|float, originalPrice: string|float|null, points: int}>
$replaceTime : string|null = null
Return values
array{success: bool, code: string}

setParamsConfig()

public setParamsConfig(Config $paramsConfig) : static
Parameters
$paramsConfig : Config
Return values
static

softDelete()

Soft deletes sets without a cascade (`deleted=1` instead of deleting rows) through the bridge action `.../soft-delete`. Has the same `int|array` signature as the generic {@see delete()} (group deletion in the grid sends an array of ids).

public softDelete(int|array<int, int> $id) : Result
Parameters
$id : int|array<int, int>
Return values
Result

updateColumn()

public updateColumn(int|array<string|int, int> $entityId, string $property, mixed $value) : Result
Parameters
$entityId : int|array<string|int, int>
$property : string
$value : mixed
Return values
Result

updateColumns()

public updateColumns(int|array<string|int, int> $entityId, array<string, mixed> $values) : Result
Parameters
$entityId : int|array<string|int, int>
$values : array<string, mixed>
Return values
Result

bumpCacheTags()

Bumps cache tags for the entity after commit: its class, the owned-cascade classes from metadata and the optional `additionalCacheTags()` of the manager.

protected bumpCacheTags(object $entity) : void

Fail-open (the invalidator swallows exceptions). Called from the manager Save/Delete/Tree traits after the commit.

Parameters
$entity : object

bumpCacheTagsExplicit()

Bumps the given classes explicitly (raw-DBAL paths with a cross-entity effect).

protected bumpCacheTagsExplicit(array<string|int, string> $classes) : void
Parameters
$classes : array<string|int, string>

bumpCacheTagsForClass()

Bumps cache tags by class name when there is no instance (bulk delete, `updateColumns()`, raw DBAL, tree operations).

protected bumpCacheTagsForClass(class-string $rootClass[, array<string|int, string> $extraTags = [] ]) : void

Bumps the root class and its owned-cascade classes.

Parameters
$rootClass : class-string
$extraTags : array<string|int, string> = []

classCacheTags()

Returns extra tags for a bump that has no entity, typically tree operations ({@see \App\Core\Traits\Api\Models\Managers\TreeTrait::treeTransaction()}) that rewrite `lft`/`rgt` on many rows.

protected classCacheTags() : array<string|int, string>

IMPORTANT: additionalCacheTags(object) receives an entity, so a class-level bump cannot use it; without this hook a delete would lose the cross-entity tag (Comment to CommentThread). A manager whose cross-entity tag does not depend on a particular entity returns it here.

NOTE: unlike additionalCacheTags(), this hook is declared (with an empty default) instead of being an opt-in through method_exists(); method_exists() is always true in a manager that has the method, which phpstan reports as alreadyNarrowedType.

Return values
array<string|int, string>

esReindexBestEffort()

Catches ES up after an admin mutation; it never breaks a write that is already in the database.

protected esReindexBestEffort(array<string|int, int> $ids) : void
Parameters
$ids : array<string|int, int>

getService()

Returns the service for the traits.

protected getService() : TService
Return values
TService

touchForEsWatermark()

Bumps `updateTime` for the watermark sync ({@see ElasticReindexTrait::save()}). Nothing else sets this column for product sets, so the sync would miss admin edits.

protected touchForEsWatermark(BaseEntity $entity) : void
Parameters
$entity : BaseEntity
On this page

Search results