Писал приложение, в котором была необходимость создать внутреннюю почту, с возможностью отослать письмо и c возможностью на это email потом ответить. Возникла задача цитирования текста предыдущего сообщения при ответах на входящие письма, наподобие, как делают всякого рода email clients, или тот же gmail с web-интерфейсом.
Например:
> Это quoted text.
> Всё что тут было написано, было написано
> не мной, во входящем сообщении.
Можно, конечно, взять и написать примитивную логику, подобно:
str_replace("\n","\n> ","> ".$text);
Но, это плохое решение, если хочется сделать красивое повторное цитирование уже ранее процитированного текста. Обратите внимание, как это делает gmail или другие email клиенты:
> повторное цитирование:
>
>> Это quoted text.
>> Всё что тут было написано, было написано
>> не мной, во входящем сообщении.
При повторном цитировании текста, вначале строки, возле угловой скобки ставится отступ лишь в том случае, если рядом стоит «чистый текст», ранее не обвёрнутый в кавычки цитирования. Так что без дополнительной логики, простым str_replace() тут не обойтись.
Оказалось, что найти такую функцию на PHP среди готовых решений не так-то просто. Поэтому предлагаю свой вариант реализации на PHP:
// function for wrapping/quoting text on replies
public function quote_text(&$body)
{
$body_quote = ">"; // quotation mark
$rewrap_body = explode("\n", $body);
$body = '';
$cnt = count($rewrap_body);
for ($i=0;$i<$cnt;$i++)
{
if (preg_match("/^(>+)/", $rewrap_body[$i], $matches)) {
$gt = $matches[1];
$body .= $body_quote . str_replace("\n", "\n" . $body_quote
. "$gt ", rtrim($rewrap_body[$i])) ."\n";
} else {
$body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n" . $body_quote . (!empty($body_quote) ? ' ' : ''), rtrim($rewrap_body[$i])) . "\n";
}
unset($rewrap_body[$i]);
}
}
Функция quote_text принимает переменную по ссылке в качестве единственного параметра. Результатом работы этой функции будет процитированный текст, обвёрнутый в метки $body_quote, по схеме цитирования, описанной выше.