в почтовых сообщениях строки обрезаются очень коротко. Это происходит из-за того, что функция php wordwrap некорректно работает с UTF-8 - русские символы у нее имеют длину 2, а английские - 1. Из-за этого нельзя просто в 2 раза увеличить границу - строки с английскими словами (например, url) разъедутся.
Я добавила функцию _wordwrap, и изменила на нее вызов в _drupal_wrap_mail_line (файл includes/mail.inc)
Кстати, во втором вызов wordwrap, которые предполагает обрезать слова, пропущен 4й параметр, который, собственно и должен указывать на обрезание. Иначе вызов функции с шириной 996 после ширины 77 не имеет смысла.
// Use soft-breaks only for purely quoted or unindented text.
$line = wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
// Break really long words at the maximum width allowed.
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n");
}
->
// Use soft-breaks only for purely quoted or unindented text.
$line = _wordwrap($line, 77 - $values['length'], $values['soft'] ? " \n" : "\n");
// Break really long words at the maximum width allowed.
$line = wordwrap($line, 996 - $values['length'], $values['soft'] ? " \n" : "\n", 1);
}
function _wordwrap( $str, $width, $break="\n") {
$formatted = '';
$position = -1;
$prev_position = 0;
$last_line = -1;
/// looping the string stop at each space
while( $position = mb_stripos( $str." ", " ", ++$position, 'utf-8' ) ) {
if( $position > $last_line + $width + 1 ) {
$formatted.= mb_substr( $str, $last_line + 1, $prev_position - $last_line - 1, 'utf-8' ).$break;
$last_line = $prev_position;
}
$prev_position = $position;
}
/// adding last line without the break
$formatted.= mb_substr( $str, $last_line + 1, mb_strlen( $str ), 'utf-8' );
return $formatted;
}
Комментарии
О, давно руки чесались с этим разобраться!
Спасибо, в закладки.
спасибо, полезно
Фикс — http://drupal.org/node/540228
Спасибо, пригодилось.
2neochief: посмотрел патч - он не прошел тест, да и версия у него стоит 7.x-dev. Он для Drupal 6 подходит?
PS: Странно что ширину текста письма в файле includes/mail.inc не вынесли в настройки, а просто забили её константой 77.
PPS: для хостинга где PHP < 5.2 строка
<?php
while( $position = mb_stripos( $str." ", " ", ++$position, 'utf-8' ) ) {
?>
выдает ошибку, т.к. функция mb_stripos() появилась только в PHP версии 5.2.
Gairon, ну патч c drupal.org возможно не работает, из-за того что код в Drupal немного изменился. Возьмите блокнот, и посмотрите что на что заменяется. И вручную через блокнот - замените.
neochief, патч c drupal.org я применил, но всё равно какая-то кривость. В web-интерфейсе Mail.ru письмо нормально выглядит. Но вот когда я читаю то же письмо в обычной почтовой программе Mozilla Thunderbird, получаю полную кашу. Дело в том что патч добавляет пробелы в конце обрезаемых строк. А Mozilla Thunderbird автоматически объединяет строки на конце которых есть пробелы, чтобы письмо было удобнее читать.
Письмо после обработки функцией drupal_wordwrap:
В результате Mozilla Thunderbird отображает такое письмо:
neochief, не подскажите как можно подкорректировать патч, чтобы на конце тех строк, где перенос должен быть обязательно - пробелов не было вообще? (сейчас там по два пробела)
Просветите меня, а зачем вообще делается перенос строк в почтовых сообщениях? Разве почтовая программа для чтения почты, ну или почтовый web-интерфейс сам не разорвёт строку в нужном месте. Какая цель делать такие разрывы? Я догадываюсь, что это предусматривает сам почтовый формат text/plain, но сходу не нашёл информацию по этой теме.
Я сейчас делаю проще: просто ставлю модуль htmlmail. Обрезание строк при отправке через CCK email field лечится хаком оного field
fairwind, спасибо. Формат text/html - это конечно выход. Но всё таки желательно посылать сообщения в стандартном формате text/plain, без использования html.
Немного переформулирую вопрос. Как можно переделать фикс http://drupal.org/node/540228, чтобы в конце строки где строка разбита функцией drupal_wordwrap - стоял двойной пробел, а там где изначально и так был перенос строки, вообще не было пробелов? Т.е. чтобы после обработки drupal_wordwrap получалось такое письмо:
Кроме добавления функции _wordwrap в файл includes/mail.inc - других решений нет?
Нашёл способ борьбы с тем что мешало в фиксе neochief http://drupal.org/node/540228
Добавил строчку:
Перед строкой:
Это убирает пробелы в конце текстовых строк __
Ну и соответственно, после этого Mozilla Thunderbird отображает письмо нормально, а не превращает его в кашу.
Большое спасибо ТС, заработало вроде.
У меня патч так и не заработал. Ругается, что не известна ему функция drupal_wordwrap.
Пока нашел выход только с решением топикастера.
Так, проблема решена! я просто установил в настройках HTML Mail FULL HTML формат, однако системные сообщения немного надо настроить, токен ссылки надо заключить в
<a href=""></a>
Найти HTML Mail можно здесь:
http://drupalmodules.com/search/node/mail+category%3A41
Данная тема считай что закрыта, никакие PHP больше выполнять не надо, русский текст отныне не обрезается вообще (без переноса или вручную проставленного
<br/>
), как и любой другой конечно.Токен ссылки работают нормально даже без заключения их в
<a href=""></a>
Но вот в фильтрованном HTML токен ссылки обрезаются и требуют заключения
в
<a href=""></a>
(так как иначе в обрезанном виде они не работоспособны),в фильтрованном HTML нельзя настроить отступ между строк,
<br/>
не помогаетОгромное спасибо действительно помогло Х))
Григорий_978
можете скрин дать -- где это выставить?
поставил модули HTML Mail и Mail System
вроде выставил на странице /admin/config/system/htmlmail Post-filtering unfiltered -- один фиг обрезается