Исправление кодировки в письмах Opencart 3

Проблема: при переключении в режим отправки писем по 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, ссылка

2 комментария к “Исправление кодировки в письмах Opencart 3”

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх