Уже достаточно давно в продукте появилось поддержка прикрепления файлов к почтовым событиям.
Прикрепить файл просто: вызываем метод Bitrix\Main\Mail\Event::send, в ключе FILE передаем либо массив ID из базы, либо массив путей. В старом методе CEvent::Send, который по факту уже является оберткой для нового, указываем параметр $files (описан в документации).
При передаче путей, Битрикс предварительно сохраняет файлы в таблицу b_file с помощью CFile::SaveFile. Общая логика такая:
Все выглядит отлично, но «счастливые» обладатели сайтов на windows-1251 могут столкнуться с проблемами при прикреплении файлов с русскими именами.
Пусть у нас есть:
и мы хотим отправить письмо с этими файлами.
Следующий код успешно отправит письмо с 2 вложениями, но только на кодировке utf-8:
use Bitrix\Main\Mail\Event;
Event::send([
"EVENT_NAME" => "SOME_EVENT",
"LID" => "s1",
"C_FIELDS" => [],
"FILE" => [
$_SERVER["DOCUMENT_ROOT"]."/файл.jpg",
$_SERVER["DOCUMENT_ROOT"]."/file.jpg"
]
);
С windows-1251, в лучшем случае, в письме придет только один файл.
Необходимо правильно указать путь, так как кодировка сайта у нас windows-1251, а кодировка файловой системы – utf-8.
Полный код будет выглядеть следующим образом:
use \Bitrix\Main\Mail\Event;
use \Bitrix\Main\IO;
Event::send([
"EVENT_NAME" => "SOME_EVENT",
"LID" => "s1",
"C_FIELDS" => [],
"FILE" => [
IO\Path::ConvertLogicalToPhysical($_SERVER["DOCUMENT_ROOT"]."/файл.jpg"),
$_SERVER["DOCUMENT_ROOT"]."/file.jpg"
]
]);
Стоит отметить, что Битрикс не выдает вообще никакой ошибки в первом варианте (когда CFile::SaveFile отработал некорректно), а просто заносит в таблицу b_event_attachment в поле FILE_ID значение 0.
C IO\Path::ConvertLogicalToPhysical файл сохраняется корректно.
Вроде бы задача решена. Но если мы попробуем сейчас выполнить этот код, то придет 2 файла:
«file.jpg» - нормальный, а «файл.jpg» с нулевой длиной.
Происходит это из-за бага, который есть внутри ядра. Тикет создан в феврале 2017 с категорией «Ошибки», пока исправления нет. Суть в том, что агент, который отправляет письма производит двойную конвертацию имени файла. Сначала в CFile::MakeFileArray, а затем в классе Bitrix\Main\Mail\Mail:: setAttachment при вызове Bitrix\Main\IO\File::getFileContents.
«Исправляем» это:
Было:
try {
$fileContent = File::getFileContents($attachment["PATH"]);
} catch (\Exception $exception) {
$fileContent = '';
}
Стало:
try {
$fileContent = File::getFileContents($attachment["PATH"]);
} catch (\Bitrix\Main\IO\FileNotFoundException $exception) {
try {
$fileContent = File::getFileContents(\Bitrix\Main\IO\Path::convertPhysicalToLogical($attachment["PATH"]));
} catch (\Exception $exception) {
$fileContent = '';
}
} catch (\Exception $exception) {
$fileContent = '';
}
Т.е. если при попытке получить содержимое файла вывалилось исключение «Файл не найден», пробуем получить содержимое по сконвертированному в обратную сторону имени файла. Теперь все файлы отправляются.
Комментариев пока что нет
Входим в число лучших компаний России в сферах интернет-рекламы и разработки сайтов по результатам самых авторитетных рейтингов
Нужна помощь с сайтом? Заполните форму, и наши менеджеры проконсультируют вас уже сегодня!
Уникальный тариф «Оборот», где доход агентства больше не зависит от визитов и позиций вашего сайта, а привязан исключительно к росту оборота вашей компании.
Тариф, который хотели сделать многие, но реализовали только мы.