ОсновноеRadiotalkПользовательское
VOC++ чаты (больше не поддерживаются)
3   •   Посмотреть все темы

Исправление ошибок в коде чатов VOC++

 

327
Геннадий @mychatik
В коде чатов VOC++, к сожалению, довольно много ошибок.
К тому же, некоторые переменные и функции, используемые в коде чата и некоторых модов - являются уже устаревшими и подлежат замене.

И хотя эти ошибки пока не стали критичными, и чат с ними работоспособен, их наличие может проявиться при смене версии php или переносе на другой сервер, который перестал поддерживать устаревшие функции, либо сказываться на кроссбраузерности и СЕО.

В этой теме буду выкладывать способы исправления данных проблем.
Все предложенные правки - 100% рабочие, сделаны и протестированы мною в чате «Глобус».

Не обязательно делать все изменения сразу. Можно заменять по мере их обнаружения, во время установки модов, или правки кода.
Если вы сразу замените не все, а только часть устаревших функций, то от этого чат не "сломается", а будет работать, как и работал.

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

Напоминаю, что перед правкой файла (особенно с заменой функций) - обязательно (!!!) делайте его бэкап!

327
Геннадий @mychatik
И начнем с самого начала. С заголовка страницы - DOCTYPE.

Согласно спецификациям HTML и XHTML тег DOCTYPE (что означает «объявление типа документа») сообщает валидатору, какую именно версию (X)HTMLвы используете в своей странице. Этот тег должен всегда находиться в первой строке каждой страницы сайта.
Тег DOCTYPE — ключевой компонент web-страниц, претендующих на соответствие стандартам: без него ваш код и CSS не пройдут проверку валидатором.
Он также важен для правильного отображения и работы страницы в броузерах, соответствующих стандартам (Mozilla, IE5/Mac, и IE6/Win).
Тег, в атрибутах которого указывается полный URI (полный web-адрес), сообщает броузерам, что страницу нужно вывести с соблюдением определенного стандарта или подвида этого стандарта.
Если вы будете пользоваться неполным тегом DOCTYPE, устаревшим его видом, или вообще забудете про него, броузер перейдет в «загадочный» (quirk) режим и будет исходить из предположения, что вы писали код страницы с ошибками и вольно отступали от стандартов, т.е. так, как писали в конце 90-ых годов.
В этом режиме броузер попытается разобрать вашу страницу по правилам обратной совместимости и выведет на экран, например, CSS так, как его вывел бы Internet Explorer 4-ой версии, а DOM будет работать так, как он работал именно в этом броузере (IE переключается в свой старый DOM, а Mozilla и Netscape 6 переключается вообще в непонятно что).
Понятно, что для вас эти выкрутасы не желательны. Но именно это вы можете получить, если будете пользоваться неполным или неправильным тегом DOCTYPE.

В файлах /js_frameset.php, /дизайн/fullinfo.php и /admin/index.php указан DOCTYPE, как
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
Но этот DOCTYPE - для обычных страниц. И он невалиден для документов с фреймами, которыми и являются указанные файлы.

Его необходимо заменить на
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
Этот DTD идентичен HTML 4.01 Transitional DTD, за исключением содержимого <HTML>: в наборе фреймов, тег <FRAMESET> заменяет тег <BODY>.

К тому же указанный в чате DOCTYPE - устаревший.
На остальных страницах нужно только сменить версию с HTML 4.0 на HTML 4.01.

В одной из сборок я встретил вообще раритетный DOCTYPE (спецификация 1995 г.)
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//RU//4.0">
Если у вас тоже что-то подобное - меняем на правильный.

327
Геннадий @mychatik
Замена $HTTP_SERVER_VARS на $_SERVER
Замена $HTTP_GET_VARS на $_GET
Замена $HTTP_POST_VARS на $_POST
Замена $HTTP_POST_FILES на $_FILES
Замена $HTTP_ENV_VARS на $_ENV

В PHP » 4.1.0 были добавлены суперглобальные массивы:
$_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, $_REQUEST, $_SESSION и $ _FILES.
А с PHP 5.4.0, старые массивы $HTTP_*_VARS и $HTTP_POST_FILES удалены.

Соответственно, $HTTP_GET_VARS устарел и заменён на суперглобальный массив $_GET, $HTTP_POST_VARS — на $_POST и т.д.

Например, в /admin/check_session.php необходимо найти:
while (list($var, $val) = each($HTTP_GET_VARS)) $$var = $val;
while (list($var, $val) = each($HTTP_POST_VARS)) $$var = $val;

и заменить на:
while (list($var, $val) = each($_GET)) ${$var} = $val;
while (list($var, $val) = each($_POST)) ${$var} = $val;

В /data/engine/files/log_message.php, кроме замены устаревших массивов, необходимо удалить один из них:
в строке (в файле она встречается 3 раза):
global $data_path, $HTTP_SERVER_VARS;

удаляем всё, выделенное красным.
То же самое и в /inc_common.php:
global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, ${$variable_name};

Делается это потому, что массивы $_SERVER, $_GET, $_POST, $_COOKIE и так уже является суперглобальными (т.е. доступными в любом месте скрипта), поэтому дополнительное указание для них не нужно.
--------------------------------------

Файлы, в которых необходима замена:

Эта информация скрыта и доступна только зарегистрированным пользователям.

327
Геннадий @mychatik
Переменные переменных (символические ссылки)

Переменная переменная берет значение переменной и рассматривает его как имя переменной.
То есть, это имя переменной, которое может быть определено и изменено динамически.
Переменная переменная обозначается оператором $$.

$foo = 'bar';
$bar = 'I am text';
echo $$foo; // I am text

В выражение $$foo вместо $foo будет подставлено его значение и получится $bar.

Теоретически, знаков $ перед именем переменной может быть сколько угодно.

$Bar = "a";
$Foo = "Bar";
$World = "Foo";
$Hello = "World";
$a = "Hello";

$a; // выведет Hello
$$a; // выведет World
$$$a; // выведет Foo
$$$$a; // выведет Bar
$$$$$a; // выведет a

$$$$$$a; // выведет Hello
$$$$$$$a; // выведет World

//... и так далее ...//

Подробнее можно прочитать **********.

Этот синтаксис уже устарел в PHP5, а в PHP7 - удалён.
Для эмуляции предыдущего поведения необходимо использовать фигурные скобки.

Переменные переменные используются довольно редко, но в коде чата они есть.
Поэтому, если вы при редактировании кода встретите запись, подобную $$var = ... - её нужно заменить на ${$var} = ...

Примеры подобной замены - в предыдущем посте.

------------------------------------

Файлы, требующие редактирования:

Эта информация скрыта и доступна только зарегистрированным пользователям.

327
Геннадий @mychatik
Замена ereg (eregi) на preg_match
Замена ereg_replace (ereg_replacei) на preg_repalce

(для тех, кто не в курсе, символ "i" в конце функции означает регистронезависимый поиск)

Начиная с PHP 5.3, разработчки решили избавиться от POSIX регулярных выражений (**********).
В самом деле, зачем нужны две библиотеки для работы с регулярными выражениями, если можно обойтись одной?
К тому же, POSIX регулярные выражения гораздо медленнее чем Perl совместимые регулярные выражения (PCRE).

Просто взять и заменить одно выражение на другое нельзя. Будет выдано сообщение об ошибке.
Для корректной замены, необходимо:

1. Заменить ereg и eregi на preg_match, ereg_replace и ereg_replacei на preg_repalce;
2. Добавить разделители в начало и конец регулярного выражения;
3. Если POSIX функция кончается на i (eregi, ereg_replacei), то добавить i в конец регулярного выражения, после разделителя.

P.S. Не забывайте экранировать обратным слешем \ мета-символы ^ $ * + - ? . \ |, если они используются в регулярных выражениях в качестве того символа, каким они есть, а не в качестве специального символа.

---------------------------------

Примеры замены:

В /admin/search.php ищем:
if (eregi($ttt,$t_nickname)) $users_to_show[] = $user;
и меняем на:
if (preg_match("/".$ttt."/i", $t_nickname)) $users_to_show[] = $user;
В этом файле можно сделать ещё лучше:
if (mb_stripos($t_nickname, $ttt) !== false) $users_to_show[] = $user;
P.S. Данная функция намного проще и быстрее регулярки, но её нужно использовать осторожно.
Не везде она сможет заменить регулярное выражение.
К примеру, если применить её в /data/engine/files/users_search.php - то поиск по * перестаёт работать.

В /plugins/antihack/plugin.php ищем:
$string = ereg_replace ("[^a-zA-Z0-9.]", "", $string);
и меняем на:
$string = preg_replace("/[^A-Za-z0-9\.]/", "", $string);
(В этом примере, спецсимвол . был заэкранирован)

---------------------------------

Я буду стараться выложить все файлы, где необходима замена.
Но если что упущу - добавляйте и спрашивайте, если не получается сделать самим.

Файлы, в которых необходимо производить замену (некоторых файлов у вас может не быть):

Эта информация скрыта и доступна только зарегистрированным пользователям.

327
Геннадий @mychatik
Замена split на explode или preg_split.

С версии PHP 5.3.0 функция split считается УСТАРЕВШЕЙ. В PHP 7.0 - удалена.

Меняется она на функцию explode, которая не использует регулярных выражений и поэтому работает намного быстрее.
Если же нужно разбить строку по регулярному выражению - тогда применяется более быстрая функция preg_split.

В чатах на движке VOC++ - все split меняются на explode, без каких-либо дополнительных изменений в коде.


Файлы, в которых нужна замена:

Эта информация скрыта и доступна только зарегистрированным пользователям.

327
Геннадий @mychatik
В некоторых чатах возникает проблема с ответами в викторине, при использовании юзером транслитерации.

Проблема заключается в том, что в языковом файле, в функции транслита, почему-то вместо русских букв написали аналогичные по виду английские.
И викторина, соответственно, их не принимает. Хотя на читаемость текста это не влияет.
Для исправления бага - полностью заменить аналогичный массив в languages/ru.php.

Вот исправленный мною и дополненный массив соответствия транслитерации => русским буквам:

Эта информация скрыта и доступна только зарегистрированным пользователям.

327
Геннадий @mychatik
Убираем дублирование атрибута style:

В чате "кликабельность" ника осуществляется подобным образом:
<a style='text-decoration: underline' style='{cursor: pointer}' onClick=\"javascript:parent.Whisper('НИК');\">НИК</a>
Вроде как всё в порядке. Данный код работает не один десяток лет во всех чатах на движке VOC++.
А вот валидатор ругается на двойной атрибут style в теге.
И до сих пор никто не обратил внимания, и не не устранил ошибку.

Исправляется очень просто:
<a style='text-decoration: underline; cursor: pointer;' onClick=\"javascript:parent.Whisper('НИК');\">НИК</a>
Эта строка встречается в коде чата много раз, в разных вариантах и в разных файлах.
В том числе и в главной админке Конфигурирование => Внешний вид => Шаблоны сообщений

327
Геннадий @mychatik
Проблема с Style Selection Plugin for VOC++ BSE от CyberDream

В чатах иногда замечается проблема, когда невозможно ничего сделать с подарками.
Ни удалить, ни вернуть, ни продать.

Проблема возникает только там, где установлен мод Style Selection Plugin for VOC++ BSE от CyberDream - товар набора шрифтов.
И именно тогда, когда был приобретён этот товар в магазине, но ещё не применён.
После применения данного товара - проблема с подарками исчезает.

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

Но оказалось, что это не глюк.
Проблема - в вышеназванном моде. Все его копии имеют ошибку в коде. То ли случайную, то ли кем-то внесённую.
В файле frontend.php мода отсутствует закрывающий тег формы </form>.

Для устранения проблемы достаточно добавить этот тег после всего кода.
Чтобы в конце было так:

<td><input type="Submit" class="input_button" value="OK"></td>
</tr>
</table>
</form>

P.S. Данный мод, выложенный мною на форуме - исправлен.

327
Геннадий @mychatik
В коде чата есть несколько неправильных записей кода цвета в шестнадцатеричном формате (не указан префикс «#»).

<font color=\"bf0d0d\">
Но сделано это не просто так.
В дальнейшем символ # с помощью регулярного выражения преобразуется в ник пользователя и правильная запись кода цвета приводит к неправильному выводу текста в чат.

Но можно исправить код так, чтобы и запись кода была правильной, и вывод сообщения - тоже.
Для этого нужно записать код цвета не в шестнадцатеричном HEX, а в десятичном RGB формате.

Для этого, открываем корневой файл voc.php и ищем строку:

$sw_rob_login = "<font color=\"bf0d0d\"><b>".$current_user->login_phrase."</b></font>";
И меняем её на:
$sw_rob_login = '<b style="color:rgb(191,13,13);">'.$current_user->login_phrase.'</b>';
То же самое делаем и в корневом who.php, только с двумя строками:
$sw_rob_login = "<font color=\"bf0d0d\"><b>".$current_user->login_phrase."</b></font>";
Меняем на:
$sw_rob_login = '<b style="color:rgb(191,13,13);">'.$current_user->login_phrase.'</b>';
И
$sw_rob_logout = "<font color=\"bf0d0d\"><b>".$current_user->logout_phrase."</b></font>";
Меняем на:
$sw_rob_logout = '<b style="color:rgb(191,13,13);">'.$current_user->logout_phrase.'</b>';
А в строке:
$sw_rob_login = str_replace("||", "<font color=\"bf0d0d\">".ucfirst($current_user->chat_status)."</font>", $sw_rob_login);
префикс # можно просто добавить:
$sw_rob_login = str_replace("||", '<font color="#bf0d0d">'.ucfirst($current_user->chat_status).'</font>', $sw_rob_login);
или сделать так:
$sw_rob_login = str_replace("||", '<span style="color:#bf0d0d;">'.ucfirst($current_user->chat_status).'</span>', $sw_rob_login);