CategoryParameterRelSyncTrait
Synchronizes the parameter targeting of an e-shop category (`parameterRels`) in `afterSave`.
Port of the shared advert-category trait (CategoryParameterRelSyncTrait)
without propagation to the subtree. The useDefaultParameters gating is not done here: the
admin form does not send the parameterRels key while the category uses the default
parameters (ProductCategoryFormTrait).
The rels are not saved by the object graph (the Api ProductCategory maps them without
cascade or orphanRemoval, hence they are in defaultSkipFields). The admin form sends
meta['parameterRels'] as a flat list of {parameterId, order} rows; required,
useInSearch and group default to false, false and null, but the trait reads them generally.
The rows are replaced (delete all, then insert) through updateColumn(..., 'parameterRels', ...),
a reflective mapper insert over CategoryParameterRel::getFieldNames().
IMPORTANT: the mirror column categoryId must be set explicitly. insertable: false on the
Shared entity blocks only the regular Doctrine persist, this raw insert ignores it, so an
unset value would overwrite the FK with null.
IMPORTANT: the meta['parameterRels'] key must be told from its absence with
array_key_exists(), not ?? or empty(). Otherwise every category save that knows
nothing about parameters (for example a future batch operation without meta) would silently
delete all rels, because an empty normalized list means remove-all. A missing key leaves the
rels untouched, so they survive a resave.
Tags
Table of Contents
Methods
- buildParameterRelEntities() : array<int, CategoryParameterRel>
- normalizeParameterRelsMeta() : array<int, array{parameterId: int, order: int, required: bool, useInSearch: bool, parameterGroupId: ?int}>
- Normalizes and deduplicates the rel data from `meta['parameterRels']`. A parameter may appear in a category only once (composite PK = category + `parameterId`), so a duplicate `parameterId` is dropped (the first wins).
- syncCategoryParameterRels() : Result|null
- Returns `null` when nothing changed, otherwise the `Result` of the rel write.
Methods
buildParameterRelEntities()
private
buildParameterRelEntities(int $categoryId, array<int, array{parameterId: int, order: int, required: bool, useInSearch: bool, parameterGroupId: ?int}> $relsData) : array<int, CategoryParameterRel>
Parameters
- $categoryId : int
- $relsData : array<int, array{parameterId: int, order: int, required: bool, useInSearch: bool, parameterGroupId: ?int}>
Return values
array<int, CategoryParameterRel>normalizeParameterRelsMeta()
Normalizes and deduplicates the rel data from `meta['parameterRels']`. A parameter may appear in a category only once (composite PK = category + `parameterId`), so a duplicate `parameterId` is dropped (the first wins).
private
normalizeParameterRelsMeta(array<string, mixed> $meta) : array<int, array{parameterId: int, order: int, required: bool, useInSearch: bool, parameterGroupId: ?int}>
Parameters
- $meta : array<string, mixed>
Return values
array<int, array{parameterId: int, order: int, required: bool, useInSearch: bool, parameterGroupId: ?int}>syncCategoryParameterRels()
Returns `null` when nothing changed, otherwise the `Result` of the rel write.
private
syncCategoryParameterRels(ProductCategory $category, array<string, mixed> $meta) : Result|null
afterSave() must evaluate it and pass a failure on, so that the shared SaveTrait rolls
back the whole save. updateColumn() catches DBALException and returns
Result::failure() without rethrowing (SaveTrait::updateColumns()),
so a discarded return value would show the admin "saved" with the parameter targeting
not written.
Parameters
- $category : ProductCategory
- $meta : array<string, mixed>