среда, 20 июля 2011 г.

Gallery2 и кириллица

История болезни

Есть такая дурная особенность веб-приложений и CMS написанных зарубежными авторами, а именно - отсутствие какого-либо респекта по отношению к чужим языкам в кодировках. В целом, Gallery2 построена вокруг UTF-8, что должно было в теории лишить её подобных недостатков. Однако, не тут то было.

После установки выяснилось, что в паре мест вместо русского текста наблюдаются кракозябры. Одно из них - список фотографий на боковой панели, второй - в сокращённом виде комментариев.

Попробовал погуглить, но решения своей проблемы не нашёл. Пришлось включать мозг :).
Итак, запустив firebug и разобрав страницу, я увидел функцию entitytruncate, которая замечательно подходила под оба описанных случая - и названия на боковой панели и сокращённые комментирии обрезаны, сиречь truncated.

Пошарив в папке галереи на предмет всяких обрезаний, нашёл следующее:

$find /usr/share/egroupware/gallery/|grep trunc
/usr/share/egroupware/gallery/gallery2/lib/smarty_plugins/modifier.entitytruncate.php
/usr/share/egroupware/gallery/gallery2/lib/smarty/plugins/modifier.truncate.php

Так как страничка под firebug'ом сослалась на entitytruncate, в него и заглянул.
И увидел там замечательные строки:

$string = GalleryUtilities::utf8ToUnicodeEntities($string);

с комментарием:

/*
* Convert multibyte characters to html entities and then get an entity-safe substring.
* Split the string exactly on the boundary. If there's no change, then we're done.
*/

который при переводе на понятный язык звучит, как "отрезаем ноги, чтобы член длинней казался".
И в дальнейшем все выводы преобразуются обрано строчкой типа

return GalleryUtilities::unicodeEntitiesToUtf8($piece);

Естественно, первым, что я попытался выяснить было "а накуа вообще переводить из utf-8 в старый юникод?"
И убрав все следы подобных переводов (первую строчку и в последующих убрав функцию

GalleryUtilities::unicodeEntitiesToUtf8() ).

Сохранив свою новую modifier.entitytruncate.php убедился, что решение работает.
Краказябры исчезли.

В принципе на этом можно было бы и остановиться, однако смутило одно - несмотря на указанное $breakWords=false обрезание происходит где попало, а в некоторых случаях на месте обрезки поперёк слова проявились символы �

Так как PHP я начал изучать относительно не давно, с ходу понять, что там не работает (с учётом того, что текст простенькой функции обрезания вызывает кучу других функций) у меня не получилось.

Однако перед этим чисто из праздного интереса я заглянул в файлик modifier.truncate.php и обнаружил там ту же функцию обрезки текста, только написанную на более человеческом языке и вполне мне понятную.

В общем, не долго думая, я переименовал modifier.truncate.php в modifier.entitytruncate.php, изменил в объявлении

function smarty_modifier_truncate($string, $length = 80, $etc = '...',
$break_words = false, $middle = false)

на

function smarty_modifier_entitytruncate($string, $length, $etc = '...',
$break_words = false, $middle = false)

и всё заработало на этот раз так, как полагается.


Коротко решение

1. Находим в каталоге галереи modifier.entitytruncate.php и modifier.truncate.php и заменяем второй на первый.

В моём случае это:

$cp gallery2/lib/smarty/plugins/modifier.truncate.php gallery2/lib/smarty_plugins/modifier.entitytruncate.php

2. Открываем полученный modifier.entitytruncate.php в любимом текстовом редакторе.

$vim gallery2/lib/smarty_plugins/modifier.entitytruncate.php

3. Меняем строку

function smarty_modifier_truncate($string, $length = 80, $etc = '...',
$break_words = false, $middle = false)

на

function smarty_modifier_entitytruncate($string, $length, $etc = '...',
$break_words = false, $middle = false)

4. Сохраняем файл и перезапускаем сервер:

#service apache2 restart

Дело сделано.