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'
51 $eventManager = Main\EventManager::getInstance();
53 $eventManager->registerEventHandler(
54 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
55 'catalog', __CLASS__,
'handlerProductOnBeforeAdd'
57 $eventManager->registerEventHandler(
58 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
59 'catalog', __CLASS__,
'handlerProductOnAfterAdd'
62 $eventManager->registerEventHandler(
63 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
64 'catalog', __CLASS__,
'handlerProductOnBeforeUpdate'
66 $eventManager->registerEventHandler(
67 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
68 'catalog', __CLASS__,
'handlerProductOnAfterUpdate'
71 $eventManager->registerEventHandler(
72 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
73 'catalog', __CLASS__,
'handlerPriceOnBeforeAdd'
75 $eventManager->registerEventHandler(
76 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
77 'catalog', __CLASS__,
'handlerPriceOnAfterAdd'
80 $eventManager->registerEventHandler(
81 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
82 'catalog', __CLASS__,
'handlerPriceOnBeforeUpdate'
84 $eventManager->registerEventHandler(
85 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
86 'catalog', __CLASS__,
'handlerPriceOnAfterUpdate'
89 $eventManager->registerEventHandler(
90 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_DELETE,
91 'catalog', __CLASS__,
'handlerPriceOnBeforeDelete'
93 $eventManager->registerEventHandler(
94 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_DELETE,
95 'catalog', __CLASS__,
'handlerPriceOnAfterDelete'
103 $eventManager = Main\EventManager::getInstance();
105 $eventManager->unRegisterEventHandler(
106 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
107 'catalog', __CLASS__,
'handlerProductOnBeforeAdd'
109 $eventManager->unRegisterEventHandler(
110 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
111 'catalog', __CLASS__,
'handlerProductOnAfterAdd'
114 $eventManager->unRegisterEventHandler(
115 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
116 'catalog', __CLASS__,
'handlerProductOnBeforeUpdate'
118 $eventManager->unRegisterEventHandler(
119 'catalog',
'Bitrix\Catalog\Model\Product::'.Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
120 'catalog', __CLASS__,
'handlerProductOnAfterUpdate'
123 $eventManager->unRegisterEventHandler(
124 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_ADD,
125 'catalog', __CLASS__,
'handlerPriceOnBeforeAdd'
127 $eventManager->unRegisterEventHandler(
128 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_ADD,
129 'catalog', __CLASS__,
'handlerPriceOnAfterAdd'
132 $eventManager->unRegisterEventHandler(
133 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_UPDATE,
134 'catalog', __CLASS__,
'handlerPriceOnBeforeUpdate'
136 $eventManager->unRegisterEventHandler(
137 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_UPDATE,
138 'catalog', __CLASS__,
'handlerPriceOnAfterUpdate'
141 $eventManager->unRegisterEventHandler(
142 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_BEFORE_DELETE,
143 'catalog', __CLASS__,
'handlerPriceOnBeforeDelete'
145 $eventManager->unRegisterEventHandler(
146 'catalog',
'Bitrix\Catalog\Model\Price::'.Main\
Entity\DataManager::EVENT_ON_AFTER_DELETE,
147 'catalog', __CLASS__,
'handlerPriceOnAfterDelete'
150 unset($eventManager);
155 return self::handlerOnBeforeAdd($event, self::ENTITY_PRODUCT, self::EVENT_ON_BEFORE_PRODUCT_ADD);
161 if (!self::allowedEvents())
164 $success = $event->getParameter(
'success');
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)
183 ExecuteModuleEventEx($handler, $data);
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))
217 $fields = $event->getParameter(
'fields');
218 $externalFields = $event->getParameter(
'external_fields');
219 $oldFields = $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)
226 if (ExecuteModuleEventEx($handler, [&$fields]) ===
false)
234 if (isset($fields[
'RECALL']))
236 $result->modifyActions([
'OLD_RECOUNT' => $fields[
'RECALL']]);
237 unset($fields[
'RECALL']);
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())
264 $success = $event->getParameter(
'success');
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))
276 $fields = $event->getParameter(
'fields');
277 $actions = $event->getParameter(
'actions');
278 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
280 $event->getParameter(
'id'),
281 $fields + $event->getParameter(
'external_fields')
283 unset($actions, $fields);
285 foreach ($handlerList as $handler)
287 ExecuteModuleEventEx($handler, $data);
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');
311 $fields = $event->getParameter(
'fields');
312 $externalFields = $event->getParameter(
'external_fields');
313 $oldFields = $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)
320 if (ExecuteModuleEventEx($handler, [$id, &$fields]) ===
false)
328 if (isset($fields[
'RECALL']))
330 $result->modifyActions([
'OLD_RECOUNT' => $fields[
'RECALL']]);
331 unset($fields[
'RECALL']);
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] = [];
404 $eventManager = Main\EventManager::getInstance();
405 $result = $eventManager->findEventHandlers($module, $event);
408 foreach (array_keys($result) as $index)
410 $result[$index][
'FROM_MODULE_ID'] =
'catalog';
411 $result[$index][
'MESSAGE_ID'] = $event;
414 self::$handlerList[$eventIndex] = $result;
416 unset($result, $eventManager);
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))
433 $fields = $event->getParameter(
'fields');
434 $externalFields = $event->getParameter(
'external_fields');
435 $oldFields = $fields;
436 $oldExternalFields = $externalFields;
437 if (!empty($externalFields))
438 $fields = $fields + $externalFields;
440 foreach ($handlerList as $handler)
442 if (ExecuteModuleEventEx($handler, [&$fields]) ===
false)
450 self::fillResultData($result, $entity, $oldFields, $oldExternalFields, $fields);
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())
469 $success = $event->getParameter(
'success');
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)
485 ExecuteModuleEventEx($handler, $data);
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');
509 $fields = $event->getParameter(
'fields');
510 $externalFields = $event->getParameter(
'external_fields');
511 $oldFields = $fields;
512 $oldExternalFields = $externalFields;
513 if (!empty($externalFields))
514 $fields = $fields + $externalFields;
516 foreach ($handlerList as $handler)
518 if (ExecuteModuleEventEx($handler, [$id, &$fields]) ===
false)
526 self::fillResultData($result, $entity, $oldFields, $oldExternalFields, $fields);
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)
556 if (ExecuteModuleEventEx($handler, [$id]) ===
false)
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())
580 $success = $event->getParameter(
'success');
584 self::disableEvents();
586 $handlerList = self::getHandlerList(
'catalog', $eventName);
587 if (!empty($handlerList))
590 $event->getParameter(
'id')
593 foreach ($handlerList as $handler)
595 ExecuteModuleEventEx($handler, $data);
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())
612 $success = $event->getParameter(
'success');
616 self::disableEvents();
618 $handlerList = self::getHandlerList(
'catalog', $eventName);
619 if (!empty($handlerList))
621 $fields = $event->getParameter(
'fields');
622 $actions = $event->getParameter(
'actions');
623 $fields[
'RECALL'] = (isset($actions[
'OLD_RECOUNT']) && $actions[
'OLD_RECOUNT'] ===
true);
625 $event->getParameter(
'id'),
626 $fields + $event->getParameter(
'external_fields')
628 unset($actions, $fields);
630 foreach ($handlerList as $handler)
632 ExecuteModuleEventEx($handler, $data);
634 unset($handler, $data);
638 self::enableEvents();
643 private static function setHandlerError(Catalog\Model\EventResult $result, $eventName)
647 $oldException = $APPLICATION->GetException();
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]);
702 foreach ($fields as $key => $value)
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);