Содержание:
Проблема: при переключении в режим отправки писем по SMTP текст писем может приходить поврежденным — например, с неизвестными символами либо с лишними пробелами посреди слов. Проблема замечена на связке шаблон Prostore + SMTP-сервер Beget.
Причина в механизме нарезки тела письма на строки в \system\library\mail\smtp.php, send() : устанавливается лимит для каждой строки исходя из ее кодировки, затем html нарезается по нему с помощью str_split(); граница может пройти прямо посередине слова
$length = (mb_detect_encoding($message, mb_detect_order(), true) == 'ASCII') ? 998 : 249;
$lines = explode("\n", $message);
foreach ($lines as $line) {
$results = str_split($line, $length); // <-- проблемная строка
foreach ($results as $result) {
if (substr(PHP_OS, 0, 3) != 'WIN') {
fputs($handle, $result . "\r\n");
} else {
fputs($handle, str_replace("\n", "\r\n", $result) . "\r\n");
}
}
}
Для исправления можно использовать готовый модификатор (в конце статьи) либо поправить вручную – добавить в класс Smtp() метод str_split_word_aware() отсюда, и модифицировать код выше следующим образом:
$length = (mb_detect_encoding($message, mb_detect_order(), true) == 'ASCII') ? 998 : 249;
$lines = explode("\n", $message);
foreach ($lines as $line) {
$line = trim($line);
$results = [];
if (method_exists($this, 'str_split_word_aware')){
$results = $this->str_split_word_aware($line, $length);
foreach ($results as &$r_val) {
$r_val = trim($r_val);
}
} else {
$results = str_split($line, $length);
}
foreach ($results as $result) {
if (substr(PHP_OS, 0, 3) != 'WIN') {
fputs($handle, $result . "\r\n");
} else {
fputs($handle, str_replace("\n", "\r\n", $result) . "\r\n");
}
}
}
Как итог, теперь строки будут нарезаться по границе слов
Модификатор для Opencart
По данному рецепту собрал модификатор, тестировался на ocStore 3.0.3.7, ссылка