21 авг. 2014 г., 3:12
Не очищается список адресатов при использовании modUser::sendEmail()
Не прошло и часа как я написал топик о возобновлении общения на нашем Сайте, как уже пишу новый топик с извинениями и багрепортом…
Извините все, кому сегодня упало в ящик куча спам-писем от меня! Кому интересно, под катом объяснение причины утреннего спаминга, а ближе к вечеру я более детально изучу данный вопрос, и может накатаю решение...
В общем, я решил всех обрадовать, отправив по одному короткому письму. Вот код:
Бывает :)
Но почему-то список адресатов не очищался... И с каждым новым письмом список получателей увеличивался. В итоге самые давние пользователи сайта получили наибольшее число писем. Еще раз извините! Я не специально.
Собственно ничего страшного!)) Конечно был некоторый шок/недоумение что это вдруг такой поток одного и того же письма))) :) С другой стороны даже настроение стало лучше, и всё будет хорошо!))) Мы всё понимаем! :)
Алишер, привет! :)
Сергей, привет! Спасибо за понимание! :)
Уже отчаялся повторить эту ошибку. Гнал по несколько емейлов на свои ящики, и все шло ОК, то есть без кучи копий в адресатах. Вроде тот же самый скрипт, а ошибки нет... И тут меня осенило! Я все письма гнал на разные ящики, но одного домена. А что если на разные? Добавил в список получателей емейл с другим доменом. И вот тут ошибка и проявилась)))
Чуть позже более предметно ее изучу, разберусь в чем проблема и отпишусь.
Все, разобрался. Оказалась целая история :) Это из разряда сложных логических ошибок.
Для начала кратко напомню задачу и суть проблемы: я решил всем пользователям разослать кратенькую новость. Для этого я сделал выборку всех активных пользователей и в цикле запустил отправку писем каждому через метод $user->sendEmail() (скрипт смотрите выше). Проблемы выразилась в том, что каждому новому письму помимо самого адресата добавлялся список всех предыдущих адресатов, то есть с каждым новым письмом количество адресатов увеличивалось на одного и некоторые пользователи получили десяток и больше писем. Благо я быстро заметил и понял проблему и рестартанул веб-сервер и сендмейл.
Сейчас вот полтора часа разбирался в сути проблемы и разобрался. Оказывается, все дело в моем личном емейле. Ну и плюс логическая ошибка в методе modUser::sendMail(). Ошибка заключалась в том, что если отправка письма выполняется с ошибкой, то метод возвращает false, не доходя до очистки списка получателей. Вот эти строчки:
if ($this->xpdo->mail->send() == false) {
return false;
}
$this->xpdo->mail->reset();
return true;
Как видите, в случае ошибки $this->xpdo->mail->reset() просто не может выполниться. А раз список не очищается, в нем присутствует и мой злополучный емейл. А это значит, что при следующей попытке отправить письмо (точнее письма) phpMailer опять вернет ошибку (хотя всем, кроме меня он письма отправит успешно), ну и так далее в цикле.
Конечно же это бага, и пуллреквест я отправил https://github.com/modxcms/revolution/pull/11931/files
Так а в чем косяк моего емейла? В чем он виноват?
А вот это вообще отдельная история :) Дело в том, что домен modxclub.ru привязан к серверу, на котором и размещается сайт modxclub.ru (что вполне логично). Так вот, при попытке отправки письма сервер определял, что он сам и является машиной-получателем, а не на гугл надо слать, где на самом деле почта и располагается. И он такой шлет запрос-отправку на локалхост, но шлет он для info@. А инфо (как и любой другой ящик) - это пользователь. И он такой спрашивает "а есть такой пользователь info?", на что система отвечает "нет, такого пользователя нет", и веб-сервер такой "а, ну тогда я не могу письмо доставить", и phpMailer возвращает false. Ну а все остальное я описал выше :)
Вот такая веселая бага)))
Все, пуллреквест приняли, бага поправлена :)