Вход • Регистрация

Рассылка циклически повторяется.

  • 06 августа 2016 г.
  • Расскажите пожалуйста как устроена рассылка. Проблема вот в чем: В базе имеется 50 адресов. (некоторые из них недействительны). При отправки рассылки с доменной почты (smtp настроено) на все 50 адресов скрипт начинает показывать, что он оправляет сначала 50, потом 100, затем 150 писем... Дальше я сам прерываю процесс, потому как на почту (с которой идет рассылка) начинается сыпаться уведомление от хостинга, что превышен лимит отправлений (120 писем в час). Притом на многие адреса рассылка не ушла...

    Итого: у меня в базе 50 адресов, а отправляет в разы больше. Судя по тому, что мне на почту (она среди тех 50 адресов) 3 раза пришло одно и тоже письмо подозреваю, что при несуществующей почте скрипт каким - то образом шлет заново всю рассылку.

    Встречались ли вы с таким ? Использую DIAFAN.CMS 6.0.3.5
    • 06 августа 2016 г.
    • Цитата
      как устроена рассылка

      modules/subscribtion/admin/subscribtion.admin.php
      Код
      $rows = DB::query_fetch_all("SELECT mail, name, code FROM {subscribtion_emails} WHERE act='1' AND trash='0'".$ids." LIMIT ".$i.", ".$this->mail_count); //получаем из базы первые ***(из настроек модуля, например 10) подписчиков
      foreach ($rows as $row)
      {
      ....
      send_mail(); //отправляем каждому письмо
      $k++;
      }
      if($k == $this->mail_count)
      { //если отправили всем 10, то выводим в браузер сообщение "Отправлено 10 писем" и ставим редирект на вызов самого себя, передавая GET с i=10, чтобы этот же скрипт отправил новую пачку писем следующим, начиная с 10
      echo '
      Sended: '.($i * $this->mail_count + $k).'
      <meta http-equiv="Refresh" content="0; url='.URL.'?subscribtion_action=send_mail&amp;i='.($i + 1).'&amp;id='.$s["id"].'">';
      exit;
      }
      // если отправлено всё, то ставим редирект обратно в модуль с сообщением "Все отправлено"
      $this->diafan->redirect(URL.'success'.(10 + $k + $i * $this->mail_count).'/');

      Теоретически, если браузер не поддерживает редиректы или хостинг рубит GET-переменные, скрипт может не воспринимать $i, которая пропускает УЖЕ отправленные письма и может бесконечно крутиться, отправляя одно и то же первым.
      • 09 августа 2016 г.
      • Цитата
        Теоретически, если браузер не поддерживает редиректы или хостинг рубит GET-переменные, скрипт может не воспринимать $i, которая пропускает УЖЕ отправленные письма и может бесконечно крутиться, отправляя одно и то же первым.
        Не соглашусь. Здесь ключевое слово у истца следующее:
        Цитата
        Итого: у меня в базе 50 адресов, а отправляет в разы больше.
        Другим словом - зацикливание.
  • 06 августа 2016 г.
  • Посмотрел, что количество писем, отправляемых за одну итерацию в скрипте = 50. Попробовал отправить 50 или меньше - уходят. Вместе с проблемными. Если писем больше 50-ти начинается зацикливание...
    • 06 августа 2016 г.
    • Ну, мне сказать нечего на это. Надо смотреть сервер, логи, крутить-вертеть.
      Или просто оптравляйте по 50 писем.
      • 06 августа 2016 г.
      • Если что проясню - напишу. Так конечно, что гадать-то. Спасибо.
      • 08 августа 2016 г.
      • Изменил в subscribtion.admin.php переменную $mail_count с 50 на 100 (количество писем, отправляемых за одну итерацию по умолчанию). Результат - 100 писем ушли успешно. Буду копаться дальше, но как мне кажется проблема в итерации...
        • 08 августа 2016 г.
        • Цитата
          как мне кажется проблема в итерации...
          • 08 августа 2016 г.
          • Надо было написать "ОЧЕВИДНО", а не кажется
            • 09 августа 2016 г.
            • Ну, если
              Цитата
              Надо было написать "ОЧЕВИДНО"
              Тогда исправим опечатку в коде. Берем файл modules/subscribtion/admin/subscribtion.admin.php, открываем ее редактором и находим там вот эту функцию
              Код
              public function send_mail() { ... }
              В этой функции ищем следующую строчку
              Код
              $rows = DB::query_fetch_all("SELECT mail, name, code FROM {subscribtion_emails} WHERE act='1' AND trash='0'".$ids." LIMIT ".$i.", ".$this->mail_count);
              и удаляем ее. В замен удаленной строчки (там где была искомая строчка) вставим вот эти
              Код
              if ($i <= 0) $i = 1;
              $last_row = $i + $this->mail_count - 1;
              $rows = DB::query_fetch_all("SELECT mail, name, code FROM {subscribtion_emails} WHERE act='1' AND trash='0'".$ids." LIMIT ".$i.", ".$last_row);
              Все, вытираем испарину, самое сложное сделано. Сохраняем файл, сбрасываем кэш и наслаждаемся работой отправки писем.

              Для любопытных и пытливых поясню (профессионалы и так знают).
              Оператор SQL LIMIT позволяет вывести указанное число строк из таблицы. Оператор SQL LIMIT записывается всегда в конце запроса. Используется в СУБД MySQL. Аналогом в MS SQL Server является оператор SQL TOP.
              Оператор LIMIT имеет следующий синтаксис:
              Код
              LIMIT first_row [, last_row]
              Оператор SQL LIMIT выводит то количество записей, которое указано в параметре first_row. Если, через запятую указано значение параметра last_row, то будут выведены строки в диапазоне first_row - last_row включительно.

              Как-то так.

              Успехов.

Новости

  • 18 июня
  • В сборке большое обновление demo-шаблона, дополнительная защита от спама, улучшение YML-импорта и еще много важного и интересного.
  • 24 апреля
  • В новой сборке совершили революцию в структурировании кастомизированной информации в шаблонах, добавили авторегистрацию пользователей, усовершенствовали защиту от спама, актуализировали накопительную скидку, а также улучшили производительность и стабильность работы системы.
  • 12 января
  • После выхода сборки 7.1 мы выпустили уже три патча, в каждом из которых улучшаем административную часть сайта. Сборка DIAFAN.CMS 7.1.3 уже доступна к установке. 

Форум