Надеялся, что никогда не увижу Битрикс вновь, но, как это обычно бывает, мне снова пришлось ковырять «любимую» CMS.
Задача вполне типичная возникла, клиент хотел получать на почту сообщения о новых отзывах, дабы своевременно удалять нелицеприятные и откровенно похабные тексты. Сказано — сделано. Для решения этой задачи нужно:
- cоздать почтовое событие и почтовый шаблон
- повесить обработчик на событие модуля форума «onAfterMessageAdd»
Тут, вероятно, требуется небольшое пояснение. Компонент forum.topic.reviews — именно этот компонент отвечает за отзывы на товар, использует для хранения отзывов форум, специально отведенную ветку на форуме. Каждый раз, когда кто-то добавляет новый отзыв на товар, создается новая тема на форуме(если такой еще нет), и в нее добавляется сообщение. Именно поэтому нам нужно событие «onAfterMessageAdd(Добавление нового сообщения на форум)»,
а там уже в самом обработчике можно определить, относится ли это сообщение к товару, или обычное сообщение на форуме.
Обработчик события onAfterMessageAdd
Мой обработчик получился примерно такой:
[php]
function notifyNewItemFeedback($ID, $arFields){
ob_start();
$res = CIBlockElement::GetList(
array(),
array(
‘IBLOCK_ID’ => %id_инфоблока_каталога%,
‘PROPERTY_FORUM_TOPIC_ID’ => $arFields[«TOPIC_ID»]
),
false,
false,
array(‘*’, ‘IBLOCK_ID’, ‘ID’, ‘NAME’, ‘PROPERTY_FORUM_TOPIC_ID’, ‘SECTION_ID’, ‘SECTION’, ‘SECTIONS’)
);
if($ar_res = $res->GetNext()){
var_dump(date(‘d.m.Y H:i:s’));
echo ‘найден товар ‘.$ar_res[‘NAME’];
$TYPE_MAIL_EVENT = ‘NEW_ITEM_REVIEW’;
var_dump($ar_res);
$arMail = array(
‘ITEM_NAME’ => $ar_res[‘NAME’],
‘AUTHOR_NAME’ => $arFields[‘AUTHOR_NAME’],
‘POST_DATE’ => date(‘d.m.Y H:i:s’),
‘POST_MESSAGE’ => $arFields[‘POST_MESSAGE’],
‘PATH2ITEM’ => ‘/catalog/’ . $ar_res[‘IBLOCK_SECTION_ID’] . ‘/’ . $ar_res[‘ID’],
);
var_dump($arMail);
$ID_MAIL_EVENT = %id_почтового_события%;
$ok = CEvent::Send($TYPE_MAIL_EVENT, «s1», $arMail, $ID_MAIL_EVENT);
if ($ok){
echo ‘Сообщение отправлено’;
}
else{
‘Сообщение не отправлено ‘.$ok;
}
}
else
echo ‘Элемент не найден.’;
$dump = ob_get_clean();
if (!empty($ok)){
return true;
}
else{
$filename = dirname(__FILE__).’/dump.txt’;
if (!file_exists($filename)){
$f = fopen($filename, ‘w+’);
fclose($f);
}
file_put_contents($filename, $dump);
}
}
AddEventHandler(«forum», «onAfterMessageAdd», «notifyNewItemFeedback»);
[/php]
Внимательные читатель заметил, что в обработчике используется переменная %id_почтового_события%, которая, пока, неясно откуда берется. В Битриксе есть свой механизм отправки сообщений, в нем присутствуют сущности двух видов — почтовые события и почтовые шаблоны.
Если с шаблоном более-менее понятно, то с событием понятно не все. Почтовое событие вызывается программно в коде. Событие строго типизировано, событие требует строго определенный набор параметров, которые описывают это событие, эти параметры определяются типом почтового события. Когда событие вызвано, обработчик почты рассылает шаблонные сообщения, привязанные к его типу. Текст сообщения генерируется на основе параметров типа события и самого шаблона.
Создадим почтовое событие
Настройки->Почтовые события->Типы почтовых событий->Добавить тип
Тип: «NEW_ITEM_REVIEW»
Там же посмотрите ID этого события, оно вам нужно.
Создадим почтовый шаблон
Настройки->Почтовые события->Почтовые шаблоны->Добавить шаблон
Всё на вместе и должно работать. Думаю, большинство задач в Битриксе решаются также просто, но, к сожалению, сделать просто бывает сложней чем сделать сложно.
А в какой файл надо добавить функцию function notifyNewItemFeedback(… ?
В файл /www/shop/bitrix/php_interface/init.php
Если нет файла то нада создать.
Заменил %id_инфоблока_каталога% и %id_почтового_события% на свои значения
Добавил в init.php, ни админка ни сайт после этого не грузится
‘IBLOCK_ID’ => %id_инфоблока_каталога%,
‘IBLOCK_ID’ => 3,
давайте скайп может помогу разобраться
Хорошее решение, но почему-то не работает при добавлении первого комментария к товару (то есть при создании новой темы форума).
А если для этого случая добавить ту же функцию под onAfterTopicAdd, работает некорректно — не отображает, к какому товару добавили отзыв почему-то. То есть уведомление есть, но где отзыв оставлен, непонятно.
Да, при добавлении первого отзыва ничего не приходит. Можно ли это как-то исправить?
Используйте поправку:
…
‘IBLOCK_ID’ => GetMainBlockId(),
//’PROPERTY_FORUM_TOPIC_ID’ => $arFields[«TOPIC_ID»]
‘ID’ => $arFields[‘MESSAGE_INFO’][‘PARAM2’]
…
т.е. ищите не по коду темы форума, а напрямую по коду элемента в массиве $arFields[‘MESSAGE_INFO’][‘PARAM2’]
Все просто и понятно. спасибо.