[alpha] Real User Posts - valid code

Здесь авторы могут постить бета-версии своих модификаций для phpBB 2.0.x. Внимание! Не устанавливайте бета-версии модов на работающие форумы!

[alpha] Real User Posts - valid code

Сообщение quazi 11.01.2006 8:40

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

кажется на форуме упоминался некий мод, корректирующий сие явление, что есть лишь временное лекарство

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

и еще. я практически не слежу за официальными обновлениями - по причине глубокой модификации форума. поэтому личная рекомендация тестерам
1. на рабочий форум не ставить, тестировать локально
2. фраза "найти" указывает на фрагменты файлов форума версии 2.0.19
3. фраза "заменить на" указывает на фрамент кода, в который случайно попал фрагмент другой модификации

возможно, что похожее предложение уже существует, возможно оно лучше - в таком случае покажите. будет интересно сравнить

и так

открыть memberlist.php

найти
Код: Выделить всё
$sql = "SELECT username, user_id, user_viewemail, user_posts, user_regdate, user_from, user_website, user_email, user_icq, user_aim, user_yim, user_msnm, user_avatar, user_avatar_type, user_allowavatar
        FROM " . USERS_TABLE . "
        WHERE user_id <> " . ANONYMOUS . "
        ORDER BY $order_by";


заменить на
Код: Выделить всё
$sql = "SELECT u.*, COUNT(p.poster_id) AS real_posts
        FROM " . USERS_TABLE . " u
        LEFT JOIN " . POSTS_TABLE . " p ON p.poster_id = u.user_id
        WHERE user_id <> " . ANONYMOUS . "
        GROUP BY u.user_id
        ORDER BY $order_by";


найти
Код: Выделить всё
               $posts = ( $row['user_posts'] ) ? $row['user_posts'] : 0;


заменить на
Код: Выделить всё
                $posts = ( $row['real_posts'] ) ? $row['real_posts'] : 0;


открыть viewtopic.php

найти
Код: Выделить всё
$sql = "SELECT u.username, u.user_id, u.user_posts, u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim, u.user_yim, u.user_regdate, u.user_msnm, u.user_viewemail, u.user_rank, u.user_sig, u.user_sig_bbcode_uid, u.user_avatar, u.user_avatar_type, u.user_allowavatar, u.user_allowsmile, p.*,  pt.post_text, pt.post_subject, pt.bbcode_uid
        FROM " . POSTS_TABLE . " p, " . USERS_TABLE . " u, " . POSTS_TEXT_TABLE . " pt
        WHERE p.topic_id = $topic_id
                $limit_posts_time
                AND pt.post_id = p.post_id
                AND u.user_id = p.poster_id
        ORDER BY p.post_time $post_time_order
        LIMIT $start, ".$board_config['posts_per_page'];


заменить на
Код: Выделить всё
$sql = "SELECT u.*, p.*, pt.post_text, pt.post_subject, pt.bbcode_uid, COUNT( u.user_id ) real_posts
        FROM " . POSTS_TABLE . " p, " . USERS_TABLE . " u, " . POSTS_TEXT_TABLE . " pt
        LEFT JOIN " . POSTS_TABLE . " pp ON pp.poster_id = u.user_id
        WHERE p.topic_id = $topic_id
                $limit_posts_time
                AND pt.post_id = p.post_id
                AND p.poster_id = u.user_id
        GROUP BY p.post_id
        ORDER BY p.post_time $post_time_order
        LIMIT $start, " . $board_config['posts_per_page'];


найти
Код: Выделить всё
        $poster_posts = ( $postrow[$i]['user_id'] != ANONYMOUS ) ? $lang['Posts'] . ': ' . $postrow[$i]['user_posts'] : '';


заменить на
Код: Выделить всё
        $poster_posts = ( $postrow[$i]['user_id'] != ANONYMOUS ) ? $lang['Posts'] . ': ' . $postrow[$i]['real_posts']: '';


открыть includes/functions.php

найти
Код: Выделить всё
        $sql = "SELECT *
                FROM " . USERS_TABLE . "
                WHERE ";
        $sql .= ( ( is_integer($user) ) ? "user_id = $user" : "username = '" .  str_replace("\'", "''", $user) . "'" ) . " AND user_id <> " . ANONYMOUS;


заменить на
Код: Выделить всё
        $_user = ( is_integer($user) ) ? "u.user_id = $user" : "u.username = '" . $user . "'";
        $sql = "SELECT u.*, COUNT(p.poster_id) AS real_posts
                FROM " . USERS_TABLE . " u
                LEFT JOIN " . POSTS_TABLE . " p ON p.poster_id = u.user_id
                WHERE $_user
                GROUP BY u.user_id";


открыть includes/usercp_viewprofile.php

найти
Код: Выделить всё
        'POSTS' => $profiledata['user_posts'],


заменить на
Код: Выделить всё
        'POSTS' => $profiledata['real_posts'],
quazi
phpBB 2.0.8
 
Сообщения: 314
Зарегистрирован: 15.03.2005 19:49


Сообщение Xpert 11.01.2006 9:22

Единственное что мне не нравится в данной модификации - это повышение нагрузки. Оно допустимо везде кроме viewtopic...
Эксперт - это человек, который избегает мелких ошибок на пути к грандиозному провалу.
Любая более-менее сложная задача имеет несколько простых, изящных, лёгких для понимания неправильных решений
Аватара пользователя
Xpert
phpBB Guru
 
Сообщения: 5716
Зарегистрирован: 13.03.2004 22:27
Откуда: msk.ru

Сообщение quazi 11.01.2006 10:28

я думал над этим

в просмотре топиков действительно используется достаточно сложный запрос с левыми джойнами, что самое печальное в таком виде на некоторых запросах время выполнения запроса увеличивается примерно в 3-10 раз.
quazi
phpBB 2.0.8
 
Сообщения: 314
Зарегистрирован: 15.03.2005 19:49

Сообщение Xpert 11.01.2006 13:59

На самом деле я давно не сталкивался с рассинхронизацией числа сообщений. Так что очень может быть что предложенное здесь решение излишне.
Эксперт - это человек, который избегает мелких ошибок на пути к грандиозному провалу.
Любая более-менее сложная задача имеет несколько простых, изящных, лёгких для понимания неправильных решений
Аватара пользователя
Xpert
phpBB Guru
 
Сообщения: 5716
Зарегистрирован: 13.03.2004 22:27
Откуда: msk.ru

Сообщение quazi 27.01.2006 1:32

в продолжение темы

открыть groupcp.php

найти
Код: Выделить всё
   $posts = ( $row['user_posts'] ) ? $row['user_posts'] : 0;


заменить на
Код: Выделить всё
   // +Real Users Posts - valid code
   $posts = isset($row['real_posts']) ? $row['real_posts'] : ( ( $row['user_posts'] ) ? $row['user_posts'] : 0 );
   // -Real Users Posts - valid code


найти
Код: Выделить всё
   $sql = "SELECT username, user_id, user_viewemail, user_posts, user_regdate, user_from, user_website, user_email, user_icq, user_aim, user_yim, user_msnm
      FROM " . USERS_TABLE . "
      WHERE user_id = " . $group_info['group_moderator'];


заменить на
Код: Выделить всё
   // +Real Users Posts - valid code
   $sql = "SELECT username, user_id, user_viewemail, user_posts, user_regdate, user_from, user_website, user_email, user_icq, user_aim, user_yim, user_msnm
         , COUNT(p.poster_id) AS real_posts
      FROM " . USERS_TABLE . " u
      LEFT JOIN " . POSTS_TABLE . " p ON p.poster_id = u.user_id
      WHERE user_id = " . $group_info['group_moderator'] . "
      GROUP BY u.user_id";
   // -Real Users Posts - valid code


найти
Код: Выделить всё
   $sql = "SELECT u.username, u.user_id, u.user_viewemail, u.user_posts, u.user_regdate, u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim, u.user_yim, u.user_msnm, ug.user_pending
      FROM " . USERS_TABLE . " u, " . USER_GROUP_TABLE . " ug
      WHERE ug.group_id = $group_id
         AND u.user_id = ug.user_id
         AND ug.user_pending = 0
         AND ug.user_id <> " . $group_moderator['user_id'] . "
      ORDER BY u.username";


заменить на
Код: Выделить всё
   // +Real Users Posts - valid code
   $sql = "SELECT u.username, u.user_id, u.user_viewemail, u.user_posts, u.user_regdate, u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim, u.user_yim, u.user_msnm, ug.user_pending
         , COUNT(p.poster_id) AS real_posts
      FROM " . USERS_TABLE . " u, " . USER_GROUP_TABLE . " ug
      LEFT JOIN " . POSTS_TABLE . " p ON p.poster_id = u.user_id
      WHERE ug.group_id = $group_id
         AND u.user_id = ug.user_id
         AND ug.user_pending = 0
         AND ug.user_id <> " . $group_moderator['user_id'] . "
      GROUP BY u.user_id
      ORDER BY u.username";
   // -Real Users Posts - valid code


найти
Код: Выделить всё
   $sql = "SELECT u.username, u.user_id, u.user_viewemail, u.user_posts, u.user_regdate, u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim, u.user_yim, u.user_msnm
      FROM " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug, " . USERS_TABLE . " u
      WHERE ug.group_id = $group_id
         AND g.group_id = ug.group_id
         AND ug.user_pending = 1
         AND u.user_id = ug.user_id
      ORDER BY u.username";


заменить на
Код: Выделить всё
   // +Real Users Posts - valid code
   $sql = "SELECT u.username, u.user_id, u.user_viewemail, u.user_posts, u.user_regdate, u.user_from, u.user_website, u.user_email, u.user_icq, u.user_aim, u.user_yim, u.user_msnm
         , COUNT(p.poster_id) AS real_posts
      FROM " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug, " . USERS_TABLE . " u
      LEFT JOIN " . POSTS_TABLE . " p ON p.poster_id = u.user_id
      WHERE ug.group_id = $group_id
         AND g.group_id = ug.group_id
         AND ug.user_pending = 1
         AND u.user_id = ug.user_id
      GROUP BY u.user_id
      ORDER BY u.username";
   // -Real Users Posts - valid code


все это рассматривается исключительно с целью сохранности целостности данных ( о чем я уже писал в первом посте )

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

возможно продолжение следует
quazi
phpBB 2.0.8
 
Сообщения: 314
Зарегистрирован: 15.03.2005 19:49

Сообщение ETZel 27.01.2006 10:15

quazi
Лучше не наргужать запросы лишним join (в конце концов, поле user_posts существует именно для ускорения запросов).
Надо в админке сделать кнопочку "resync", при нажатии на которую целостность бы восстанавливалась (по аналогии с форумными resync).
Рассинхронизация происходит очень редко => ручного способа корректировки достаточно.
Аватара пользователя
ETZel
phpBB 1.4.4
 
Сообщения: 97
Зарегистрирован: 03.01.2006 11:47
Откуда: Челябинск

Сообщение quazi 27.01.2006 10:57

практика говорит (не утверждает и тем более не постулирует), что лучше один большой запрос вместо нескольких маленьких

но это не аксиома... все зависит от многих факторов - в превую очередь зависит от СУБД
quazi
phpBB 2.0.8
 
Сообщения: 314
Зарегистрирован: 15.03.2005 19:49

Сообщение Поручик 27.01.2006 17:24

ETZel писал(а):Надо в админке сделать кнопочку "resync",

И еще есть такой мод.

Добавлено спустя 41 минуту 44 секунды:

Вчера на оффсайте откопал
Код: Выделить всё
##########################################
## MOD Title: Post Count Resync
## MOD Version: 1.2.1
## Author: R45 < adam at (@) rasadam.com > Adam Alkins - http://www.rasadam.com
## Description: This is an admin module for the ACP system. It will allow you to resync all user's post
##              counts to their correct figure.
Профессионал - тот же дилетант, только знающий, где ошибётся.
Генератор db_update.php для phpBB2 с некоторыми удобствами. Многие моды я беру или ищу здесь, здесь, тут
Все консультации только на форуме, приваты и стук в аську по таким вопросам игнорируются!
FAQ-phpBB2 | FAQ-phpBB3 | Ошибки новичков, или как не поссориться с модератором | Правила конференции

наш форум http://forum.aeroion.ru/
Аватара пользователя
Поручик
Его Благородие
Его Благородие
 
Сообщения: 3769
Зарегистрирован: 12.05.2005 17:25
Откуда: Оренбург (Южный Урал)

Сообщение quazi 27.01.2006 18:15

Поручик писал(а):Post Count Resync

мне знаком этот мод

мое мнение это костыль
quazi
phpBB 2.0.8
 
Сообщения: 314
Зарегистрирован: 15.03.2005 19:49


Вернуться в Бета-версии модов для phpBB 2.0.x

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0