Как создать свой триггер

Урок 222 из 362
Автор: Александр Суворов
Сложность урока:
4 уровень - сложно, требуется сосредоточится, внимание деталям и точному следованию инструкции.
4 из 5
Просмотров: 4887
Ограничения по редакциям: Старт

Пошаговое создание триггера

  • Простейший триггер
  • Получение данных события
  • Форма настройки триггера
  • Фильтрация в триггере
  • Свои поля персонализации
  • Фильтрация по сайту

  • Примечание:
    1. Все примеры упакованы в архив.
    2. Распакуйте его, затем папку sender скопируйте в /bitrix/php_interface/.
    3. Далее в init.php подключите пример:
      include_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/php_interface/sender/handlers.php");
      


    Простейший триггер

    Создадим простейший триггер:

    1. Для начала выберем одно из событий Перечень событий модуля блогов приведен в специальной главе документации для разработчиков. , к примеру в блоге добавление комментария OnCommentAdd.
    2. Теперь создадим класс SenderTriggerBlogComment, который обязательно наследуется от класса \Bitrix\Sender\Trigger.
      <?
      
      class SenderTriggerBlogComment extends \Bitrix\Sender\Trigger
      {
         public function getName()
         {
            return 'Добавлен комментарий';
         }
      
         public function getCode()
         {
            return "my_blog_comment";
         }
      
         public function getEventModuleId()
         {
            return 'blog';
         }
      
         public function getEventType()
         {
            return "OnCommentAdd";
         }
         
         public function getRecipient()
         {
            return array(
               'NAME' => 'Иван',
               'EMAIL' => 'ivan@example.com',
               'USER_ID' => '3'
            );
         }
      
         public function filter()
         {
            // безусловно разрешаем запустить рассылку
            return true;
         }
      
         public function getForm()
         {
            return '';
         }
      }
      
      
      • getName() - возвращает название триггера. Оно выводится в списке целей и условий запуска.
      • getCode() - возвращает код триггера, уникальный в рамках модуля. Желательно указывать свой префикс, чтобы коды не пересеклись.
      • getEventModuleId() - возвращает модуль, который генерирует событие, на которое сработает триггер.
      • getEventType() - возвращает событие, на которое должен сработать триггер.
      • getRecipient() - возвращает массив или объект одного адреса или списка адресов. Результат может быть в в виде массива, или \Bitrix\Main\DB\Result или CDBResult.
      • filter() - возвращает true или false. Результат указывает запускать ли рассылку или нет. В функции можно указывать свои условия фильтрации события, свои выборки адресов.
      • getForm() - возвращает форму настройки триггера. Форма выведется на странице указания событий запуска и цели.
    3. Теперь подключим триггер. Для этого, сохраним класс триггера в файл /bitrix/php_interface/trigger_blog_comment.php.
    4. Далее нам нужно повесить обработчик события запроса списка триггеров. Для этого в /bitrix/php_interface/init.php добавим код:
         AddEventHandler("sender", "OnTriggerList", array("MySenderEventHandler","onTriggerList"));
         class MySenderEventHandler
         {
             public static function onTriggerList($data)
             {
            require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/php_interface/trigger_blog_comment.php');
            $data['TRIGGER'] = 'SenderTriggerBlogComment';
            return $data;
             }
         }
      

    Получение данных события

    Чтобы получить данные, передаваемые в событии, нужно воспользоваться методом getParam('EVENT'):

    $event = $this->getParam('EVENT');
    

    Она вернет массив параметров, передаваемых в функцию обработчик.

    К примеру, в событии OnOrderAdd модуля Sale передаются два параметра: ID (Идентификатор заказа) и arFields (Массив полей заказа).

    Тогда первый будет доступен по ключу 0, второй по ключу 1:

       $event = $this->getParam('EVENT');
       $ID = $event[0];
       $arFields = $event[1];
    

    Теперь вернемся к нашему триггеру. Как видим, в getRecipient прописан вручную адрес ivan@example.com.

    Давайте отправлять рассылку автору комментария.

    При событии добавления комментария в функцию-обработчик передается два параметра:

    • Первый - код добавленного комментария.
    • Второй - массив, переданный в CBlogComment::Add.

    Таким образом, мы в триггере можем получить код автора:

       $event = $this->getParam('EVENT');
       $authorId = $event[1]['AUTHOR_ID'];
    

    Теперь по этому коду мы можем получить e-mail и имя пользователя.

    Изменим метод getRecipient:

    public function getRecipient()
       {
          // получим данные из события
          $event = $this->getParam('EVENT');
          // Во втором параметре события есть код пользователя AUTHOR_ID
          $authorId = $event[1]['AUTHOR_ID'];
    
          if($authorId)
          {
             // получим email и имя пользователя, оставившего комментарий
             $user = \Bitrix\Main\UserTable::getRowById($authorId);
             if($user)
             {
                // возвращаем данные адресата в виде массива
                return array(
                   'EMAIL' => $user['EMAIL'],
                   'NAME' => $user['NAME'],
                   'USER_ID' => $user['ID'],
                );
             }
          }
    
          // если не нашли данные адресата, то не кому и рассылать
          return false;
       }
    

    Форма настройки триггера

    В типовом решении магазина комментарии блогов используются в качестве комментариев к товарам.

    Допустим, мы хотим запускать рассылку только при добавлении комментариев в конкретном одном блоге.

    Для этого сделаем форму настройки:

    public function getForm()
       {
          $blogId = $this->getFieldValue('BLOG_ID');
          
          $blogList = array();
          $blogDb = CBlog::GetList(
             array('ID' => 'DESC'),
             array('ACTIVE' => 'Y'),
             false,
             false,
             array('NAME', 'ID')
          );
          while($blog = $blogDb->Fetch())
          {
             $blog['SEL ECTED'] = ($blog['ID'] == $blogId ? true : false);
             $blogList[] = $blog;
          }
    
          ob_start();
          ?>
          <table>
             <tr>
                <td>Блог:</td>
                <td>
                   <sel ect name="<?=$this->getFieldName('BLOG_ID');?>">
                      <option value="">(любой)</option>
                      <?foreach($blogList as $blog):?>
                         <option value="<?=htmlspecialcharsbx($blog['ID'])?>" <?=($blog['SEL ECTED'] ? 'sel ected' : '')?>>
                            <?=htmlspecialcharsbx($blog['NAME'])?>
                         </option>
                      <?endforeach?>
                   </select>
                </td>
             </tr>
          </table>
          <?
          $resultForm = ob_get_clean();
    
          return $resultForm;
       }
    
    • getFieldName() - функция-обертка для получения имени поля для возможности его сохранения.
    • getFieldValue() - функция возвращает текущее сохраненное значение настройке.

    Фильтрация в триггере

    В форме настроек триггера появился список блогов, но, когда добавляем комментарий в другой блог, рассылка все равно запускается.

    Теперь в методе filter() сравним блог, выбранный в настройках, с блогом, в который добавлен комментарий:

    public function filter()
       {
          // получим код блога, в который добавлен комментарий
          $event = $this->getParam('EVENT');
          $eventBlogId = $event[1]['BLOG_ID'];
          
          // Сравним, что комментарий добавлен в блоге,
          // который указан в настройках формы. Если они одинаковы, запускаем рассылку.
          // Если в настройках не указан блог, то запускаем рассылку.
          $blogId = $this->getFieldValue('BLOG_ID');
          if($blogId && $blogId != $eventBlogId)
          {
             // запрещаем запускать рассылку
             return false;
          }
          
          // разрешаем запустить рассылку
          return true;
       }
    

    Свои поля персонализации

    Полей персонализации: #EMAIL#, #NAME#, #USER_ID# - может быть мало.

    Как сделать больше полей?

    Добавим еще три тега: код комментария, код поста, код блога.

       public function getPersonalizeFields()
       {
          $eventData = $this->getParam('EVENT');
          return array(
             'BLOG_COMMENT_ID' => $eventData[0],
             'BLOG_POST_ID' => $eventData[1]['POST_ID'],
             'BLOG_ID' => $eventData[1]['BLOG_ID'],
          );
       }
    

    Теперь доступны для использования в теле писем новые теги: #BLOG_COMMENT_ID#, #BLOG_POST_ID#, #BLOG_ID#. Причем, доступны только в письмах тех рассылок, в которых триггер указан в качестве условия запуска.

    Но чтобы эти теги показывались в списке тегов, нужно добавить их описание:

       public static function getPersonalizeList()
       {
          return array(
             array(
                'CODE' => 'BLOG_ID', // код тега, доступен как #BLOG_ID#
                'NAME' => 'Код блога', // выводимое название тега
                'DESC' => 'Это код блога, с которым связано событие' // описание
             ),
             array(
                'CODE' => 'BLOG_POST_ID',
                'NAME' => 'Код поста блога',
                'DESC' => 'Это код поста блога, с которым связано событие'
             ),
             array(
                'CODE' => 'BLOG_COMMENT_ID',
                'NAME' => 'Код комментария',
                'DESC' => 'Это код комментария, с которым связано событие'
             ),
          );
       }
    

    Примечание: В скором времени можно будет указать свои поля в результате функции getRecipient, но сейчас это еще не доступно, как и свои поля в коннекторах адресов.

    Фильтрация по сайту

    При создании/редактировании рассылки обязательно задается привязка к сайту.

    Вы можете получить код сайта методом getSiteId():

    $siteId = $this->getSiteId();
    

    И уже использовать для сравнения с кодом сайта из события, или выбрав из базы привязку к сайту, или текущим сайтом (с константой SITE_ID).

    Текст раскрывает тему
    Мы стараемся сделать документацию понятнее и доступнее,
    и Ваше мнение важно для нас
    Нам жаль это слышать… Но мы постараемся быть лучше! Поясните, пожалуйста, свой выбор:

    Мы благодарны вам за помощь в улучшении документации.

    Курсы разработаны в компании «1С-Битрикс»