Code: Select all
$table_prefix = 'firstboard.phpbb_';
$table_shared = 'secondboard.phpbb_';
Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id
FROM ' . USERS_TABLE . ' u
LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1)
GROUP BY u.user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}");
}
$db->sql_freeresult($result);
Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id
FROM ' . USERS_TABLE . ' u
LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1)
GROUP BY u.user_id';
$result = $db->sql_query($sql);
$user_data = array();
while ($row = $db->sql_fetchrow($result))
{
$user_data[$row['user_id']] = (int) $row['num_posts'];
}
$db->sql_freeresult($result);
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id
FROM ' . USERS_TABLE . ' u
LEFT JOIN properprefix_posts p ON (u.user_id = p.poster_id AND p.post_postcount = 1)
GROUP BY u.user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (!empty($user_data[$row['user_id']]))
{
$row['num_posts'] += $user_data[$row['user_id']];
}
$db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}");
}
$db->sql_freeresult($result);
dcz wrote:Seemed easier than I though, in includes/acp/acp_main.php, you can replace :with :Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}"); } $db->sql_freeresult($result);
In this you just have to set the properprefix_posts to the proper value for the second board.Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); $user_data = array(); while ($row = $db->sql_fetchrow($result)) { $user_data[$row['user_id']] = $row['num_posts']; } $db->sql_freeresult($result); $sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN properprefix_posts p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $row['num_posts'] += $user_data[$row['user_id']]; $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}"); } $db->sql_freeresult($result);
And so on for all others.
Note that the original code is a bit heavy for very large board, it's performing a query per user so ...
Adding the extra counting does not change much though, I tested this with over 5000 users without issues.
And the good thing is that the user post pages will only consider the local amount, so results will stay consistent, while the total amount will be kept in user profiles
Enjoy
++
Yes.This makes it so that the post counts are the same per user across multiple boards, is that correct?
Code: Select all
@unlink('path_to_the_slave_forum/cache/' . basename($filename));
Code: Select all
/**
* Removes/unlinks file
*/
function remove_file($filename, $check = false)
{
Code: Select all
includes/acm/acm_file.php
Hey there dcz,dcz wrote:Yes.This makes it so that the post counts are the same per user across multiple boards, is that correct?
By the way, I edited the post above to add some sanity checks in the code, not that it could cause trouble but could through some notice about the user_data count to be not set in some of the shared forums.
For the cache thing, you could clear every boards's cache at once, adding something like :
after :Code: Select all
@unlink('path_to_the_slave_forum/cache/' . basename($filename));
in :Code: Select all
/** * Removes/unlinks file */ function remove_file($filename, $check = false) {
Should work to clear the same file name's cache file currently cleared in the other forum cache dir, if the server's set up allows you to. To make it short, it will in most cases imply that all forums are installed within the same ftp account to work.Code: Select all
includes/acm/acm_file.php
Will of course cause unlink to unlink nothing in some cases, but I'm pretty sure it's faster to directly unlink than to first check if the target file exists so.
++
This is great! Seems to work perfectly for me too! The only thing I have tested yet is if I try to reset user message count from the ACP, will it set the message count of users who haven't posted on the forum which I'm working from to 0? Or does your Mod also solve that?dcz wrote:Seemed easier than I though, in includes/acp/acp_main.php, you can replace :with :Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}"); } $db->sql_freeresult($result);
In this you just have to set the properprefix_posts to the proper value for the second board.Code: Select all
$sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN ' . POSTS_TABLE . ' p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); $user_data = array(); while ($row = $db->sql_fetchrow($result)) { $user_data[$row['user_id']] = (int) $row['num_posts']; } $db->sql_freeresult($result); $sql = 'SELECT COUNT(p.post_id) AS num_posts, u.user_id FROM ' . USERS_TABLE . ' u LEFT JOIN properprefix_posts p ON (u.user_id = p.poster_id AND p.post_postcount = 1) GROUP BY u.user_id'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { if (!empty($user_data[$row['user_id']])) { $row['num_posts'] += $user_data[$row['user_id']]; } $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_posts = {$row['num_posts']} WHERE user_id = {$row['user_id']}"); } $db->sql_freeresult($result);
And so on for all others.
Note that the original code is a bit heavy for very large board, it's performing a query per user so ...
Adding the extra counting does not change much though, I tested this with over 5000 users without issues.
And the good thing is that the user post pages will only consider the local amount, so results will stay consistent, while the total amount will be kept in user profiles
Enjoy
++
Code: Select all
cookie domain : .example.com (with the dot ".")
cookie path : /
Code: Select all
function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false)
{
global $db, $auth, $phpbb_root_path, $phpEx, $config;
// We need both username and user_id info
$result = user_get_id_name($user_id_ary, $username_ary);
if (!sizeof($user_id_ary) || $result !== false)
{
return 'NO_USERS';
}
if (!$group_name)
{
$group_name = get_group_name($group_id);
}
switch ($action)
{
case 'demote':
case 'promote':
$sql = 'SELECT user_id FROM ' . USER_GROUP_TABLE . "
WHERE group_id = $group_id
AND user_pending = 1
AND " . $db->sql_in_set('user_id', $user_id_ary);
$result = $db->sql_query_limit($sql, 1);
$not_empty = ($db->sql_fetchrow($result));
$db->sql_freeresult($result);
if ($not_empty)
{
return 'NO_VALID_USERS';
}
$sql = 'UPDATE ' . USER_GROUP_TABLE . '
SET group_leader = ' . (($action == 'promote') ? 1 : 0) . "
WHERE group_id = $group_id
AND user_pending = 0
AND " . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
$log = ($action == 'promote') ? 'LOG_GROUP_PROMOTED' : 'LOG_GROUP_DEMOTED';
break;
case 'approve':
// Make sure we only approve those which are pending ;)
$sql = 'SELECT u.user_id, u.user_email, u.username, u.username_clean, u.user_notify_type, u.user_jabber, u.user_lang
FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
WHERE ug.group_id = ' . $group_id . '
AND ug.user_pending = 1
AND ug.user_id = u.user_id
AND ' . $db->sql_in_set('ug.user_id', $user_id_ary);
$result = $db->sql_query($sql);
$user_id_ary = $email_users = array();
while ($row = $db->sql_fetchrow($result))
{
$user_id_ary[] = $row['user_id'];
$email_users[] = $row;
}
$db->sql_freeresult($result);
if (!sizeof($user_id_ary))
{
return false;
}
$sql = 'UPDATE ' . USER_GROUP_TABLE . "
SET user_pending = 0
WHERE group_id = $group_id
AND " . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
// Send approved email to users...
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$messenger = new messenger();
foreach ($email_users as $row)
{
$messenger->template('group_approved', $row['user_lang']);
$messenger->to($row['user_email'], $row['username']);
$messenger->im($row['user_jabber'], $row['username']);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($row['username']),
'GROUP_NAME' => htmlspecialchars_decode($group_name),
'U_GROUP' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership")
);
$messenger->send($row['user_notify_type']);
}
$messenger->save_queue();
$log = 'LOG_USERS_APPROVED';
break;
case 'default':
$sql = 'SELECT user_id, group_id FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary, false, true);
$result = $db->sql_query($sql);
$groups = array();
while ($row = $db->sql_fetchrow($result))
{
if (!isset($groups[$row['group_id']]))
{
$groups[$row['group_id']] = array();
}
$groups[$row['group_id']][] = $row['user_id'];
}
$db->sql_freeresult($result);
foreach ($groups as $gid => $uids)
{
remove_default_rank($gid, $uids);
remove_default_avatar($gid, $uids);
}
group_set_user_default($group_id, $user_id_ary, $group_attributes);
$log = 'LOG_GROUP_DEFAULTS';
break;
}
// Clear permissions cache of relevant users
$auth->acl_clear_prefetch($user_id_ary);
add_log('admin', $log, $group_name, implode(', ', $username_ary));
group_update_listings($group_id);
return false;
}
Code: Select all
group_set_user_default($group_id, $user_id_ary, $group_attributes);
Code: Select all
'user_colour'
Code: Select all
define('LOCAL_KEY', '_alpha');
Code: Select all
settype($group_attributes[$attribute], $type);
$sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute];
Code: Select all
function group_set_user_default($group_id, $user_id_ary, $group_attributes = false, $update_listing = false)
{
global $db;
if (empty($user_id_ary))
{
return;
}
$attribute_ary = array(
'group_colour' => 'string',
'group_rank' => 'int',
'group_avatar' => 'string',
'group_avatar_type' => 'int',
'group_avatar_width' => 'int',
'group_avatar_height' => 'int',
);
$sql_ary = array(
'group_id' => $group_id
);
// Were group attributes passed to the function? If not we need to obtain them
if ($group_attributes === false)
{
$sql = 'SELECT ' . implode(', ', array_keys($attribute_ary)) . '
FROM ' . GROUPS_TABLE . "
WHERE group_id = $group_id";
$result = $db->sql_query($sql);
$group_attributes = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
}
foreach ($attribute_ary as $attribute => $type)
{
if (isset($group_attributes[$attribute]))
{
// If we are about to set an avatar or rank, we will not overwrite with empty, unless we are not actually changing the default group
if ((strpos($attribute, 'group_avatar') === 0 || strpos($attribute, 'group_rank') === 0) && !$group_attributes[$attribute])
{
continue;
}
settype($group_attributes[$attribute], $type);
$sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute];
}
}
// Before we update the user attributes, we will make a list of those having now the group avatar assigned
if (isset($sql_ary['user_avatar']))
{
// Ok, get the original avatar data from users having an uploaded one (we need to remove these from the filesystem)
$sql = 'SELECT user_id, group_id, user_avatar
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . '
AND user_avatar_type = ' . AVATAR_UPLOAD;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
avatar_delete('user', $row);
}
$db->sql_freeresult($result);
}
else
{
unset($sql_ary['user_avatar_type']);
unset($sql_ary['user_avatar_height']);
unset($sql_ary['user_avatar_width']);
}
$sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
WHERE ' . $db->sql_in_set('user_id', $user_id_ary);
$db->sql_query($sql);
if (isset($sql_ary['msrp_colour']))
{
// Update any cached colour information for these users
$sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_last_poster_colour = '" . $db->sql_escape($sql_ary['msrp_colour']) . "'
WHERE " . $db->sql_in_set('forum_last_poster_id', $user_id_ary);
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_first_poster_colour = '" . $db->sql_escape($sql_ary['msrp_colour']) . "'
WHERE " . $db->sql_in_set('topic_poster', $user_id_ary);
$db->sql_query($sql);
$sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_last_poster_colour = '" . $db->sql_escape($sql_ary['msrp_colour']) . "'
WHERE " . $db->sql_in_set('topic_last_poster_id', $user_id_ary);
$db->sql_query($sql);
global $cache, $phpbb_root_path, $phpEx, $table_prefix;
include($phpbb_root_path . 'includes/arcade/arcade_constants.' . $phpEx);
$sql = 'UPDATE ' . ARCADE_CATS_TABLE . " SET cat_last_play_user_colour = '" . $db->sql_escape($sql_ary['msrp_colour']) . "'
WHERE " . $db->sql_in_set('cat_last_play_user_id', $user_id_ary);
$db->sql_query($sql);
$cache->destroy('sql', ARCADE_CATS_TABLE);
$cache->destroy('sql', ARCADE_GAMES_TABLE);
$cache->destroy('sql', ARCADE_SCORES_TABLE);
$cache->destroy('_arcade_leaders');
global $config;
if (in_array($config['newest_user_id'], $user_id_ary))
{
set_config('newest_msrp_colour', $sql_ary['msrp_colour'], true);
}
}
if ($update_listing)
{
group_update_listings($group_id);
}
}
Bah! This must mean something else is being set within it to allow for it to use user_colour as a full line, but if I add that it just curls up and dies.SQL ERROR [ mysql4 ]
Unknown column 'msrp_' in 'field list' [1054]
SQL
UPDATE station_area52main.phpbb_users SET group_id = 5, msrp_ = NULL WHERE user_id = 2
Now I have made some progress I think! Just need to figure out this null thing, but I have a hunch my answer is at the top of functions_user.php file. Might or might not.SQL ERROR [ mysql4 ]
Column 'msrp_colour' cannot be null [1048]
SQL
UPDATE station_area52main.phpbb_users SET group_id = 5, msrp_colour = NULL WHERE user_id = 2
Code: Select all
'user_colour' => ' ',
Code: Select all
'msrp_colour' => ' ',