CoolCMS API

ProductHardDeleteManager
in package

Hard-deletes a product or a single variant: builds the plan, checks the gates and cleans up related data.

Called by ProductManager (buildPlan()) and ProductVariantManager (buildVariantPlan(), the product stays) from the DeleteTrait::delete() hooks, inside the delete transaction.

Contract:

  • a product's variants are deleted with it;
  • a product set is deleted (with its images and threads) only when it would be left empty after the deleted variants are removed (EmptiedSetResolver); a set with other content stays and only loses the item;
  • IMPORTANT: history is never deleted. A set, variant or stock item referenced by an order, complaint or gift makes the deletion refuse, because the FK of those references is SET NULL and the history would silently lose its link. Soft delete remains available. Invoices are not affected: they keep a code and name snapshot and reference neither the product, variant nor set;
  • carts are cleaned up (cart_items has no FK).

Everything runs as raw DBAL in the same transaction as the product delete, with no find() (every Api read does UoW::clear()).

Table of Contents

Constants

CART_ITEMS_TABLE  : string = 'cms_mod_eshop_cart_items'
EXTERNAL_MODULE_ESHOP  : int = 4
The eshop module in `cms_system_modules`, used by the variant to stock item mirror ({@see ProductVariantManager}).
HANDLED_REFERENCES  : array<string|int, mixed> = ['cms_mod_eshop_product_sets.cms_mod_eshop_prod...
References to a product, variant or set with a rule other than `CASCADE` that this manager handles (`table.column`). Any other such reference makes the deletion refuse before anything is written.
PRODUCTS_TABLE  : string = 'cms_mod_eshop_products'
SET_IMAGES_TABLE  : string = 'cms_mod_eshop_product_set_image_relations'
SET_ITEMS_TABLE  : string = 'cms_mod_eshop_set_item_relations'
SETS_TABLE  : string = 'cms_mod_eshop_product_sets'
STOCK_ITEMS_TABLE  : string = 'cms_mod_store_stock_items'
VARIANTS_TABLE  : string = 'cms_mod_eshop_product_variants'

Properties

$em  : EntityManagerInterface
$emptiedSetResolver  : EmptiedSetResolver
$productSetManager  : ProductSetManager
$unitOfWorkReset  : UnitOfWorkReset

Methods

__construct()  : mixed
apply()  : Result|null
Writes before the product row is deleted, inside the delete transaction.
buildPlan()  : ProductHardDeletePlan
Builds the plan for deleting products; all their variants are deleted too.
buildVariantPlan()  : ProductHardDeletePlan
Builds the plan for deleting single variants: the product stays, the variant's sale card and any bundles left empty by it are deleted. `productIds` is empty, so {@see apply()} does not detach the product from its other sets.
findBlockers()  : array<int, string>
Returns the reasons why the product cannot be hard-deleted (empty list = it can). Writes nothing.
findUncoveredReferences()  : array<int, string>
Returns references to a product, variant or set that do not cascade on delete and are unknown to this manager.
reindexSearch()  : void
Best-effort after commit: removes the deleted sets from the search index and reindexes the surviving ones.
releaseStockItemMirror()  : void
Clears the variant to stock item mirror on stock items that pointed to a deleted variant.
collect()  : void
discardDeletedSets()  : void
Detaches the sets just deleted by SQL that are still managed (loaded earlier in the same unit of work). Their rows are gone, but the instance keeps its ManyToOne references to the comment and rating threads; once a thread manager removes and flushes one thread, the next flush would find the reference as a new entity and fail ("ProductSet#commentThread"). Today the read `UoW::clear()` in the thread manager's `find()` hides that; without it the set must go explicitly.
findParentBundles()  : array<int, array<int, int>>
planFor()  : ProductHardDeletePlan
Builds the shared core of the plan: sets to delete, bundles that only lose an item, and what belongs to the deleted sets.
toInt()  : int
toInts()  : array<int, int>
toStr()  : string
variantsWithStockItems()  : array{0: list, 1: list}
Returns the variants matching the condition (a single `IN (?)` parameter) and their stock items.

Constants

EXTERNAL_MODULE_ESHOP

The eshop module in `cms_system_modules`, used by the variant to stock item mirror ({@see ProductVariantManager}).

private int EXTERNAL_MODULE_ESHOP = 4

HANDLED_REFERENCES

References to a product, variant or set with a rule other than `CASCADE` that this manager handles (`table.column`). Any other such reference makes the deletion refuse before anything is written.

private array<string|int, mixed> HANDLED_REFERENCES = ['cms_mod_eshop_product_sets.cms_mod_eshop_product_variants_product_variant_id', 'cms_mod_eshop_order_items.cms_mod_eshop_product_sets_product_set_id', 'cms_mod_eshop_complaint_items.cms_mod_eshop_product_sets_product_set_id', 'cms_mod_eshop_gifts.cms_mod_eshop_product_sets_product_set_id']

Properties

Methods

buildVariantPlan()

Builds the plan for deleting single variants: the product stays, the variant's sale card and any bundles left empty by it are deleted. `productIds` is empty, so {@see apply()} does not detach the product from its other sets.

public buildVariantPlan(array<int, int> $variantIds) : ProductHardDeletePlan
Parameters
$variantIds : array<int, int>
Return values
ProductHardDeletePlan

findUncoveredReferences()

Returns references to a product, variant or set that do not cascade on delete and are unknown to this manager.

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

collect()

private collect(array<int, int> &$bucket, mixed $value) : void
Parameters
$bucket : array<int, int>
$value : mixed

discardDeletedSets()

Detaches the sets just deleted by SQL that are still managed (loaded earlier in the same unit of work). Their rows are gone, but the instance keeps its ManyToOne references to the comment and rating threads; once a thread manager removes and flushes one thread, the next flush would find the reference as a new entity and fail ("ProductSet#commentThread"). Today the read `UoW::clear()` in the thread manager's `find()` hides that; without it the set must go explicitly.

private discardDeletedSets(array<int, int> $setIds) : void

A set not in the identity map costs only the lookup.

Parameters
$setIds : array<int, int>

findParentBundles()

private findParentBundles(array<int, int> $setIds) : array<int, array<int, int>>
Parameters
$setIds : array<int, int>
Return values
array<int, array<int, int>> —

bundle id mapped to all of its items

planFor()

Builds the shared core of the plan: sets to delete, bundles that only lose an item, and what belongs to the deleted sets.

private planFor(array<int, int> $productIds, array<int, int> $variantIds, array<int, int> $stockItemIds, array<int, int> $leafSetIds) : ProductHardDeletePlan
Parameters
$productIds : array<int, int>
$variantIds : array<int, int>
$stockItemIds : array<int, int>
$leafSetIds : array<int, int>
Return values
ProductHardDeletePlan

toInts()

private toInts(array<int, mixed> $values) : array<int, int>
Parameters
$values : array<int, mixed>
Return values
array<int, int>

variantsWithStockItems()

Returns the variants matching the condition (a single `IN (?)` parameter) and their stock items.

private variantsWithStockItems(string $where, array<int, int> $ids) : array{0: list, 1: list}
Parameters
$where : string
$ids : array<int, int>
Return values
array{0: list, 1: list}
On this page

Search results