Триггер для не наступивших событий

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

Как быть, если нет события?

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


Cо срабатыванием триггера по событию разобрались в предыдущей главе. А как быть, если нет события?

К примеру, клиент не заходил на сайт 30 дней? Или клиент бросил корзину 7 дней назад? Только по прошествии времени мы узнаем, что у нас какой-то период времени что-то не происходит: нет оформления заказа, нет захода на сайт.

На этот случай у нас есть другой тип триггера. Он запускается раз в день, в указанное время, и ему не нужно событие.


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

  • Создадим свой триггер, унаследованный уже от другого класса: \Bitrix\Sender\TriggerConnectorClosed и и определим логику в методе filter():
    <?
    
    class SenderTriggerViewedProduct extends \Bitrix\Sender\TriggerConnectorClosed
    {
       /*
        * @return string
        *
        * Название триггера
        */
       public function getName()
       {
          return 'Просмотрел товары и ушел';
       }
    
       /*
        * @return string
        *
        * Уникальный код триггера
        */
       public function getCode()
       {
          return "my_viewed_product";
       }
    
       /*
        * @return bool
        *
        * Может ли триггер использоваться как цель,
        * а не только для запуска
        */
       public static function canBeTarget()
       {
          return false;
       }
    
       /*
        * @return bool
        *
        * Функция, которая сообщает, запускать ли рассылку для данного события.
        *
        */
       public function filter()
       {
          \Bitrix\Main\Loader::includeModule('sale');
          \Bitrix\Main\Loader::includeModule('catalog');
    
    
          $days = $this->getFieldValue('DAYS_VIEW');
          if(!is_numeric($days))
          {
             $days = 1;
          }
    
          $dateFr om = new \Bitrix\Main\Type\DateTime;
          $dateTo = new \Bitrix\Main\Type\DateTime;
    
          $dateFr om->setTime(0, 0, 0)->add('-' . $days.' days');
          $dateTo->setTime(0, 0, 0)->add('-' . ($days - 1) . ' days');
    
          $userListDb = \Bitrix\Catalog\CatalogViewedProductTable::getList(array(
             'select' => array('USER_ID' => 'FUSER.USER.ID', 'EMAIL' => 'FUSER.USER.EMAIL', 'NAME' => 'FUSER.USER.NAME'),
             'filter' => array(
                '=SITE_ID' => $this->getSiteId(),
                '>DATE_VISIT' => $dateFr om,
                '<DATE_VISIT' => $dateTo,
             ),
             'group' => array('USER_ID', 'EMAIL', 'NAME'),
             'order' => array('FUSER.USER.ID' => 'ASC')
          ));
    
          if($userListDb->getSelectedRowsCount() > 0)
          {
             // есть просмотренные товары
             // сохраняем список адресатов
             $this->recipient = $userListDb;
    
             // запускаем рассылку
             return true;
          }
          else
          {
             // нет просмотренных товаров, не запускаем рассылку
             return false;
          }
       }
    
    
       /*
        * @return string
        *
        * Форма настройки триггера
        */
       public function getForm()
       {
          return '
             <table>
                <tr>
                   <td>Сколько дней назад:</td>
                   <td>
                      <input size=3 type="text" name="'.$this->getFieldName('DAYS_VIEW').'" value="'.htmlspecialcharsbx($this->getFieldValue('DAYS_VIEW', 90)).'">
                   </td>
                </tr>
             </table>
          ';
       }
    
    
       /*
        * @return array|\Bitrix\Main\DB\Result|\CDBResult
        *
        * Функция, которая из данных события
        * вернет данные о получателе рассылки
        */
       public function getRecipient()
       {
          // возвращаем сохраненные адресаты
          return $this->recipient;
       }
    }
    

    Здесь мы фильтруем список просмотров по дате просмотра за период в один день. От текущего дня отнимаем указанное количество дней.

    Таким образом, если у нас указано в настройках триггера 1 день, то фильтр по дате на момент запуска будет выбирать записи за предыдущий день. И так каждый день.

  • Если нам нужна возможность обработать старые данные, то есть отправить письма не только «за вчера», но еще один раз отправить по всем пользователям, кто просматривал ранее, то сообщим, что триггер такое умеет делать:
       public static function canRunForOldData()
       {
          return true;
       }
    
  • А теперь реализуем такую возможность в методе filter(). Для этого, если метод isRunForOldData() возвращает true, фильтруем все, что ранее [текущая_дата - указанное количество дней в настройках]:
    if($this->isRunForOldData())
          {
             $filter = array(
                '!DATE_VISIT' => null,
                '<DATE_VISIT' => $dateTo,
             );
          }
          else
          {
             $filter = array(
                '>DATE_VISIT' => $dateFr om,
                '<DATE_VISIT' => $dateTo,
             );
          }
          $filter['=SITE_ID'] = $this->getSiteId();
          
          $userListDb = \Bitrix\Catalog\CatalogViewedProductTable::getList(array(
             'select' => array('USER_ID' => 'FUSER.USER.ID', 'EMAIL' => 'FUSER.USER.EMAIL', 'NAME' => 'FUSER.USER.NAME'),
             'filter' => $filter,
             'group' => array('USER_ID', 'EMAIL', 'NAME'),
             'order' => array('FUSER.USER.ID' => 'ASC')
          ));
    



Курсы разработаны в компании «1С-Битрикс»
Спасибо, мы рады что смогли помочь Вам. Ниже Вы можете оставить свой отзыв или пожелание :)
Нам жаль это слышать… Но мы постараемся быть лучше! Поясните, пожалуйста, свой выбор:

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

Мы стараемся сделать документацию понятнее и доступнее,
и Ваше мнение важно для нас