В предыдущей заметке Объекты сущностей инфоблоков был упомянут менеджер событий, позволяющий реализовывать код обработчиков в классах сущностей. Приведу здесь реализацию.
Для работы менеджера необходимо использовать следующий формат имен классов сущностей: PrefixIblockCodeElement и PrefixIblockCodeSection. Таким образом, используя префикс My - для инфоблока с кодом Company класс элемента будет MyCompanyElement, раздела MyCompanySection.
Сам класс менеджера:
<?php
class ObjEventManager {
static $iblocks;
private $cache_id;
private $cache_dir;
private $ttl = 3600;
public function __construct() {
// кешированный список инфоблоков $this->iblocks
$this->cache_id = 'my_iblock';
$this->cache_dir = '/my_iblock';
$cache = new CPHPCache();
if ($cache->InitCache($this->ttl, $this->cache_id, $this->cache_dir)) {
self::$iblocks = $cache->GetVars();
} elseif (CModule::IncludeModule("iblock") && $cache->StartDataCache()) {
$res = CIBlock::GetList(array(), array('CHECK_PERMISSIONS' => 'N'), false);
while($iblock = $res->Fetch()) {
self::$iblocks[$iblock['ID']] = $iblock;
}
if(count(self::$iblocks) > 0) {
$cache->EndDataCache(self::$iblocks);
} else {
$cache->AbortDataCache();
}
} else {
$this->iblocks = array();
}
// регистрируем все события инфоблоков
foreach(get_class_methods(get_class($this)) as $method) {
// если метод начинается на On
if(strpos($method, 'On') === 0) {
AddEventHandler("iblock", $method, Array(get_class($this), $method));
}
}
}
private static function getClassMethod($iblock_id, $element_type, $method) {
$class_method = false;
if(is_array(self::$iblocks) && array_key_exists($iblock_id, self::$iblocks)) {
$class_prefix = defined('OBJ_IBLOCK_PREFIX') ? OBJ_IBLOCK_PREFIX : '';
$class_name = $class_prefix . ucfirst(self::$iblocks[$iblock_id]['CODE']) . $element_type;
if(class_exists($class_name) && method_exists($class_name, $method)) {
$class_method = array($class_name, $method);
}
}
return $class_method;
}
/********************************************* ELEMENTS *************************************************/
public static function OnBeforeIBlockElementAdd(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnBeforeIBlockElementAdd');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnStartIBlockElementAdd(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnStartIBlockElementAdd');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnAfterIBlockElementAdd(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnAfterIBlockElementAdd');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnBeforeIBlockElementUpdate(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnBeforeIBlockElementUpdate');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnStartIBlockElementUpdate(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnStartIBlockElementUpdate');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnAfterIBlockElementUpdate(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Element', 'OnAfterIBlockElementUpdate');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnBeforeIBlockElementDelete($ID) {
}
public static function OnAfterIBlockElementDelete($ID) {
}
public static function OnIBlockElementDelete($ID) {
}
public static function OnAfterIBlockElementSetPropertyValues($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $PROPERTY_CODE) {
$method = self::getClassMethod($IBLOCK_ID, 'Element', 'OnAfterIBlockElementSetPropertyValues');
if($method) return call_user_func_array($method, array($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $PROPERTY_CODE));
}
public static function OnAfterIBlockElementSetPropertyValuesEx($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $FLAGS) {
$method = self::getClassMethod($IBLOCK_ID, 'Element', 'OnAfterIBlockElementSetPropertyValuesEx');
if($method) return call_user_func_array($method, array($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $FLAGS));
}
/********************************************* SECTIONS *************************************************/
public static function OnBeforeIBlockSectionAdd(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Section', 'OnBeforeIBlockSectionAdd');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnAfterIBlockSectionAdd(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Section', 'OnAfterIBlockSectionAdd');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnBeforeIBlockSectionUpdate(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Section', 'OnBeforeIBlockSectionUpdate');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnAfterIBlockSectionUpdate(&$arFields) {
$method = self::getClassMethod($arFields['IBLOCK_ID'], 'Section', 'OnAfterIBlockSectionUpdate');
if($method) return call_user_func_array($method, array($arFields));
}
public static function OnBeforeIBlockSectionDelete($ID) {
}
public static function OnAfterIBlockSectionDelete($ID) {
}
}
Для его подключения в init.php должен быть объявлен префикс и создан объект:
define('OBJ_IBLOCK_PREFIX', 'My');
new ObjEventManager();
Не реализованы вызовы для событий удаления, но их можно дописать в соответствии с потребностями конкретного проекта.
Пример использования - создание обработчика, сбрасывающего кеш при OnAfterIBlockElementSetPropertyValuesEx
<?php
class MyCompanyElement extends ObjElement {
static $iblock_id = 3;
public static function OnAfterIBlockElementSetPropertyValuesEx($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $FLAGS) {
global $CACHE_MANAGER;
$CACHE_MANAGER->ClearByTag("iblock_id_" . $IBLOCK_ID);
}
}
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».