RelationFieldsTrait
Relation fields of the product set form: composition (set contains sets x count), accessories (set plus order) and three plain many-to-many collections (tags, fees, links).
All use a picker in a multiplier row (PickerTrait); the dynamic parameter fields are in ParameterFieldsTrait.
Save semantics:
setItemsandaccessoriesare owned join entities (orphan removal): the complete new collection is sent and an empty one deletes all (the ApibeforeSaverejects that for a bundle).tags,feesandlinksare plain many-to-many: thin id references are sent and an empty array legitimately detaches everything.
Table of Contents
Methods
- addProductSetAccessoryFields() : void
- Adds the accessory rows: picker of another set; the order is the row order (SortableJS).
- addProductSetItemFields() : void
- Adds the set composition rows: picker of another set plus quantity (`set_item_relations.count`).
- addProductSetM2mFields() : void
- Adds the plain many-to-many collections, each as a multiplier of pickers.
- buildProductSetAccessories() : ArrayCollection<int, ProductSetAccessory>
- Builds the owned accessory collection (PK set plus accessory, `order`).
- buildProductSetItems() : ArrayCollection<int, SetItemRel>
- Builds the owned `SetItemRel` collection from the composition rows (PK set plus item, `count`).
- buildProductSetM2m() : ArrayCollection<int, T>
- Builds thin id references for a plain many-to-many collection; the Api `hydrateForPersist` resolves them as managed entities and rewrites the join table.
- buildProductSetRelationRowDefaults() : array<string, array<int, array<string, mixed>>>
- Returns the multiplier prefill rows of all relation collections from the loaded set.
- guardRelationRowLimit() : void
- Guards the row limit of one of the five relation collections, measured on the raw HTTP data in `onAnchor` (see {@see MultiplierLimits::guard()} for why `onAnchor`).
- wireProductSetMultiplierButtons() : void
- Wires the add/remove buttons of a multiplier: UI-only actions (naja redraws just its snippet), hence `setValidationScope([])`; otherwise removing a row would raise required-field errors elsewhere.
Methods
addProductSetAccessoryFields()
Adds the accessory rows: picker of another set; the order is the row order (SortableJS).
private
addProductSetAccessoryFields(Form $form) : void
Parameters
- $form : Form
addProductSetItemFields()
Adds the set composition rows: picker of another set plus quantity (`set_item_relations.count`).
private
addProductSetItemFields(Form $form) : void
An item may be a ready bundle (nested set); recursion and cycles are checked by the Api
(ProductSetManager::validateComposition() and SetCompositionService).
Parameters
- $form : Form
addProductSetM2mFields()
Adds the plain many-to-many collections, each as a multiplier of pickers.
private
addProductSetM2mFields(Form $form) : void
The legacy parameters (specification) collection is not edited here; the tab uses the
dynamic fields of ParameterFieldsTrait.
Parameters
- $form : Form
buildProductSetAccessories()
Builds the owned accessory collection (PK set plus accessory, `order`).
private
buildProductSetAccessories(ArrayHash<string|int, mixed> $values, ProductSet $set) : ArrayCollection<int, ProductSetAccessory>
The order is the row position in the submit (SortableJS moves the DOM, the browser sends rows in the new order).
Parameters
- $values : ArrayHash<string|int, mixed>
- $set : ProductSet
Return values
ArrayCollection<int, ProductSetAccessory>buildProductSetItems()
Builds the owned `SetItemRel` collection from the composition rows (PK set plus item, `count`).
private
buildProductSetItems(ArrayHash<string|int, mixed> $values, ProductSet $set) : ArrayCollection<int, SetItemRel>
productSet on the child is not set here; linkOwnedCollections fills it from the owner.
A self-reference is dropped here (the Api guard would reject it anyway); other cycles (A contains B contains A) are detected only by the Api, since the admin cannot compute them without querying the DB.
Parameters
- $values : ArrayHash<string|int, mixed>
- $set : ProductSet
Return values
ArrayCollection<int, SetItemRel>buildProductSetM2m()
Builds thin id references for a plain many-to-many collection; the Api `hydrateForPersist` resolves them as managed entities and rewrites the join table.
private
buildProductSetM2m(ArrayHash<string|int, mixed> $values, string $container, string $idField, T> $entityClass) : ArrayCollection<int, T>
Parameters
- $values : ArrayHash<string|int, mixed>
- $container : string
- $idField : string
- $entityClass : T>
Tags
Return values
ArrayCollection<int, T>buildProductSetRelationRowDefaults()
Returns the multiplier prefill rows of all relation collections from the loaded set.
private
buildProductSetRelationRowDefaults(ProductSet $set) : array<string, array<int, array<string, mixed>>>
Parameters
- $set : ProductSet
Return values
array<string, array<int, array<string, mixed>>>guardRelationRowLimit()
Guards the row limit of one of the five relation collections, measured on the raw HTTP data in `onAnchor` (see {@see MultiplierLimits::guard()} for why `onAnchor`).
private
guardRelationRowLimit(Form $form, string $key) : void
The main editForm (standalone and bundle mode) does not render $form->getErrors(), so
the error is also flashed on the presenter; in variant mode editForm is AJAX and its
onError (see FormTrait) already redraws flashMessagesSnippet, so this channel
covers both modes.
Parameters
- $form : Form
- $key : string
wireProductSetMultiplierButtons()
Wires the add/remove buttons of a multiplier: UI-only actions (naja redraws just its snippet), hence `setValidationScope([])`; otherwise removing a row would raise required-field errors elsewhere.
private
wireProductSetMultiplierButtons(Multiplier $multiplier, string $snippet) : void
Parameters
- $multiplier : Multiplier
- $snippet : string