ProductFormTrait
Product pivot form, modeled on {@see \App\UI\Admin\Bazaar\Presenters\Traits\Forms\AdvertFormTrait}.
Saving has two paths (variants and their sale sets are saved only in the modal component ProductSetEdit, outside this form):
- Product + texts + categories: object graph (
api/eshop/product). Texts are an owned collection (orphanRemoval), categories a plain M:N (id references, full replace, so an empty multiplier legitimately detaches all categories). - Main photo:
$meta['image']/$meta['imageDelete'](base64); the Api makes an Asset with variants from it and sets the FK (as in BlogCategoryManager).
Table of Contents
Methods
- createComponentEditForm() : Form
- addProductBaseFields() : void
- Basics: producer, type, activation, main photo.
- addProductCategoryFields() : void
- Categories (M:N): multiplier of rows with a Picker. A row is a hidden `categoryId` + a text label `category` (rendered by the Picker itself; {@see \App\UI\Admin\Eshop\Presenters\Traits\Pickers\ProductCategoryPickerTrait}).
- addProductTranslationFields() : void
- Multilingual fields: one set per language (`<field>_<langId>`), active per checkbox.
- buildProductCategories() : ArrayCollection<int, ProductCategory>
- Categories as light id references: Api `hydrateForPersist` looks them up as managed entities and syncs the join table.
- buildProductEntity() : Product
- Product + texts + categories. On edit it works with the loaded entity (it carries associations the form does not edit, which the object-graph save would otherwise null; `variants` is in Api `defaultSkipFields`, so this save never touches it).
- collectProductImageMeta() : array<string, mixed>
- Main photo for `$meta`: a new image (base64) and/or the delete flag. The Api makes an Asset (variants) from it and sets the FK.
- loadProductSelectData() : void
- Form axes (producers, product types), once per request, before building fields and defaults.
- persistProduct() : Product|null
- Shared save logic of `save`/`update` and `saveAndVariants`: builds the entity, saves it (object graph + main photo meta) and flashes the result. Returns the saved entity (with id) or null on error.
- referenceOrNull() : T|null
- Light entity reference (id only); the hydrator looks it up as managed on the Api side.
- saveProductAndManageVariants() : void
- "Save product first" button: its own onClick outside the save/update gate (see the comment at `$saveAndVariants` in `createComponentEditForm()`). Shares the save logic with `saveProductForm()` via `persistProduct()` and on success also navigates to the edit (the right column switches from the gate button to the variant list).
- saveProductForm() : bool
- setProductFormDefaults() : void
Methods
createComponentEditForm()
protected
createComponentEditForm() : Form
Return values
FormaddProductBaseFields()
Basics: producer, type, activation, main photo.
private
addProductBaseFields(Form $form) : void
Parameters
- $form : Form
addProductCategoryFields()
Categories (M:N): multiplier of rows with a Picker. A row is a hidden `categoryId` + a text label `category` (rendered by the Picker itself; {@see \App\UI\Admin\Eshop\Presenters\Traits\Pickers\ProductCategoryPickerTrait}).
private
addProductCategoryFields(Form $form) : void
Parameters
- $form : Form
addProductTranslationFields()
Multilingual fields: one set per language (`<field>_<langId>`), active per checkbox.
private
addProductTranslationFields(Form $form) : void
Parameters
- $form : Form
buildProductCategories()
Categories as light id references: Api `hydrateForPersist` looks them up as managed entities and syncs the join table.
private
buildProductCategories(ArrayHash<string|int, mixed> $values) : ArrayCollection<int, ProductCategory>
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
ArrayCollection<int, ProductCategory>buildProductEntity()
Product + texts + categories. On edit it works with the loaded entity (it carries associations the form does not edit, which the object-graph save would otherwise null; `variants` is in Api `defaultSkipFields`, so this save never touches it).
private
buildProductEntity(ArrayHash<string|int, mixed> $values) : Product
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
ProductcollectProductImageMeta()
Main photo for `$meta`: a new image (base64) and/or the delete flag. The Api makes an Asset (variants) from it and sets the FK.
private
collectProductImageMeta(ArrayHash<string|int, mixed> $values) : array<string, mixed>
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
array<string, mixed>loadProductSelectData()
Form axes (producers, product types), once per request, before building fields and defaults.
private
loadProductSelectData() : void
persistProduct()
Shared save logic of `save`/`update` and `saveAndVariants`: builds the entity, saves it (object graph + main photo meta) and flashes the result. Returns the saved entity (with id) or null on error.
private
persistProduct(ArrayHash<string|int, mixed> $values) : Product|null
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
Product|nullreferenceOrNull()
Light entity reference (id only); the hydrator looks it up as managed on the Api side.
private
referenceOrNull(T> $entityClass, int|null $id) : T|null
Parameters
- $entityClass : T>
- $id : int|null
Tags
Return values
T|nullsaveProductAndManageVariants()
"Save product first" button: its own onClick outside the save/update gate (see the comment at `$saveAndVariants` in `createComponentEditForm()`). Shares the save logic with `saveProductForm()` via `persistProduct()` and on success also navigates to the edit (the right column switches from the gate button to the variant list).
private
saveProductAndManageVariants(SubmitButton $button) : void
The button is .ajax + data-naja-force-redirect: Nette redirect() sends a {redirect} payload and
Naja does a hard redirect (window.location.assign), so the edit loads fully and the URL is rewritten
correctly (a soft client-side fetch would fail between the add and edit layouts).
IMPORTANT: backKey is carried over (as BasePresenter::createForm does for "apply"); otherwise the
edit generates a new key from the Referer, i.e. the add page, and "Save"/"Cancel" on the edit would
return to the add page instead of the original one.
Parameters
- $button : SubmitButton
saveProductForm()
private
saveProductForm(ArrayHash<string|int, mixed> $values) : bool
Parameters
- $values : ArrayHash<string|int, mixed>
Return values
boolsetProductFormDefaults()
private
setProductFormDefaults(Form $form) : void
Parameters
- $form : Form