В Битриксе, начиная с версии 7.1.3, появилась возможность переопределить стандартный механизм отправки почты.
Когда может быть полезен такой финт ушами? К примеру, когда в конторе есть какой-то централизованный сервис отправки почты, который должны использовать все приложения (SMTP-сервер на другой машине, веб-служба, что угодно). Для примера, рассмотрим GMail в качестве такого сервиса.[spoiler]
Механика простая: везде, где должна вызываться функция mail(), вызывается bxmail(). А уже в этой функции, перед вызовом стандартной функции mail(), Битрикс проверяет, определена ли функция custom_mail() и, если да, вызывает её вместо mail(). Соответственно, чтобы переопределить механизм отправки, нужно всего лишь написать функцию custom_mail() (в /bitrix/php_interface/init.php, к примеру (если хотим, чтобы такой механизм отправки действовал для всех сайтов на данной копии)).
Приступим к делу! Лично мне для отправки почты через GMail ближе всего Zend_Mail, но... Ни эта библиотека, ни другие не позволяют установить "сырые" заголовки для письма. А разбирать $additional_headers мне что-то не очень хочется. Следовательно, выбор перепадает на PEAR::Net_SMTP, как на механизм прямой работы с SMTP-сервером.
Итак, ближе к коду!
require_once 'Net/SMTP.php';
/**
* Отпраляем почту через SMTP-сервер GMail (пользователь: user@gmail.com).
*
* @see CEvent::HandleEvent()
* @see bxmail()
*
* @param string $to Адрес получателя.
* @param string $subject Тема.
* @param string $message Текст сообщения.
* @param string $additionalHeaders Дополнительные заголовки передаются Битриксом почти всегда ("FROM" передаётся здесь).
*
* @return bool
*/
function custom_mail($to, $subject, $message, $additionalHeaders = '')
{
/*
* Настройки можно (нужно) вынести в админку, но это уже домашнее задание :)
*/
$smtpServerHost = 'ssl://smtp.gmail.com';
$smtpServerHostPort = 465;
$smtpServerUser = 'user@gmail.com';
$smtpServerUserPassword = 'password';
if (!($smtp = new Net_SMTP($smtpServerHost, $smtpServerHostPort))) {
return false;
}
if (PEAR::isError($e = $smtp->connect())) {
return false;
}
if (PEAR::isError($e = $smtp->auth($smtpServerUser, $smtpServerUserPassword))) {
return false;
}
preg_match('/From: (.+)\n/i', $additionalHeaders, $matches);
list(, $from) = $matches;
$smtp->mailFrom($from);
$smtp->rcptTo($to);
/*
* Получаем идентификатор конца строки у Битрикса.
*/
$eol = CAllEvent::GetMailEOL();
$additionalHeaders .= $eol . 'Subject: ' . $subject;
if (PEAR::isError($e = $smtp->data($additionalHeaders . "\r\n\r\n" . $message))) {
return false;
}
$smtp->disconnect();
return true;
}
Вынесение настроек в админку, создание статического объекта соединения (чтобы не тратить время при отправке множества писем за раз) — это всё задания на дом
Безусловно, стОит! Буквально читаете мысли. Прежде всего, благодарю за полезную наработку. Пользуя ее, самому захотелось высвободить некоторое количество времени и оформить модулем. Но учитывая ваше оживление в том же русле, бью себя по рукам.
И, если позволите, некоторые пожелания к интерфейсу управления, и соответствующему функционалу.
Чтобы фичи в настройках приближались по возможностям к фичам почтовых программ, предлагая гибкость для использования с различными почтовыми серверами, например:
выбрать SSL-шифрование при необходимости, или не выбирать (автоматическая подстановка номера соответствующего порта)
Спасибо за хороший отзыв, приятно слышать, что кому-то ещё пригодилось
Пожелания тоже постараюсь учесть, но не факт, что все сразу — я думал собраться быстрее то, что есть, чтобы уже был какой-то модуль. Возможно мы с Вами вместе потом доведём модуль до ума — это же открытый код
Добрый день, как определить эту функцию. Я создал файл init.php но при отправе почты он все равно берет стандартную функцию майл. Как сделать так, чтобы битрикс вызывал именно custom_mail?
да. подскажите пожалуйста как правильно инклудить данную функцию. Где что надо прописать, чтобы портал ее использовал? и какие пакеты на CentOS 5 должны быть установлены, чтобы это работало?
В общем случае правильнее настраивать почту на почтовом сервере (Exim, Postfix), а не в самом Битриксе. Это обеспечит меньшее количество ошибок (не нужно трогать Битрикс руками) + поддержку очереди для отправки писем.
Ветров Михаил, советую отказаться от использования custom_mail и решить проблему на уровне локального почтового сервера: Exim или Postfix (в них можно настроить отсылку почты через внешний сервер, как у меня в статье, или у вас с phpmailer). Это решение намного более прозрачное и рабочее.
Ветров Михаил, согласен, рынок для такого расширения всё ещё есть. Видимо, это только я уже давно не вижу «обычных» shared-хостингов и поэтому на них не ориентируюсь (и не хочу, т.к. не вижу будущего у shared-хостинга).
По поводу одного ящика — не совсем так. В случае GMail — может быть любой адрес, подтверждённый в настройках аккаунта. Но лучше использовать специальный сервис для отправки (типа SendGrid, Postmark или Mandrill), через который будет отправляться почта, — в этом случае адрес отправителя может быть любым.
P.S. Вариант с GMail в статье идёт только в качестве примера. Я привёл выше сервисы, которые реально подходят для этогой задачи.
Разместил файл с скриптом в указанном месте. И теперь при заходе на сайт появляется вот такая ерунда (Screenshot_1) Версия КП 15.5.1 Права на файл выставил такие же, как и на файлы в папке. Если этот скрипт запустить в "Командная PHP-строка", то отрабатывает без ошибок. Подскажите в какую сторону капать?
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».