Интересный сайт. Факты и решения

Dle, php 5.4 и теги на русском языке

5122 просмотров Сайты Нет комментов »

При переходе программного обеспечения сервера на версию php 5.4 обнаружились проблемы в работе движка dle. Все они возникают на старых версиях движка, но обновить двиг далеко не всегда является возможным, настолько сильно он может быть модифицирован различными модулями и/или ручными доработками. Следовательно требуется исправлять, то что есть. Опишу те ошибки, с которыми столкнулся на cms dle при обновлении пхп до 5.4.

Одна из проблем — перестали отображаться новости на странице тегов, имеющих русские символы. Например, на странице http://site.ru/tags/%C0%ED%E5%EA%E4%EE%F2%FB/ выдавалась стандартная фраза движка «По данному адресу публикаций на сайте не найдено, либо у вас нет доступа для просмотра информации по данному адресу». Поиск в интернете по запросу «dle php 5.4 тэги на русском языке» ничего не дал.

Однако, поиском удалось найти решение следующей проблемы — отсутствовали все или частично заголовки новостей в админпанели. Запрос «dle php 5.4 не отображаются новости» привел к информации, как исправить проблему.

В обоих случаях проблема возникала из-за функции htmlspecialchars (функция преобразования специальных символов в html). Третьим аргументом функции является указание кодировки. В дле этот аргумент не указан. По умолчанию используется UTF-8, а база движка в CP1251. Поэтому нужно явно указать функции кодировку.

 
Разберем сначала проблему с русскими тегами.

Для нормальной работы тегов на русском языке в файле engine.php изменить строку (№257 — здесь и далее в скобках буду указывать примерный номер строки в файле. В разных версиях dle номер строки будет немного отличаться):


$tag = @$db->safesql ( htmlspecialchars ( strip_tags ( stripslashes ( trim ( $tag ) ) ), ENT_QUOTES ) );

на


$tag = @$db->safesql ( htmlspecialchars ( strip_tags ( stripslashes ( trim ( $tag ) ) ), ENT_QUOTES, 'cp1251' ) );


 
Далее выяснилось, что при добавлении или редактировании новостей в админке, теги на кириллице просто пропадают. Решение аналогичное:
В файле engine/inc/addnews.php строку (№505)


else $_POST['tags'] = @$db->safesql( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['tags'] ) ) ), ENT_QUOTES ) );

заменить на


else $_POST['tags'] = @$db->safesql( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['tags'] ) ) ), ENT_QUOTES, 'cp1251' ) );


В файле engine/inc/editnews.php строку (№1414)


$tag = @$db->safesql ( htmlspecialchars ( strip_tags ( stripslashes ( trim ( $tag ) ) ), ENT_QUOTES ) );

заменить на


$tag = @$db->safesql ( htmlspecialchars ( strip_tags ( stripslashes ( trim ( $tag ) ) ), ENT_QUOTES, 'cp1251' ) );


 
Чтобы русские теги не пропадали при добавлении новостей с веб-страницы, тоже сделать для файла engine/modules/addnews.php:
строка (№108)


else $_POST['tags'] = @$db->safesql( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['tags'] ) ) ), ENT_QUOTES ) );

меняется на


else $_POST['tags'] = @$db->safesql( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['tags'] ) ) ), ENT_QUOTES, 'cp1251' ) );


Таким образом все сводится к добавлению функции htmlspecialchars третьего аргумента ‘cp1251′.

 
Если не отображаются заголовки новостей в админке:
в файле engine/inc/editnews.php строку (№187)


$title = htmlspecialchars( stripslashes( $title ), ENT_QUOTES );

заменить на


$title = htmlspecialchars( stripslashes( $title ), ENT_QUOTES, 'cp1251' );


В файле engine/classes/parse.class.php строку (№420-510)


if (!$this->safe_mode AND $this->edit_mode) $txt = htmlspecialchars( $txt, ENT_QUOTES );

заменить на


if (!$this->safe_mode AND $this->edit_mode) $txt = htmlspecialchars( $txt, ENT_QUOTES, 'cp1251' );


 
Не работал поиск новостей в админке по части заголовка. Исправить сроки (№39-42):


$search_field = $db->safesql( trim( htmlspecialchars( stripslashes( urldecode( $_REQUEST['search_field'] ) ), ENT_QUOTES ) ) );
$search_author = $db->safesql( trim( htmlspecialchars( stripslashes( urldecode( $_REQUEST['search_author'] ) ), ENT_QUOTES ) ) );
$fromnewsdate = $db->safesql( trim( htmlspecialchars( stripslashes( $_REQUEST['fromnewsdate'] ), ENT_QUOTES ) ) );
$tonewsdate = $db->safesql( trim( htmlspecialchars( stripslashes( $_REQUEST['tonewsdate'] ), ENT_QUOTES ) ) );


на


$search_field = $db->safesql( trim( htmlspecialchars( stripslashes( urldecode( $_REQUEST['search_field'] ) ), ENT_QUOTES, 'cp1251' ) ) );
$search_author = $db->safesql( trim( htmlspecialchars( stripslashes( urldecode( $_REQUEST['search_author'] ) ), ENT_QUOTES, 'cp1251' ) ) );
$fromnewsdate = $db->safesql( trim( htmlspecialchars( stripslashes( $_REQUEST['fromnewsdate'] ), ENT_QUOTES, 'cp1251' ) ) );
$tonewsdate = $db->safesql( trim( htmlspecialchars( stripslashes( $_REQUEST['tonewsdate'] ), ENT_QUOTES, 'cp1251' ) ) );



 
Также не отображалось содержимое шаблона в админке. Исправляется файл engine/ajax/templates.php для одних версий dle:
строка (№176)


$content = @htmlspecialchars( file_get_contents( $root.$file_path."/".$file_name ), ENT_QUOTES );

меняется на


$content = @htmlspecialchars( file_get_contents( $root.$file_path."/".$file_name ), ENT_QUOTES, 'cp1251' );


или файл engine/inc/templates.php для других версий:
строка (№224)


return htmlspecialchars( $text, ENT_QUOTES );

заменить на


return htmlspecialchars( $text, ENT_QUOTES, 'cp1251' );


 
При сохранении настроек пропадали название сайта, ключевые слова и прочие ячейки с русскми словами. Для исправления в файле options.php строкау (№1102)


$value = htmlspecialchars( $value);

заменить на


$value = htmlspecialchars( $value, ENT_COMPAT, 'cp1251');


и строку (№1106)


$name = htmlspecialchars( $name, ENT_QUOTES );

заменить на


$name = htmlspecialchars( $name, ENT_QUOTES, 'cp1251' );


 
Это те проблемы, которые были замечены в первую очередь. Вероятно, и даже наверняка, потребуется где-то еще функции htmlspecialchars указывать кодировку. Следует доработать все вызовы функции в движке.
При вызове с одним аргументом добавляем:


, ENT_COMPAT, 'cp1251'

Пр вызове с двумя аргументами добавляем:


, 'cp1251'

В некоторых случаях ничего менять не требуется, например:


$name = $db->safesql(trim(htmlspecialchars($parse->process(convert_unicode($_POST['name'], $config['charset'])))));


 
Еще одна замеченная проблема некоторых старых версий dle при переходе на php 5.4 — не работает авторизация. Точнее, при авторизации админпанель есть, сам сайт не отображается. При выходе из админпанели сайт работает. Проблема оказалась в функции session_register, которая перестала поддерживаться в php 5.4. Нужно сделать поиск по содержимому файлов dle, найти все вызовы этой функции и удалить или заремировать ее. Скорее всего, это будут файлы init.php, modules/addnews.php, modules/register.php, modules/sitelogin.php.

 
Еще одна замеченная ошибка дле на php 5.4:
Deprecated: mysql_escape_string(): This function is deprecated; use mysql_real_escape_string() instead. in /var/www/cs-w/data/www/cs-w.net/engine/classes/mysqli.class.php on line 162

Причем из-за ошибки сайт может как полностью не работать, так и открываться с ошибкой. Во втором случае иногда из-за дизайна ошибки не видно на экране, нужно смотреть код страницы.

Возникает ошибка из-за того, что устарела функция mysql_escape_string. Решение:
в файле engine\classes\mysqli.class.php строку (№162)


else return mysql_escape_string($source);

заменить на строку


else return ($source);


Эта же ошибка появится при попытке сделать бекап базы через админку. Исправляем:
в файле engine\inc\dumper.php строку (№286)


$row[$k] = isset($row[$k]) ? "'" . mysql_escape_string($row[$k]) . "'" : "NULL";

меняем на


$row[$k] = isset($row[$k]) ? "'" . mysql_real_escape_string($row[$k]) . "'" : "NULL";


 
И еще ошибка, которая появилась при переходе на php 5.4 на движках, ранее подправленных под версию 5.3.
Fatal error: Call-time pass-by-reference has been removed in
Теперь указание знака амперсанда (&) перед переменной при вызове функции вызывает фатальную ошибку и, как следствие, остановку выполнения дальнейшего кода. Указывать знак амперсанда теперь нужно только в определении функции. В общем, нужно убрать знак амперсанда в строке на которую указывает ошибка.

Поделитесь, пожалуйста:

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