Отлично
Попытаюсь разобраться.
Если счётчик постингов не накручивается, значит SQL-запрос, его поднимающий не выполняется. Поскольку там никаких транзакций нет, можно точно сказать что не выполняется сам код, выполняющий запрос.
Как поднимается число постингов:
есть такая функция
update_post_stats - она его и поднимает. Запрос выполняется в конце функции, вот его код, думаю, даже человеку не знающему php он будет понятен:
Враппер для подсветки синтаксиса писал(а):- Код: Выделить всё
if ($mode != 'poll_delete')
{
$sql = "UPDATE " . USERS_TABLE . "
SET user_posts = user_posts + 10 $sign
WHERE user_id = $user_id";
if (!$db->sql_query($sql, END_TRANSACTION))
{
message_die(GENERAL_ERROR, 'Error in posting', '', __LINE__, __FILE__, $sql);
}
}
return;
}
Многие сейчас начнут возмущаться... с сказал что никакой транзакции там нет, но сам выложил код, где невооруженным глазом видно, что запрос для увеличения находится в транзакции. Почему же всё таки я был прав:
Ну во-перых большая вероятность, что при установке форума, был указан тип СУБД - "MySQL 3.x" а не "MySQL 4.x / 5.x".
Для MySQL 3 , уровень абстракции базы данных (DAL) использует модуль db/mysql.php в котором не предусмотрена работа с транзакциями. Т.е. второй аргумент ф-ции query() просто игнорируется.
Допустим, что выбрали СУБД, поддерживающую транзакции - установщик phpBB2 создаёт таблицы типа MyISAM - которые тоже не поддерживают транзакции. Причём установщик не позволяет выбрать тип таблиц.
И даже если наша администрация в самом начале сама поменяла тип таблиц, ну, к примеру, на BerkeleyDB - всё равно, траназкция тут не причём, ибо код добавления самого постинга также находится в транзакции, и если б дело было именно в ней, этот запрос (добавление записи постинга, и его текста) тоже бы не выполнился...
Значит запрос-инкрементатор не выполнился только потому, что выполнение до него не дошло.
Так как в коде функции
update_post_stats нет никаких return-ов до этого кода, можно с уверенностью сказать что эту функцию вообще никто не вызывал.
Перелезаем на уровень выше (из includes/function_posts.php в posting.php).
Как происходит постинг:
Сначала идёт большая часть - проверка допуска (ведь posting.php предназначен не только для постинга. Он выполняет и множество других функций - правка постингов, начало тем, удаление тем, прилепление тем, голосование, квотинг и тд.).
После чего если $mode = 'reply', а mode=reply ибо по-другому спамбот ничего бы не запостил, вызывается три функции
prepare_post - подготавливает пост, парсит бб-коды, заменяет неразрешенные html-теги на <> эквивалент, делает замену запрещённых цензурой слов... и тд.
submit_post - добавляет постинг в базу, именно тут и начинается транзакция.
update_post_stats - о ней я уже говорил - изменяет статистику, увеличивает счётчики.
Для ясности приведу код:
Привет Гайдару, он испортил php-шную подсветку писал(а):- Код: Выделить всё
case 'reply':
$username = ( !empty($HTTP_POST_VARS['username']) ) ? $HTTP_POST_VARS['username'] : '';
$subject = ( !empty($HTTP_POST_VARS['subject']) ) ? trim($HTTP_POST_VARS['subject']) : '';
$message = ( !empty($HTTP_POST_VARS['message']) ) ? $HTTP_POST_VARS['message'] : '';
$poll_title = ( isset($HTTP_POST_VARS['poll_title']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_title'] : '';
$poll_options = ( isset($HTTP_POST_VARS['poll_option_text']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_option_text'] : '';
$poll_length = ( isset($HTTP_POST_VARS['poll_length']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_length'] : '';
$bbcode_uid = '';
prepare_post($mode, $post_data, $bbcode_on, $html_on, $smilies_on, $error_msg, $username, $bbcode_uid, $subject, $message, $poll_title, $poll_options, $poll_length);
if ( $error_msg == '' )
{
$topic_type = ( $topic_type != $post_data['topic_type'] && !$is_auth['auth_sticky'] && !$is_auth['auth_announce'] ) ? $post_data['topic_type'] : $topic_type;
submit_post($mode, $post_data, $return_message, $return_meta, $forum_id, $topic_id, $post_id, $poll_id, $topic_type, $bbcode_on, $html_on, $smilies_on, $attach_sig, $bbcode_uid, str_replace("\'", "''", $username), str_replace("\'", "''", $subject), str_replace("\'", "''", $message), str_replace("\'", "''", $poll_title), $poll_options, $poll_length);
}
break;
Сразу после switch-блока идёт вот что:
- Код: Выделить всё
if ( $error_msg == '' )
{
if ( $mode != 'editpost' )
{
$user_id = ( $mode == 'reply' || $mode == 'newtopic' ) ? $userdata['user_id'] : $post_data['poster_id'];
update_post_stats($mode, $post_data, $forum_id, $topic_id, $post_id, $user_id);
}
Теперь делаем выводы. Счётчик мог неизмениться только потому, что функцию update_post_stats вообще не вызвали. Это могло быть, если $error_msg содержала сообщение об ошибки.
Посмотрим выше, увидем, что error_msg передаётся в (причём по ссылки, что означает, что prepare_post должна поменять её значение, если произойдёт ошибка)
prepare_post НО НЕ ПЕРЕДАЁТСЯ submit_post ВООБЩЕ!.
Т.е. делаем вывод - update_post_stats не выполнилась из за того, что произошла ошибка в prepare_post. НО, как же тогда выполнилась submit_post если она также стоит а If- блоке, который не даст ей выполнится если в $error_msg - ошибка? Вопрос? Единственное что мне приходит на ум - пришёл мастер-ломастер и в попытках что то поменять, что там и правда поменял, причём так, что теперь происходит непонятно что.
Ещё как вариант - спамботы добрались до базы, и постят напрямую. Т.е. добавляя постинги в таблицу - а откуда тогда счётчик должен увеличиваться, и откуда тогда в таблице индексации слов что то возьмётся (ну это я к пункту 2).
Если разбираться, кто и что мог там поправить, и по какому случаю - единственное, что опять же мне кажется наиболее вероятным - неаккуратная установка Attachment MOD-а.