AbstractParameterRuleManager
extends Manager
in package
Manager of option rules (`SHOW_SELECT_OPTIONS`, action = 1), shared by the Bazaar, Comcat and Eshop leaf managers.
Next to the generic save() and delete() of Manager it offers a granular raw-DBAL
target-write API for the immediate-save OptionRules component (not an object-graph delete-all and reinsert):
- self::addTarget() and self::removeTarget() pin or unpin one option as a single join row; foreign or shared targets and the rule conditions stay untouched.
- self::saveCondition() upserts the rule and a single condition of it (key) with its values; other conditions of the rule are kept, which protects legacy multi-condition rules.
- self::recalcAlwaysVisible() recomputes
always_visibleof the select options from the DB (from targets, not from meta) after every mutating signal.
IMPORTANT: a target always carries both parameter_id of the select and option_id of the
option; otherwise the Front DependentSelectTrait loses the rule. addTarget() fills both.
The only module-specific input is $map (physical cms_mod_{module}_* names). The class must
not import a module entity, hence the local self::ACTION_SHOW_SELECT_OPTIONS.
Tags
Table of Contents
Constants
- ACTION_SHOW_SELECT_OPTIONS : mixed = 1
- Same value as `ParameterRule::ACTION_SHOW_SELECT_OPTIONS` of every module entity.
Properties
- $service : TService
- Manager service; subclasses narrow the type (`@property` in the Api/Admin/Front manager).
- $appContext : AppContext
- $cacheTagInvalidator : CacheTagInvalidator|null
- Post-commit invalidator of the wire-payload query cache (tag bump per entity class).
- $connection : Connection
- $languageContext : LanguageContext|null
- $map : ParameterTableMap
- $paramsConfig : Config|null
- Neon parameters (`%params%`: server paths and directories), set by the decorator (`decorators.neon`) like `setAppContext()`.
- $presenterContext : PresenterContext
- $settingContext : SettingContext
Methods
- __construct() : mixed
- addDisplayTarget() : void
- Applies the rule to the display target (one target row, option_id NULL); idempotent through an exists check.
- addTarget() : void
- Pins option `$optionId` of select `$selectId` to rule `$ruleId` (one target row).
- delete() : Result
- deleteAll() : Result
- 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).
- getAllRuleIds() : array<int, int>
- Returns ids of every rule (unified pool, the effect derives from the target, not from action).
- getAppContext() : AppContext
- getDisplayTargetRuleIds() : array<int, int>
- Returns ids of rules applied to this display target (they have its target row with option_id NULL).
- getLanguageContext() : LanguageContext|null
- getOptionRuleMap() : array<int, array<int, int>>
- Returns a map of option to the rules controlling it on the given select (per-option modal and option badge).
- getPresenterContext() : PresenterContext
-
getRuleConditionRows()
: array<int, array{parameterId: int, validator: string, optionIds: list
, values: list }> - Returns conditions of rule `$ruleId` (ordered by `key`) as normalized arrays, to prefill the "Manage" modal.
- getRuleIdsByAction() : array<int, int>
- Returns ids of all rules of the given action (picker "attach existing rule" in the display editor).
- getSelectRuleIds() : array<int, int>
- Returns ids of action = 1 rules relevant to select `$selectId`: rules with a target ON this select, or draft rules (no target anywhere) such as a freshly created condition without assigned options.
- getSettingContext() : SettingContext
- getSettings() : array<int, array<string, mixed>>
- getTableMap() : ParameterTableMap
- Returns the physical-name map of this module (see {@see ParameterTableMap}).
- getTargetOptionIds() : array<int, int>
- Returns option ids controlled by rule `$ruleId` on select `$selectId` (prefill of the assign modal and diff on save).
- 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
- isRuleSharedBeyond() : bool
- Tells whether rule `$ruleId` has targets on a select other than `$selectId`.
- recalcAlwaysVisible() : void
- Recomputes `always_visible` of the options of select `$selectId` from the DB (from targets, not from meta).
- removeDisplayTarget() : void
- Removes the rule from the display target (deletes only this target row); the rule stays in the pool, no garbage collection.
- removeTarget() : void
- Unpins option `$optionId` of select `$selectId` from rule `$ruleId` (deletes one target row).
- save() : Result
- saveCondition() : int
- Upserts the rule (action = 1) and a single condition of it (`$conditionKey`) with its values.
- saveRuleConditions() : int
- Saves the whole set of rule conditions (action = 1) in one transaction and returns `parameter_rule_id`.
- setAppContext() : $this
- setCacheTagInvalidator() : static
- setLanguageContext() : $this
- setParamsConfig() : static
- setPresenterContext() : $this
- setSettingContext() : $this
- syncDisplayTargets() : void
- Synchronizes the application of rules to a display target with the staged form selection: adds newly checked rules and removes unchecked ones. `$ruleIds` are the checked rules (a subset of the pool). It runs only when the parameter or group is saved, so the change takes effect only after the whole save. It never touches rule conditions, sources or foreign targets (only option_id NULL on this target).
- 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).
- bumpParameterRuleCacheTags() : void
- Bumps the cache tags after a raw-DBAL rule mutation; fail-open (the invalidator swallows exceptions), so a write never fails.
- cacheTagClasses() : array<int, class-string|string>
- Returns the Api entity class names whose query cache tags are bumped after a raw-DBAL rule mutation.
- 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.
- getService() : TService
- Returns the service for the traits.
- safeDisplayTargetColumn() : string
- Whitelists the display target column (parameter or group); it is interpolated into SQL.
Constants
ACTION_SHOW_SELECT_OPTIONS
Same value as `ParameterRule::ACTION_SHOW_SELECT_OPTIONS` of every module entity.
private
mixed
ACTION_SHOW_SELECT_OPTIONS
= 1
Each module entity carries its own copy and the shared ParameterRuleInterface declares no action
constants; this class must not import a module entity, so it keeps a local literal.
Properties
$service
Manager service; subclasses narrow the type (`@property` in the Api/Admin/Front manager).
public
TService
$service
$appContext
protected
AppContext
$appContext
$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.
$connection read-only
protected
Connection
$connection
$languageContext
protected
LanguageContext|null
$languageContext
= NULL
$map read-only
protected
ParameterTableMap
$map
$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.
$presenterContext
protected
PresenterContext
$presenterContext
$settingContext
protected
SettingContext
$settingContext
Methods
__construct()
public
__construct(TService $service, Connection $connection, ParameterTableMap $map) : mixed
Parameters
- $service : TService
- $connection : Connection
- $map : ParameterTableMap
addDisplayTarget()
Applies the rule to the display target (one target row, option_id NULL); idempotent through an exists check.
public
addDisplayTarget(string $targetColumn, int $targetId, int $ruleId) : void
Parameters
- $targetColumn : string
- $targetId : int
- $ruleId : int
addTarget()
Pins option `$optionId` of select `$selectId` to rule `$ruleId` (one target row).
public
addTarget(int $selectId, int $ruleId, int $optionId) : void
Idempotent: a PHP exists check stands in until the manual UNIQUE key exists.
Parameters
- $selectId : int
- $ruleId : int
- $optionId : int
delete()
public
delete(int|array<string|int, mixed> $id) : Result
Parameters
- $id : int|array<string|int, mixed>
Return values
ResultdeleteAll()
public
deleteAll([array<string|int, mixed> $filters = [] ]) : Result
Parameters
- $filters : array<string|int, mixed> = []
Return values
Resultfind()
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>getAllRuleIds()
Returns ids of every rule (unified pool, the effect derives from the target, not from action).
public
getAllRuleIds() : array<int, int>
Used by the "attach existing rule" pickers in both tabs (display and options).
Return values
array<int, int>getAppContext()
public
getAppContext() : AppContext
Return values
AppContextgetDisplayTargetRuleIds()
Returns ids of rules applied to this display target (they have its target row with option_id NULL).
public
getDisplayTargetRuleIds(string $targetColumn, int $targetId) : array<int, int>
Parameters
- $targetColumn : string
- $targetId : int
Return values
array<int, int>getLanguageContext()
public
getLanguageContext() : LanguageContext|null
Return values
LanguageContext|nullgetOptionRuleMap()
Returns a map of option to the rules controlling it on the given select (per-option modal and option badge).
public
getOptionRuleMap(int $selectId) : array<int, array<int, int>>
Only action = 1 (SHOW_SELECT_OPTIONS) and non-null option_id count.
Parameters
- $selectId : int
Return values
array<int, array<int, int>> —optionId => list ruleId
getPresenterContext()
public
getPresenterContext() : PresenterContext
Return values
PresenterContextgetRuleConditionRows()
Returns conditions of rule `$ruleId` (ordered by `key`) as normalized arrays, to prefill the "Manage" modal.
public
getRuleConditionRows(int $ruleId) : array<int, array{parameterId: int, validator: string, optionIds: list, values: list}>
Also works for a floating rule (no target on the select, where self::getOptionRuleMap() finds nothing). The parameter label is resolved in the presenter (resolveParameterLabel).
Parameters
- $ruleId : int
Return values
array<int, array{parameterId: int, validator: string, optionIds: listgetRuleIdsByAction()
Returns ids of all rules of the given action (picker "attach existing rule" in the display editor).
public
getRuleIdsByAction(int $action) : array<int, int>
Parameters
- $action : int
Return values
array<int, int>getSelectRuleIds()
Returns ids of action = 1 rules relevant to select `$selectId`: rules with a target ON this select, or draft rules (no target anywhere) such as a freshly created condition without assigned options.
public
getSelectRuleIds(int $selectId) : array<int, int>
Draft rules must be listed, otherwise they cannot be assigned through "edit options".
Parameters
- $selectId : int
Return values
array<int, int>getSettingContext()
public
getSettingContext() : SettingContext
Return values
SettingContextgetSettings()
public
getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>getTableMap()
Returns the physical-name map of this module (see {@see ParameterTableMap}).
public
getTableMap() : ParameterTableMap
Lets presenters derive the module-specific column ($map->parameterFk() or $map->groupFk()
for display rules) without carrying their own literal.
Return values
ParameterTableMapgetTargetOptionIds()
Returns option ids controlled by rule `$ruleId` on select `$selectId` (prefill of the assign modal and diff on save).
public
getTargetOptionIds(int $selectId, int $ruleId) : array<int, int>
Only non-null option ids count (controlled options, not group hide targets).
Parameters
- $selectId : int
- $ruleId : int
Return values
array<int, int>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|nullinitializeAllContexts()
public
initializeAllContexts() : void
isRuleSharedBeyond()
Tells whether rule `$ruleId` has targets on a select other than `$selectId`.
public
isRuleSharedBeyond(int $selectId, int $ruleId) : bool
Deleting the whole rule cascades to those foreign targets, so the other select would silently lose the rule; the delete confirmation is stricter in that case.
Parameters
- $selectId : int
- $ruleId : int
Return values
boolrecalcAlwaysVisible()
Recomputes `always_visible` of the options of select `$selectId` from the DB (from targets, not from meta).
public
recalcAlwaysVisible(int $selectId) : void
Options controlled by at least one rule (an option target on this select; the effect comes from the target, not from action) get 0 (the Front hides them until the condition holds), other options of the select get 1. Call it after every mutating signal.
Parameters
- $selectId : int
removeDisplayTarget()
Removes the rule from the display target (deletes only this target row); the rule stays in the pool, no garbage collection.
public
removeDisplayTarget(string $targetColumn, int $targetId, int $ruleId) : void
Parameters
- $targetColumn : string
- $targetId : int
- $ruleId : int
removeTarget()
Unpins option `$optionId` of select `$selectId` from rule `$ruleId` (deletes one target row).
public
removeTarget(int $selectId, int $ruleId, int $optionId) : void
Parameters
- $selectId : int
- $ruleId : int
- $optionId : int
save()
public
save(BaseEntity $entity[, array<string, mixed> $meta = [] ]) : Result
Parameters
- $entity : BaseEntity
- $meta : array<string, mixed> = []
Return values
ResultsaveCondition()
Upserts the rule (action = 1) and a single condition of it (`$conditionKey`) with its values.
public
saveCondition(int|null $ruleId, int $conditionKey, int $sourceParameterId, string $validator[, array<int, int> $optionIds = [] ][, array<int, string> $values = [] ]) : int
Returns parameter_rule_id (new when $ruleId is null or 0, otherwise the existing one).
Replaces just the row of the given condition (its values are removed by FK cascade); other
conditions of the rule (legacy multi-condition) and the targets stay. The function (and/or)
of the edited condition is preserved.
Parameters
- $ruleId : int|null
- $conditionKey : int
- $sourceParameterId : int
- $validator : string
- $optionIds : array<int, int> = []
-
checked options of the source (validator over an options parameter)
- $values : array<int, string> = []
-
text values (validators such as
:min)
Return values
intsaveRuleConditions()
Saves the whole set of rule conditions (action = 1) in one transaction and returns `parameter_rule_id`.
public
saveRuleConditions(int|null $ruleId, array<int, array{sourceParameterId: int, validator: string, optionIds: list, values: list}> $conditions) : int
Creates the rule when $ruleId is null or 0, deletes all its existing conditions, inserts
$conditions renumbered to keys 1..N (with values) and recomputes the source rows. Target options
are handled separately by self::addTarget() and self::removeTarget().
Unlike self::saveCondition() (per-key increment, keeps legacy function) it edits the rule
as a whole, because the "Manage" modal always sends the complete condition set. function (and/or)
is set to NULL: the Front combines conditions with an implicit AND and ignores function.
Parameters
- $ruleId : int|null
-
$conditions
: array<int, array{sourceParameterId: int, validator: string, optionIds: list
, values: list }>
Return values
intsetAppContext()
public
setAppContext(AppContext $appContext) : $this
Parameters
- $appContext : AppContext
Return values
$thissetCacheTagInvalidator()
public
setCacheTagInvalidator(CacheTagInvalidator $cacheTagInvalidator) : static
Parameters
- $cacheTagInvalidator : CacheTagInvalidator
Return values
staticsetLanguageContext()
public
setLanguageContext(LanguageContext|null $languageContext) : $this
Parameters
- $languageContext : LanguageContext|null
Return values
$thissetParamsConfig()
public
setParamsConfig(Config $paramsConfig) : static
Parameters
- $paramsConfig : Config
Return values
staticsetPresenterContext()
public
setPresenterContext(PresenterContext $presenterContext) : $this
Parameters
- $presenterContext : PresenterContext
Return values
$thissetSettingContext()
public
setSettingContext(SettingContext $settingContext) : $this
Parameters
- $settingContext : SettingContext
Return values
$thissyncDisplayTargets()
Synchronizes the application of rules to a display target with the staged form selection: adds newly checked rules and removes unchecked ones. `$ruleIds` are the checked rules (a subset of the pool). It runs only when the parameter or group is saved, so the change takes effect only after the whole save. It never touches rule conditions, sources or foreign targets (only option_id NULL on this target).
public
syncDisplayTargets(string $targetColumn, int $targetId, array<int, int>|array<int|string, mixed> $ruleIds) : void
Parameters
- $targetColumn : string
- $targetId : int
- $ruleIds : array<int, int>|array<int|string, mixed>
updateColumn()
public
updateColumn(int|array<string|int, mixed> $entityId, string $property, mixed $value) : Result
Parameters
- $entityId : int|array<string|int, mixed>
-
id, or a list of ids / composite-id arrays
- $property : string
- $value : mixed
Return values
ResultupdateColumns()
public
updateColumns(int|array<string|int, mixed> $entityId, array<string, mixed> $values) : Result
Parameters
- $entityId : int|array<string|int, mixed>
-
id, or a list of ids / composite-id arrays
- $values : array<string, mixed>
-
property name => new value
Return values
ResultbumpCacheTags()
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> = []
bumpParameterRuleCacheTags()
Bumps the cache tags after a raw-DBAL rule mutation; fail-open (the invalidator swallows exceptions), so a write never fails.
protected
bumpParameterRuleCacheTags() : void
cacheTagClasses()
Returns the Api entity class names whose query cache tags are bumped after a raw-DBAL rule mutation.
protected
abstract cacheTagClasses() : array<int, class-string|string>
IMPORTANT: this manager writes rules by raw DBAL and bypasses the bridge, so the bump in the shared
Api\SaveTrait does not cover it. Without the bump the Front advert form and list filter keep
behaving by the old rule until the query cache TTL of the parameter service expires
(cache.config.serviceTtl, an hour by default), because DependentSelectTrait
reads rules through includes over the cached ParameterService.
The leaf returns the FQCNs of the Api entities as plain strings (the tags are named by them,
e.g. app:cache:tag:App\UI\Api\Bazaar\Models\Entities\Parameter), because the admin layer does not
import a foreign module. The method is abstract on purpose: a new module without it fails loudly
instead of silently serving a stale front end.
Return values
array<int, class-string|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>getService()
Returns the service for the traits.
protected
getService() : TService
Return values
TServicesafeDisplayTargetColumn()
Whitelists the display target column (parameter or group); it is interpolated into SQL.
private
safeDisplayTargetColumn(string $column) : string
Parameters
- $column : string