32 private static $allowEvents = 0;
34 private static $handlerList = [];
36 private static $whiteList = [];
38 private static $entityClass = [
39 self::ENTITY_PRODUCT =>
'\Bitrix\Catalog\Model\Product',
40 self::ENTITY_PRICE =>
'\Bitrix\Catalog\Model\Price'
54 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
55 'catalog', __CLASS__,
'handlerProductOnBeforeAdd'
58 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
59 'catalog', __CLASS__,
'handlerProductOnAfterAdd'
63 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
64 'catalog', __CLASS__,
'handlerProductOnBeforeUpdate'
67 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
68 'catalog', __CLASS__,
'handlerProductOnAfterUpdate'
72 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
73 'catalog', __CLASS__,
'handlerPriceOnBeforeAdd'
76 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
77 'catalog', __CLASS__,
'handlerPriceOnAfterAdd'
81 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
82 'catalog', __CLASS__,
'handlerPriceOnBeforeUpdate'
85 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
86 'catalog', __CLASS__,
'handlerPriceOnAfterUpdate'
90 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_DELETE,
91 'catalog', __CLASS__,
'handlerPriceOnBeforeDelete'
94 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_DELETE,
95 'catalog', __CLASS__,
'handlerPriceOnAfterDelete'
106 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
107 'catalog', __CLASS__,
'handlerProductOnBeforeAdd'
110 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
111 'catalog', __CLASS__,
'handlerProductOnAfterAdd'
115 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
116 'catalog', __CLASS__,
'handlerProductOnBeforeUpdate'
119 'catalog',
'Bitrix\Catalog\Model\Product::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
120 'catalog', __CLASS__,
'handlerProductOnAfterUpdate'
124 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
125 'catalog', __CLASS__,
'handlerPriceOnBeforeAdd'
128 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
129 'catalog', __CLASS__,
'handlerPriceOnAfterAdd'
133 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
134 'catalog', __CLASS__,
'handlerPriceOnBeforeUpdate'
137 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
138 'catalog', __CLASS__,
'handlerPriceOnAfterUpdate'
142 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_BEFORE_DELETE,
143 'catalog', __CLASS__,
'handlerPriceOnBeforeDelete'
146 'catalog',
'Bitrix\Catalog\Model\Price::'.
Main\
Entity\DataManager::EVENT_ON_AFTER_DELETE,
147 'catalog', __CLASS__,
'handlerPriceOnAfterDelete'
155 return self::handlerOnBeforeAdd(
$event, self::ENTITY_PRODUCT, self::EVENT_ON_BEFORE_PRODUCT_ADD);
161 if (!self::allowedEvents())
168 self::disableEvents();
170 $handlerList = array_merge(
171 self::getHandlerList(
'catalog', self::EVENT_ON_PRODUCT_ADD),
172 self::getHandlerList(
'sale', self::EVENT_ON_PRODUCT_ADD)
174 if (!empty($handlerList))
177 $event->getParameter(
'id'),
178 $event->getParameter(
'fields') +
$event->getParameter(
'external_fields')
181 foreach ($handlerList as $handler)
185 unset($handler,
$data);
189 self::enableEvents();
196 return self::handlerOnBeforeUpdate(
$event, self::ENTITY_PRODUCT, self::EVENT_ON_BEFORE_PRODUCT_UPDATE);
201 return self::handlerOnAfterModify(
$event, self::EVENT_ON_PRODUCT_UPDATE);
207 if (!self::allowedEvents())
210 self::disableEvents();
212 $handlerList = self::getHandlerList(
'catalog', self::EVENT_ON_BEFORE_PRICE_ADD);
214 if (!empty($handlerList))
218 $externalFields =
$event->getParameter(
'external_fields');
220 $oldExternalFields = $externalFields;
221 $actions =
$event->getParameter(
'actions');
222 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
224 foreach ($handlerList as $handler)
241 if (isset($actions[
'OLD_RECOUNT']))
242 $result->unsetActions([
'OLD_RECOUNT']);
245 self::fillResultData(
$result, self::ENTITY_PRICE, $oldFields, $oldExternalFields,
$fields);
246 unset($actions, $oldExternalFields, $oldFields, $externalFields,
$fields);
249 self::setHandlerError(
$result, self::EVENT_ON_BEFORE_PRICE_ADD);
253 self::enableEvents();
261 if (!self::allowedEvents())
268 self::disableEvents();
270 $handlerList = array_merge(
271 self::getHandlerList(
'catalog', self::EVENT_ON_PRICE_ADD),
272 self::getHandlerList(
'sale', self::EVENT_ON_PRICE_ADD)
274 if (!empty($handlerList))
277 $actions =
$event->getParameter(
'actions');
278 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
280 $event->getParameter(
'id'),
285 foreach ($handlerList as $handler)
289 unset($handler,
$data);
293 self::enableEvents();
301 if (!self::allowedEvents())
304 self::disableEvents();
306 $handlerList = self::getHandlerList(
'catalog', self::EVENT_ON_BEFORE_PRICE_UPDATE);
307 if (!empty($handlerList))
310 $id =
$event->getParameter(
'id');
312 $externalFields =
$event->getParameter(
'external_fields');
314 $oldExternalFields = $externalFields;
315 $actions =
$event->getParameter(
'actions');
316 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
318 foreach ($handlerList as $handler)
335 if (isset($actions[
'OLD_RECOUNT']))
336 $result->unsetActions([
'OLD_RECOUNT']);
339 self::fillResultData(
$result, self::ENTITY_PRICE, $oldFields, $oldExternalFields,
$fields);
340 unset($actions, $oldExternalFields, $oldFields, $externalFields,
$fields);
343 self::setHandlerError(
$result, self::EVENT_ON_BEFORE_PRICE_UPDATE);
348 self::enableEvents();
355 return self::handlerPriceOnAfterModify(
$event, self::EVENT_ON_PRICE_UPDATE);
360 return self::handlerOnBeforeDelete(
$event, self::EVENT_ON_BEFORE_PRICE_DELETE);
365 return self::handlerOnAfterDelete(
$event, self::EVENT_ON_PRICE_DELETE);
373 private static function enableEvents()
375 self::$allowEvents++;
383 private static function disableEvents()
385 self::$allowEvents--;
393 private static function allowedEvents()
395 return (self::$allowEvents >= 0);
398 private static function getHandlerList($module,
$event)
400 $eventIndex = $module.
':'.
$event;
401 if (!isset(self::$handlerList[$eventIndex]))
403 self::$handlerList[$eventIndex] = [];
408 foreach (array_keys(
$result) as $index)
410 $result[$index][
'FROM_MODULE_ID'] =
'catalog';
414 self::$handlerList[$eventIndex] =
$result;
418 return self::$handlerList[$eventIndex];
421 private static function handlerOnBeforeAdd(Catalog\Model\Event
$event,
$entity, $eventName)
423 $result =
new Catalog\Model\EventResult();
424 if (!self::allowedEvents())
427 self::disableEvents();
429 $handlerList = self::getHandlerList(
'catalog', $eventName);
430 if (!empty($handlerList))
434 $externalFields =
$event->getParameter(
'external_fields');
436 $oldExternalFields = $externalFields;
437 if (!empty($externalFields))
440 foreach ($handlerList as $handler)
451 unset($oldExternalFields, $oldFields, $externalFields,
$fields);
454 self::setHandlerError(
$result, $eventName);
458 self::enableEvents();
463 private static function handlerOnAfterModify(Catalog\Model\Event
$event, $eventName)
465 $result =
new Catalog\Model\EventResult();
466 if (!self::allowedEvents())
473 self::disableEvents();
475 $handlerList = self::getHandlerList(
'catalog', $eventName);
476 if (!empty($handlerList))
479 $event->getParameter(
'id'),
480 $event->getParameter(
'fields') +
$event->getParameter(
'external_fields')
483 foreach ($handlerList as $handler)
487 unset($handler,
$data);
491 self::enableEvents();
496 private static function handlerOnBeforeUpdate(Catalog\Model\Event
$event,
$entity, $eventName)
498 $result =
new Catalog\Model\EventResult();
499 if (!self::allowedEvents())
502 self::disableEvents();
504 $handlerList = self::getHandlerList(
'catalog', $eventName);
505 if (!empty($handlerList))
508 $id =
$event->getParameter(
'id');
510 $externalFields =
$event->getParameter(
'external_fields');
512 $oldExternalFields = $externalFields;
513 if (!empty($externalFields))
516 foreach ($handlerList as $handler)
527 unset($oldExternalFields, $oldFields, $externalFields,
$fields);
530 self::setHandlerError(
$result, $eventName);
535 self::enableEvents();
540 private static function handlerOnBeforeDelete(Catalog\Model\Event
$event, $eventName)
542 $result =
new Catalog\Model\EventResult();
543 if (!self::allowedEvents())
546 self::disableEvents();
548 $handlerList = self::getHandlerList(
'catalog', $eventName);
549 if (!empty($handlerList))
552 $id =
$event->getParameter(
'id');
554 foreach ($handlerList as $handler)
565 self::setHandlerError(
$result, $eventName);
569 self::enableEvents();
574 private static function handlerOnAfterDelete(Catalog\Model\Event
$event, $eventName)
576 $result =
new Catalog\Model\EventResult();
577 if (!self::allowedEvents())
584 self::disableEvents();
586 $handlerList = self::getHandlerList(
'catalog', $eventName);
587 if (!empty($handlerList))
590 $event->getParameter(
'id')
593 foreach ($handlerList as $handler)
597 unset($handler,
$data);
601 self::enableEvents();
606 private static function handlerPriceOnAfterModify(Catalog\Model\Event
$event, $eventName)
608 $result =
new Catalog\Model\EventResult();
609 if (!self::allowedEvents())
616 self::disableEvents();
618 $handlerList = self::getHandlerList(
'catalog', $eventName);
619 if (!empty($handlerList))
622 $actions =
$event->getParameter(
'actions');
623 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
625 $event->getParameter(
'id'),
630 foreach ($handlerList as $handler)
634 unset($handler,
$data);
638 self::enableEvents();
643 private static function setHandlerError(Catalog\Model\EventResult
$result, $eventName)
648 if (is_object($oldException))
650 $result->addError(
new Main\Entity\EntityError(
651 $oldException->GetString()
656 $result->addError(
new Main\Entity\EntityError(
658 'BX_CATALOG_EVENT_COMPATIBILITY_ERR_UNKNOWN',
659 [
'#EVENT#' => $eventName]
663 unset($oldException);
666 private static function fillResultData(
667 Catalog\Model\EventResult
$result,
670 array $externalFields,
676 $unsetExternalFields = [];
677 $modifyExternalFields = [];
679 if (!isset(self::$entityClass[
$entity]))
683 if (!isset(self::$whiteList[
$entity]))
686 $className = self::$entityClass[
$entity];
687 $list = $className::getTabletFieldNames(Catalog\Model\Entity::FIELDS_ALL);
688 self::$whiteList[
$entity] = (!empty($list)
689 ? array_fill_keys($list,
true)
693 if (empty(self::$whiteList[
$entity]))
698 $handlerExternalFields = array_diff_key($handlerFields, self::$whiteList[
$entity]);
699 if (!empty($handlerExternalFields))
700 $handlerFields = array_intersect_key($handlerFields, self::$whiteList[
$entity]);
704 if (!array_key_exists(
$key, $handlerFields))
706 $unsetFields[] =
$key;
710 if (!is_array($value))
712 if ($value !== $handlerFields[
$key])
713 $modifyFields[
$key] = $handlerFields[
$key];
715 unset($handlerFields[
$key]);
718 if (!empty($handlerFields))
719 $modifyFields = $modifyFields + $handlerFields;
721 foreach ($externalFields as
$key => $value)
723 if (!array_key_exists(
$key, $handlerExternalFields))
725 $unsetExternalFields[] =
$key;
730 if (!is_array($value))
732 if ($value !== $handlerExternalFields[
$key])
733 $modifyExternalFields[
$key] = $handlerExternalFields[
$key];
735 unset($handlerExternalFields[
$key]);
738 if (!empty($handlerExternalFields))
739 $modifyExternalFields = $modifyExternalFields + $handlerExternalFields;
741 if (!empty($unsetFields))
742 $result->unsetFields($unsetFields);
743 if (!empty($modifyFields))
744 $result->modifyFields($modifyFields);
745 if (!empty($unsetExternalFields))
746 $result->unsetExternalFields($unsetExternalFields);
747 if (!empty($modifyExternalFields))
748 $result->modifyExternalFields($modifyExternalFields);
749 unset($modifyFields, $unsetFields);