Источники адресов, коннекторы

Урок 222 из 365
Автор: Александр Суворов
Сложность урока:
4 уровень - сложно, требуется сосредоточится, внимание деталям и точному следованию инструкции.
4 из 5
Просмотров: 4305
Ограничения по редакциям: Старт, Стандарт
Одной из отличительных черт модуля E-mail маркетинг является то, что не нужно вручную брать список адресов и добавлять его в модуль. Модуль может самостоятельно выбирать адреса по произвольным критериям из разных источников.

Источником являются: пользователи сайта, инфоблоки, веб-формы, файл или сторонний сайт. Но модуль не знает, в каком инфоблоке и в каком поле инфоблока хранится адрес. Для этого используется коннектор, который реализует общий интерфейс для доступа к адресам из источника.

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

  • Создание коннектора
  • Настройки коннектора в интерфейсе
  • Важные замечания
  • Создание коннектора

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

    1. Создадим файл my_sender_connector.php в директории bitrix/php_interface и в него добавим класс SenderConnectorUserBirthday, который расширяет базовый класс \Bitrix\Sender\Connector:
      <?php
      
      class SenderConnectorUserBirthday extends \Bitrix\Sender\Connector
      {
          public function getName()
          {
           return 'Пользователи - день рождения';
          }
      
          public function getCode()
          {
           return "my_user_birthday";
          }
      
          /** @return \CDBResult */
          public function getData()
          {
           $currentDate = new \Bitrix\Main\Type\Date();
           $filter = array(
            "PERSONAL_BIRTHDAY_DATE" => $currentDate->format("m-d"),
           );
           $resultDb = CUser::GetList(($by="ID"), ($order="asc"), $filter);
      
           return $resultDb;
          }
      
          public function getForm()
          {
           return "Все пользователи, у которых день рождения на момент рассылки";
          }
      } 
      

      Как видим, в классе 4 обязательных функции:

      • getName - название источника адресов. Оно будет выводиться в административной части сайта.
      • getCode - служебная функция, нужно указывать уникальный код.
      • getData - функция, возвращающая адреса, в ней выбираются пользователи, у которых день рождения на текущую дату. Должна возвращать объект CDBResult.
      • getForm - возвращает форму настройки коннектора. Форма выводится при создании группы адресов в административной части сайта.

    2. Теперь подключим наш коннектор к модулю Email-marketing. Для этого в файле bitrix/php_interface/init.php нужно добавить такой код:
      AddEventHandler("sender", "OnConnectorList", array("MyEventHandler","senderConnectorHandler"));
      class MyEventHandler
      {
          public static function senderConnectorHandler($arData)
          {
           $arAutoLoadClasses = array(
            'SenderConnectorUserBirthday' => '/bitrix/php_interface/my_sender_connector.php'
           );
           \Bitrix\Main\Loader::registerAutoLoadClasses(null, $arAutoLoadClasses);
      
           $arData['CONNECTOR'] = 'SenderConnectorUserBirthday';
      
           return $arData;
          }
      } 
      

      При инициализации ядра, мы подключаем обработчик на событие OnConnectorList модуля Email-marketing.

    3. В этом обработчике события возвращается поступивший параметр с указанием названия класса коннектора:
      $arData['CONNECTOR'] = 'SenderConnectorUserBirthday'; 
      

      Готово, теперь наш коннектор можно использовать.

    4. На странице Группы адресов (Сервисы > Email-маркетинг > Группы адресов) переходим к созданию/редактированию группы. В списке появился наш коннектор Пользователи - день рождения:

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

    5. Затем создадим выпуск, которому укажем периодическую отправку каждый день.

    Готово. Раз в день будет выполняться выпуск рассылки, выбирая все адреса пользователей, у которых день рождения на день запуска.

    Настройки коннектора в интерфейсе

    1. Функция getForm может возвращать html с элементами формы и javascript.

      Чтобы элементы формы были обработаны, необходимо:

      $s = '<input type="text" name="NAME">';
      
      заменить на:
      $s = '<input type="text" name="'.$this->getFieldName('NAME').'">';
      

    2. Тоже самое касается и атрибута id. Вместо указания самого id, нужно вызывать getFieldId параметром, указав id:

      Вместо:

      $s = '<input type="text" id="NAME">';
      
      следующее:
      $s = '<input type="text" id="'.$this->getFieldId('NAME').'">';
      

    3. Чтобы получить ранее сохраненное значение поля, нужно вызвать getFieldValue с параметром названия поля. Вторым параметром можно указать значение по-умолчанию:

      Вместо:

      $s = '<input type="text" name="NAME" value="">';
      
      следующее:
      $s = '<input type="text" name="'.$this->getFieldName('NAME').'" value="'.$this->getFieldValue('NAME', '').'">';
      

    4. Если требуется еще знать атрибут name тега form, где будет выводиться форма коннектора, то ее можно получить, вызвав $this->getFieldFormName().

      1. Допустим, в нашем коннекторе нам потребовалась возможность использовать адреса не только тех, у кого день рождения на текущую дату, а нужна возможность выбора:

        • на текущую дату;
        • за 3 дня до наступления;
        • возможность указать произвольное количество дней до наступления дня рождения.

        Тогда html-форма может выглядеть так:

        <script>
            function myShowBirthdayDayField(ctrl, hiddenCtrl)
            {
             if(ctrl.value=="CUSTOM")
                 BX(hiddenCtrl).style.display = "";
             else
                 BX(hiddenCtrl).style.display = "none";
            }
        </script>
        <table>
            <tr>
             <td>Дата рождения:</td>
             <td>
              <select name="BIRTHDAY" 
                  on change="myShowBirthdayDayField(this, 'DAYS');">
                  <option value="">Сегодня</option>
                  <option value="3">За три дня</option>
                  <option value="CUSTOM">Указать за сколько дней</option>
              </select>
              <input 
                  type="text" 
                  name="DAYS" 
                  id="DAYS" 
                  value="" 
                  style="display: none;"
              >
             </td>
            </tr>
        </table> 
        

        Тогда сама форма после использования getFieldId, getFieldsName, GetFieldValue будет выглядеть так:

        public function getForm()
        {
        
           return '
             <sc ript>
             function myShowField(ctrl, hiddenCtrl)
             {
              if(ctrl.value=="CUSTOM")
                  BX(hiddenCtrl).style.display = "";
              else
                  BX(hiddenCtrl).style.display = "none";
             }
             </sc ript>
             <table>
             <tr>
              <td>Дата рождения:</td>
              <td>
                  <select name="'.$this->getFieldName('BIRTHDAY').'"
                   on change="myShowField(this, \''.$this->getFieldId('DAYS').'\');">
                   <option value="">Сегодня</option>
                   <option value="3" '.('3' == $this->getFieldValue('BIRTHDAY', "") ? 'selected' : '').'>За три дня</option>
                   <option value="CUSTOM" '.('CUSTOM' == $this->getFieldValue('BIRTHDAY', "") ? 'selected' : '').'>Указать за сколько дней</option>
                  </select>
                  <input
                   type="text"
                   name="'.$this->getFieldName('DAYS').'"
                   id="'.$this->getFieldId('DAYS').'"
                   value="'.$this->getFieldValue('DAYS', "").'"
                   '.($this->getFieldValue('BIRTHDAY', "")!="CUSTOM" ? 'style="display: none;"' : "").'
                  >
              </td>
             </tr>
             </table>
           ';
        } 
        

        И теперь изменим функцию getData. Для получения установленных значений полей нужно вызывать ту же функцию getFieldValue. Используем значения из формы:

        public function getData()
        {
            $birthday = $this->getFieldValue('BIRTHDAY', 0);
            $days = $this->getFieldValue('DAYS', 0);
        
            if(is_numeric($birthday))
             $dayToAdd = $birthday;
            elseif($birthday=="CUSTOM" && is_numeric($days))
             $dayToAdd = $days;
            else
             $dayToAdd = 0;
        
        
            $currentDate = new \Bitrix\Main\Type\Date();
            $filter = array(
             "PERSONAL_BIRTHDAY_DATE" => $currentDate->add("-".$dayToAdd." day")->format("m-d"),
            );
            $resultDb = CUser::GetList(($by="ID"), ($order="asc"), $filter);
        
            return $resultDb;
        } 
        

        Добавим в группу наш коннектор два раза и посмотрим результат, они независимо друг от друга работают и сохраняются:

        Важные замечания

        В модуле есть собственная база адресов, которая выводится на странице Списки адресов (Маркетинг > Email-маркетинг > Список адресов).

        В нее можно добавлять адреса как вручную, так и из источников:

        Так, если вы не хотите, чтобы из источника пользователь мог сюда добавить адреса, то в классе коннектора нужно добавить функцию:

        /** @return bool */
        public function requireConfigure()
        {
           return true;
        } 
        

        В этом случае, он не будет отображен в данном интерфейсе.

        Но если ваш коннектор подразумевает импорт адресов в Списки адресов, то он должен возвращать отсортированные данные в строгом порядке.

        То есть, в нашем примере мы возвращаем адреса пользователей. Значит нужно сортировать по ID и возрастанию, чтобы новые пользователи были в конце выборки. Так как импорт пошаговый, мы исключаем ситуации, когда при разных выборках один и тот же адрес будет то в начале выборки, то в середине, то в конце. И этот адрес может быть пропущен.



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

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

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