public function doit() { if (check_rule($this->rule) && ($this->function != null && (is_string($this->function) && function_exists($this->function) || is_callable($this->function)))) { actions_zone("before_page_{$this->code}"); call_user_func($this->function); actions_zone("after_page_{$this->code}"); } }
public function doit($params = null) { global $PAGE; if (check_rule($this->rule) && (!$this->auto || check_auto($PAGE->code, $this->auto))) { actions_zone("before_{$this->code}"); if ($this->function != null && (is_string($this->function) && function_exists($this->function) || is_callable($this->function))) { return call_user_func($this->function, $params); } actions_zone("after_{$this->code}"); } }
/** * Place new messages into appropriate folder */ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) { global $db, $user, $config; if (!$user->data['user_new_privmsg']) { return array('not_moved' => 0, 'removed' => 0); } $user_message_rules = (int) $user->data['user_message_rules']; $user_id = (int) $user->data['user_id']; $action_ary = $move_into_folder = array(); $num_removed = 0; // Newly processing on-hold messages if ($release) { $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_NO_BOX . ' WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . "\n\t\t\t\tAND user_id = {$user_id}"; $db->sql_query($sql); } // Get those messages not yet placed into any box $retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.group_id FROM ' . PRIVMSGS_TO_TABLE . ' t, ' . PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\tWHERE t.user_id = {$user_id}\n\t\t\tAND p.author_id = u.user_id\n\t\t\tAND t.folder_id = " . PRIVMSGS_NO_BOX . ' AND t.msg_id = p.msg_id'; // Just place into the appropriate arrays if no rules need to be checked if (!$user_message_rules) { $result = $db->sql_query($retrieve_sql); while ($row = $db->sql_fetchrow($result)) { $action_ary[$row['msg_id']][] = array('action' => false); } $db->sql_freeresult($result); } else { $user_rules = $zebra = $check_rows = array(); $user_ids = $memberships = array(); // First of all, grab all rules and retrieve friends/foes $sql = 'SELECT * FROM ' . PRIVMSGS_RULES_TABLE . "\n\t\t\tWHERE user_id = {$user_id}"; $result = $db->sql_query($sql); $user_rules = $db->sql_fetchrowset($result); $db->sql_freeresult($result); if (sizeof($user_rules)) { $sql = 'SELECT zebra_id, friend, foe FROM ' . ZEBRA_TABLE . "\n\t\t\t\tWHERE user_id = {$user_id}"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $zebra[$row['zebra_id']] = $row; } $db->sql_freeresult($result); } // Now build a bare-bone check_row array $result = $db->sql_query($retrieve_sql); while ($row = $db->sql_fetchrow($result)) { $check_rows[] = array_merge($row, array('to' => explode(':', $row['to_address']), 'bcc' => explode(':', $row['bcc_address']), 'friend' => isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['friend'] : 0, 'foe' => isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['foe'] : 0, 'user_in_group' => array($user->data['group_id']), 'author_in_group' => array())); $user_ids[] = $row['user_id']; } $db->sql_freeresult($result); // Retrieve user memberships if (sizeof($user_ids)) { $sql = 'SELECT * FROM ' . USER_GROUP_TABLE . ' WHERE ' . $db->sql_in_set('user_id', $user_ids) . ' AND user_pending = 0'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $memberships[$row['user_id']][] = $row['group_id']; } $db->sql_freeresult($result); } // Now place into the appropriate folder foreach ($check_rows as $row) { // Add membership if set if (isset($memberships[$row['author_id']])) { $row['author_in_group'] = $memberships[$row['user_id']]; } // Check Rule - this should be very quick since we have all information we need $is_match = false; foreach ($user_rules as $rule_row) { if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false) { $is_match = true; $action_ary[$row['msg_id']][] = $action; } } if (!$is_match) { $action_ary[$row['msg_id']][] = array('action' => false); } } unset($user_rules, $zebra, $check_rows, $user_ids, $memberships); } // We place actions into arrays, to save queries. $sql = $unread_ids = $delete_ids = $important_ids = array(); foreach ($action_ary as $msg_id => $msg_ary) { // It is allowed to execute actions more than once, except placing messages into folder $folder_action = $message_removed = false; foreach ($msg_ary as $pos => $rule_ary) { if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER) { continue; } switch ($rule_ary['action']) { case ACTION_PLACE_INTO_FOLDER: // Folder actions have precedence, so we will remove any other ones $folder_action = true; $move_into_folder[(int) $rule_ary['folder_id']][] = $msg_id; break; case ACTION_MARK_AS_READ: if ($rule_ary['pm_unread']) { $unread_ids[] = $msg_id; } break; case ACTION_DELETE_MESSAGE: $delete_ids[] = $msg_id; $message_removed = true; break; case ACTION_MARK_AS_IMPORTANT: if (!$rule_ary['pm_marked']) { $important_ids[] = $msg_id; } break; } } // We place this here because it could happen that the messages are doubled if a rule marks a message and then moves it into a specific // folder. Here we simply move the message into the INBOX if it gets not removed and also not put into a custom folder. if (!$folder_action && !$message_removed) { $move_into_folder[PRIVMSGS_INBOX][] = $msg_id; } } // Do not change the order of processing // The number of queries needed to be executed here highly depends on the defined rules and are // only gone through if new messages arrive. // Delete messages if (sizeof($delete_ids)) { $num_removed += sizeof($delete_ids); delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX); } // Set messages to Unread if (sizeof($unread_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET pm_unread = 0 WHERE ' . $db->sql_in_set('msg_id', $unread_ids) . "\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND folder_id = " . PRIVMSGS_NO_BOX; $db->sql_query($sql); } // mark messages as important if (sizeof($important_ids)) { $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET pm_marked = 1 - pm_marked WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND " . $db->sql_in_set('msg_id', $important_ids); $db->sql_query($sql); } // Move into folder $folder = array(); if (sizeof($move_into_folder)) { // Determine Full Folder Action - we need the move to folder id later eventually $full_folder_action = $user->data['user_full_folder'] == FULL_FOLDER_NONE ? $config['full_folder_action'] - FULL_FOLDER_NONE * -1 : $user->data['user_full_folder']; $sql_folder = array_keys($move_into_folder); if ($full_folder_action >= 0) { $sql_folder[] = $full_folder_action; } $sql = 'SELECT folder_id, pm_count FROM ' . PRIVMSGS_FOLDER_TABLE . ' WHERE ' . $db->sql_in_set('folder_id', $sql_folder) . "\n\t\t\t\tAND user_id = {$user_id}"; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { $folder[(int) $row['folder_id']] = (int) $row['pm_count']; } $db->sql_freeresult($result); unset($sql_folder); if (isset($move_into_folder[PRIVMSGS_INBOX])) { $sql = 'SELECT COUNT(msg_id) as num_messages FROM ' . PRIVMSGS_TO_TABLE . "\n\t\t\t\tWHERE user_id = {$user_id}\n\t\t\t\t\tAND folder_id = " . PRIVMSGS_INBOX; $result = $db->sql_query($sql); $folder[PRIVMSGS_INBOX] = (int) $db->sql_fetchfield('num_messages'); $db->sql_freeresult($result); } } // Here we have ideally only one folder to move into foreach ($move_into_folder as $folder_id => $msg_ary) { $dest_folder = $folder_id; $full_folder_action = FULL_FOLDER_NONE; // Check Message Limit - we calculate with the complete array, most of the time it is one message // But we are making sure that the other way around works too (more messages in queue than allowed to be stored) if ($user->data['message_limit'] && $folder[$folder_id] && $folder[$folder_id] + sizeof($msg_ary) > $user->data['message_limit']) { $full_folder_action = $user->data['user_full_folder'] == FULL_FOLDER_NONE ? $config['full_folder_action'] - FULL_FOLDER_NONE * -1 : $user->data['user_full_folder']; // If destination folder itself is full... if ($full_folder_action >= 0 && $folder[$full_folder_action] + sizeof($msg_ary) > $user->data['message_limit']) { $full_folder_action = $config['full_folder_action'] - FULL_FOLDER_NONE * -1; } // If Full Folder Action is to move to another folder, we simply adjust the destination folder if ($full_folder_action >= 0) { $dest_folder = $full_folder_action; } else { if ($full_folder_action == FULL_FOLDER_DELETE) { // Delete some messages. NOTE: Ordered by msg_id here instead of message_time! $sql = 'SELECT msg_id FROM ' . PRIVMSGS_TO_TABLE . "\n\t\t\t\t\tWHERE user_id = {$user_id}\n\t\t\t\t\t\tAND folder_id = {$dest_folder}\n\t\t\t\t\tORDER BY msg_id ASC"; $result = $db->sql_query_limit($sql, $folder[$dest_folder] + sizeof($msg_ary) - $user->data['message_limit']); $delete_ids = array(); while ($row = $db->sql_fetchrow($result)) { $delete_ids[] = $row['msg_id']; } $db->sql_freeresult($result); $num_removed += sizeof($delete_ids); delete_pm($user_id, $delete_ids, $dest_folder); } } } // if ($full_folder_action == FULL_FOLDER_HOLD) { $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_HOLD_BOX . ' WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\n\t\t\t\t\tAND user_id = {$user_id}\n\t\t\t\t\tAND " . $db->sql_in_set('msg_id', $msg_ary); $db->sql_query($sql); } else { $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . "\n\t\t\t\tSET folder_id = {$dest_folder}, pm_new = 0\n\t\t\t\tWHERE folder_id = " . PRIVMSGS_NO_BOX . "\n\t\t\t\t\tAND user_id = {$user_id}\n\t\t\t\t\tAND pm_new = 1\n\t\t\t\t\tAND " . $db->sql_in_set('msg_id', $msg_ary); $db->sql_query($sql); if ($dest_folder != PRIVMSGS_INBOX) { $sql = 'UPDATE ' . PRIVMSGS_FOLDER_TABLE . ' SET pm_count = pm_count + ' . (int) $db->sql_affectedrows() . "\n\t\t\t\t\tWHERE folder_id = {$dest_folder}\n\t\t\t\t\t\tAND user_id = {$user_id}"; $db->sql_query($sql); } } } if (sizeof($action_ary)) { // Move from OUTBOX to SENTBOX // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted) $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_SENTBOX . ' WHERE folder_id = ' . PRIVMSGS_OUTBOX . ' AND ' . $db->sql_in_set('msg_id', array_keys($action_ary)); $db->sql_query($sql); } // Update new/unread count update_pm_counts(); // Now check how many messages got not moved... $sql = 'SELECT COUNT(msg_id) as num_messages FROM ' . PRIVMSGS_TO_TABLE . "\n\t\tWHERE user_id = {$user_id}\n\t\t\tAND folder_id = " . PRIVMSGS_HOLD_BOX; $result = $db->sql_query($sql); $num_not_moved = (int) $db->sql_fetchfield('num_messages'); $db->sql_freeresult($result); return array('not_moved' => $num_not_moved, 'removed' => $num_removed); }
function place_pm_into_folder(&$global_privmsgs_rules, $release = false) { global $_CLASS, $config; if (!$_CLASS['core_user']->data['user_new_privmsg']) { return; } $_CLASS['core_user']->data['user_message_rules'] = 0; $_CLASS['core_user']->data['user_full_folder'] = FULL_FOLDER_NONE; $user_new_privmsg = (int) $_CLASS['core_user']->data['user_new_privmsg']; $user_message_rules = (int) $_CLASS['core_user']->data['user_message_rules']; $user_id = (int) $_CLASS['core_user']->data['user_id']; $user_rules = $zebra = array(); if ($user_message_rules) { $sql = 'SELECT * FROM ' . FORUMS_PRIVMSGS_RULES_TABLE . "\n\t\t\tWHERE user_id = {$user_id}"; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $user_rules[] = $row; } $_CLASS['core_db']->free_result($result); if (!empty($user_rules)) { $sql = 'SELECT zebra_id, friend, foe FROM ' . ZEBRA_TABLE . "\n\t\t\t\tWHERE user_id = {$user_id}"; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $zebra[$row['zebra_id']] = $row; } $_CLASS['core_db']->free_result($result); } } // I don't like no box /* if ($release) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_NO_BOX . ' WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . " AND user_id = $user_id"; $_CLASS['core_db']->query($sql); } */ // Get those messages not yet placed into any box // NOTE: Expand Group Information to all groups the user/author is in? $sql = 'SELECT t.*, p.*, u.username, u.user_group as author_in_group FROM ' . FORUMS_PRIVMSGS_TO_TABLE . ' t, ' . FORUMS_PRIVMSGS_TABLE . ' p, ' . USERS_TABLE . " u\n\t\tWHERE t.user_id = {$user_id}\n\t\t\tAND p.author_id = u.user_id\n\t\t\tAND t.folder_id = " . PRIVMSGS_NO_BOX . ' AND t.msg_id = p.msg_id'; $result = $_CLASS['core_db']->query($sql); $action_ary = $move_into_folder = array(); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $row['to'] = explode(':', $row['to_address']); $row['bcc'] = explode(':', $row['bcc_address']); $row['friend'] = isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['friend'] : 0; $row['foe'] = isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['foe'] : 0; $row['user_in_group'] = $_CLASS['core_user']->data['user_group']; // Check Rule - this should be very quick since we have all informations we need $is_match = false; foreach ($user_rules as $rule_row) { if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false) { $is_match = true; $action_ary[$row['msg_id']][] = $action; } } if (!$is_match) { $action_ary[$row['msg_id']][] = array('action' => false); $move_into_folder[PRIVMSGS_INBOX][] = $row['msg_id']; } } $_CLASS['core_db']->free_result($result); // We place actions into arrays, to save queries. $num_new = $num_unread = 0; $sql = $unread_ids = $delete_ids = $important_ids = array(); foreach ($action_ary as $msg_id => $msg_ary) { // It is allowed to execute actions more than once, except placing messages into folder $folder_action = false; foreach ($msg_ary as $pos => $rule_ary) { if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER) { continue; } switch ($rule_ary['action']) { case ACTION_PLACE_INTO_FOLDER: $folder_action = true; $_folder_id = (int) $rule_ary['folder_id']; $move_into_folder[$_folder_id][] = $msg_id; $num_new++; break; case ACTION_MARK_AS_READ: if ($rule_ary['unread']) { $unread_ids[] = $msg_id; } $move_into_folder[PRIVMSGS_INBOX][] = $msg_id; break; case ACTION_DELETE_MESSAGE: $delete_ids[] = $msg_id; break; case ACTION_MARK_AS_IMPORTANT: if (!$rule_ary['important']) { $important_ids[] = $msg_id; } $move_into_folder[PRIVMSGS_INBOX][] = $msg_id; break; } } } $num_new += count(array_unique($delete_ids)); $num_unread += count(array_unique($delete_ids)); $num_unread += count(array_unique($unread_ids)); // Do not change the order of processing // The number of queries needed to be executed here highly depends on the defined rules and are // only gone through if new messages arrive. $num_not_moved = 0; $_CLASS['core_db']->transaction(); // Delete messages if (!empty($delete_ids)) { delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX); } // Set messages to Unread if (!empty($unread_ids)) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET unread = 0 WHERE msg_id IN (' . implode(', ', $unread_ids) . ")\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND folder_id = " . PRIVMSGS_NO_BOX; $_CLASS['core_db']->query($sql); } // mark messages as important if (!empty($important_ids)) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET marked = 1 WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND msg_id IN (" . implode(', ', $important_ids) . ')'; $_CLASS['core_db']->query($sql); } // Move into folder $folder = array(); if (!empty($move_into_folder)) { // Determine Full Folder Action - we need the move to folder id later eventually $full_folder_action = $_CLASS['core_user']->data['user_full_folder'] == FULL_FOLDER_NONE ? $config['full_folder_action'] - FULL_FOLDER_NONE * -1 : $_CLASS['core_user']->data['user_full_folder']; $sql = 'SELECT folder_id, pm_count FROM ' . FORUMS_PRIVMSGS_FOLDER_TABLE . ' WHERE folder_id IN (' . implode(', ', array_keys($move_into_folder)) . ($full_folder_action >= 0 ? ', ' . $full_folder_action : '') . ")\n\t\t\t\tAND user_id = {$user_id}"; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $folder[(int) $row['folder_id']] = (int) $row['pm_count']; } $_CLASS['core_db']->free_result($result); if (in_array(PRIVMSGS_INBOX, array_keys($move_into_folder))) { $sql = 'SELECT COUNT(*) as num_messages FROM ' . FORUMS_PRIVMSGS_TO_TABLE . "\n\t\t\t\tWHERE user_id = {$user_id}\n\t\t\t\t\tAND folder_id = " . PRIVMSGS_INBOX; $result = $_CLASS['core_db']->query_limit($sql); list($count) = $_CLASS['core_db']->fetch_row_num($result); $_CLASS['core_db']->free_result($result); $folder[PRIVMSGS_INBOX] = (int) $count; } } // Here we have ideally only one folder to move into $message_limit = $_CLASS['core_user']->data['user_message_limit'] ? $_CLASS['core_user']->data['user_message_limit'] : $config['pm_max_msgs']; foreach ($move_into_folder as $folder_id => $msg_ary) { $dest_folder = $folder_id; $full_folder_action = FULL_FOLDER_NONE; // Check Message Limit - we calculate with the complete array, most of the time it is one message // But we are making sure that the other way around works too (more messages in queue than allowed to be stored) if ($message_limit && $folder[$folder_id] && $folder[$folder_id] + count($msg_ary) > $message_limit) { $full_folder_action = $_CLASS['core_user']->data['user_full_folder'] == FULL_FOLDER_NONE ? $config['full_folder_action'] - FULL_FOLDER_NONE * -1 : $_CLASS['core_user']->data['user_full_folder']; // If destination folder itself is full... if ($full_folder_action >= 0 && $folder[$full_folder_action] + count($msg_ary) > $message_limit) { $full_folder_action = $config['full_folder_action'] - FULL_FOLDER_NONE * -1; } // If Full Folder Action is to move to another folder, we simply adjust the destination folder if ($full_folder_action >= 0) { $dest_folder = $full_folder_action; } elseif ($full_folder_action == FULL_FOLDER_DELETE) { // Delete some messages ;) $sql = 'SELECT t.msg_id FROM ' . FORUMS_PRIVMSGS_TO_TABLE . ' t, ' . FORUMS_PRIVMSGS_TABLE . " p\n\t\t\t\t\tWHERE t.msg_id = p.msg_id\n\t\t\t\t\t\tAND t.user_id = {$user_id}\n\t\t\t\t\t\tAND t.folder_id = {$dest_folder}\n\t\t\t\t\tORDER BY p.message_time ASC"; $result = $_CLASS['core_db']->query_limit($sql, $folder[$dest_folder] + count($msg_ary) - $message_limit); $delete_ids = array(); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $delete_ids[] = $row['msg_id']; } $_CLASS['core_db']->free_result($result); delete_pm($user_id, $delete_ids, $dest_folder); } } if ($full_folder_action == FULL_FOLDER_HOLD) { $num_not_moved += count($msg_ary); $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_HOLD_BOX . ' WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\n\t\t\t\t\tAND user_id = {$user_id}\n\t\t\t\t\tAND msg_id IN (" . implode(', ', $msg_ary) . ')'; $_CLASS['core_db']->query($sql); } else { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . " \n\t\t\t\tSET folder_id = {$dest_folder}, msg_new = 0\n\t\t\t\tWHERE folder_id = " . PRIVMSGS_NO_BOX . "\n\t\t\t\t\tAND user_id = {$user_id}\n\t\t\t\t\tAND msg_new = 1\n\t\t\t\t\tAND msg_id IN (" . implode(', ', $msg_ary) . ')'; $_CLASS['core_db']->query($sql); if ($dest_folder != PRIVMSGS_INBOX) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_FOLDER_TABLE . ' SET pm_count = pm_count + ' . (int) $_CLASS['core_db']->affected_rows() . "\n\t\t\t\t\tWHERE folder_id = {$dest_folder}\n\t\t\t\t\t\tAND user_id = {$user_id}"; $_CLASS['core_db']->query($sql); } else { $num_new += $_CLASS['core_db']->affected_rows(); } } } if (!empty($action_ary)) { // Move from OUTBOX to SENTBOX // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted) $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_SENTBOX . ' WHERE folder_id = ' . PRIVMSGS_OUTBOX . ' AND msg_id IN (' . implode(', ', array_keys($action_ary)) . ')'; $_CLASS['core_db']->query($sql); } // Update unread and new status field if ($num_unread || $num_new) { $set_sql = $num_unread ? 'user_unread_privmsg = user_unread_privmsg - ' . $num_unread : ''; if ($num_new) { $set_sql .= $set_sql ? ', ' : ''; $set_sql .= 'user_new_privmsg = user_new_privmsg - ' . $num_new; } $_CLASS['core_db']->query('UPDATE ' . USERS_TABLE . " SET {$set_sql} WHERE user_id = {$user_id}"); $_CLASS['core_user']->data['user_new_privmsg'] -= $num_new; $_CLASS['core_user']->data['user_unread_privmsg'] -= $num_unread; } $_CLASS['core_db']->transaction('commit'); return $num_not_moved; }
function action_update_note($par = null) { if (is_ajax() || isset($_POST['note'])) { $note = isset($par['note']) ? $par['note'] : (isset($_POST['note']) ? $_POST['note'] : ''); $note = secure_text($note); if ((isset($par['note']) || isset($_POST['note'])) && check_rule('admin_settings') && update_option('admin_notes', $note)) { if (!is_ajax()) { push_output_message(array('title' => 'Обновлено!', 'text' => 'Заметка успешно обновлена', 'class' => 'alert alert-success')); } return true; } else { if (!is_ajax()) { push_output_message(array('title' => 'Ошибка!', 'text' => 'У вас недостаточно прав для правки публичной заметки', 'class' => 'alert alert-danger')); } return false; } } return false; }
<html> <head> <title><?php page_title('Админ-панель'); ?> </title> <?php page_header(); ?> </head> <body> <header id="main-header" class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div id="login-panel" class="pull-right detwork-control"><ul class="nav navbar-nav navbar-right nav-bootstrap"> <?php $my_url = check_rule('admin_users') ? get_page_link('user_info') . '&user_id=' . current_user('ID') : '#'; ?> <li id="login-panel" class="item-settings dropdown"> <a href="<?php echo $my_url; ?> " class="dropdown-toggle" data-toggle="dropdown"><?php echo current_user('display_name'); ?> </a> <div class="subnav dropdown-menu"><form method="POST"> <?php if ($my_url != '#') { ?> <div class="user-settings btn-group input-group btn-group-justified"> <a href="<?php
/** * Place new messages into appropiate folder */ function place_pm_into_folder(&$global_privmsgs_rules, $release = false) { global $_CLASS, $config; if (!$_CLASS['core_user']->data['user_new_privmsg']) { return 0; } $_CLASS['core_user']->data['user_message_rules'] = 0; $_CLASS['core_user']->data['user_full_folder'] = FULL_FOLDER_NONE; $user_new_privmsg = (int) $_CLASS['core_user']->data['user_new_privmsg']; $user_message_rules = (int) $_CLASS['core_user']->data['user_message_rules']; $user_id = (int) $_CLASS['core_user']->data['user_id']; $action_ary = $move_into_folder = array(); if ($release) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_NO_BOX . ' WHERE folder_id = ' . PRIVMSGS_HOLD_BOX . "\r\n\t\t\t\tAND user_id = {$user_id}"; $_CLASS['core_db']->query($sql); } // Get those messages not yet placed into any box $retrieve_sql = 'SELECT t.*, p.*, u.username, u.user_id, u.user_group as group_id FROM ' . FORUMS_PRIVMSGS_TO_TABLE . ' t, ' . FORUMS_PRIVMSGS_TABLE . ' p, ' . CORE_USERS_TABLE . " u\r\n\t\tWHERE t.user_id = {$user_id}\r\n\t\t\tAND p.author_id = u.user_id\r\n\t\t\tAND t.folder_id = " . PRIVMSGS_NO_BOX . ' AND t.msg_id = p.msg_id'; if ($user_message_rules) { $result = $_CLASS['core_db']->query($retrieve_sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $action_ary[$row['msg_id']][] = array('action' => false); $move_into_folder[PRIVMSGS_INBOX][] = $row['msg_id']; } $_CLASS['core_db']->free_result($result); } else { $user_rules = $zebra = $check_rows = array(); $user_ids = $memberships = array(); // First of all, grab all rules and retrieve friends/foes $sql = 'SELECT * FROM ' . FORUMS_PRIVMSGS_RULES_TABLE . "\r\n\t\t\tWHERE user_id = {$user_id}"; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $user_rules[] = $row; } $_CLASS['core_db']->free_result($result); if (sizeof($user_rules)) { $sql = 'SELECT zebra_id, friend, foe FROM ' . ZEBRA_TABLE . "\r\n\t\t\t\tWHERE user_id = {$user_id}"; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $zebra[$row['zebra_id']] = $row; } $_CLASS['core_db']->free_result($result); } // Now build a bare-bone check_row array $result = $_CLASS['core_db']->query($retrieve_sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $check_rows[] = array_merge($row, array('to' => explode(':', $row['to_address']), 'bcc' => explode(':', $row['bcc_address']), 'friend' => isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['friend'] : 0, 'foe' => isset($zebra[$row['author_id']]) ? $zebra[$row['author_id']]['foe'] : 0, 'user_in_group' => array($_CLASS['core_user']->data['user_group']), 'author_in_group' => array())); $user_ids[] = $row['user_id']; } $_CLASS['core_db']->free_result($result); // Retrieve user memberships if (sizeof($user_ids)) { $sql = 'SELECT * FROM ' . CORE_GROUPS_MEMBERS_TABLE . ' WHERE user_id IN (' . implode(', ', $user_ids) . ') AND member_status = ' . STATUS_ACTIVE; $result = $_CLASS['core_db']->query($sql); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $memberships[$row['user_id']][] = $row['group_id']; } $_CLASS['core_db']->free_result($result); } // Now place into the appropiate folder foreach ($check_rows as $row) { // Add membership if set if (isset($memberships[$row['author_id']])) { $row['author_in_group'] = $memberships[$row['user_id']]; } // Check Rule - this should be very quick since we have all informations we need $is_match = false; foreach ($user_rules as $rule_row) { if (($action = check_rule($global_privmsgs_rules, $rule_row, $row, $user_id)) !== false) { $is_match = true; $action_ary[$row['msg_id']][] = $action; } } if (!$is_match) { $action_ary[$row['msg_id']][] = array('action' => false); $move_into_folder[PRIVMSGS_INBOX][] = $row['msg_id']; } } unset($user_rules, $zebra, $check_rows, $user_ids, $memberships); } // We place actions into arrays, to save queries. $num_new = $num_unread = 0; $sql = $unread_ids = $delete_ids = $important_ids = array(); foreach ($action_ary as $msg_id => $msg_ary) { // It is allowed to execute actions more than once, except placing messages into folder $folder_action = false; foreach ($msg_ary as $pos => $rule_ary) { if ($folder_action && $rule_ary['action'] == ACTION_PLACE_INTO_FOLDER) { continue; } switch ($rule_ary['action']) { case ACTION_PLACE_INTO_FOLDER: // Folder actions have precedence, so we will remove any other ones $folder_action = true; $_folder_id = (int) $rule_ary['folder_id']; $move_into_folder = array(); $move_into_folder[$_folder_id][] = $msg_id; $num_new++; break; case ACTION_MARK_AS_READ: if ($rule_ary['pm_unread']) { $unread_ids[] = $msg_id; } if (!$folder_action) { $move_into_folder[PRIVMSGS_INBOX][] = $msg_id; } break; case ACTION_DELETE_MESSAGE: $delete_ids[] = $msg_id; break; case ACTION_MARK_AS_IMPORTANT: if (!$rule_ary['pm_marked']) { $important_ids[] = $msg_id; } if (!$folder_action) { $move_into_folder[PRIVMSGS_INBOX][] = $msg_id; } break; } } } // $num_new += count(array_unique($delete_ids)); // $num_unread += count(array_unique($delete_ids)); $num_unread += count(array_unique($unread_ids)); // Do not change the order of processing // The number of queries needed to be executed here highly depends on the defined rules and are // only gone through if new messages arrive. $num_not_moved = 0; $_CLASS['core_db']->transaction(); // Delete messages if (!empty($delete_ids)) { delete_pm($user_id, $delete_ids, PRIVMSGS_NO_BOX); } // Set messages to Unread if (!empty($unread_ids)) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET pm_unread = 0 WHERE msg_id IN (' . implode(', ', $unread_ids) . ")\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND folder_id = " . PRIVMSGS_NO_BOX; $_CLASS['core_db']->query($sql); } // mark messages as important if (!empty($important_ids)) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET pm_marked = !pm_marked WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\n\t\t\t\tAND user_id = {$user_id}\n\t\t\t\tAND msg_id IN (" . implode(', ', $important_ids) . ')'; $_CLASS['core_db']->query($sql); } // Move into folder $folder = array(); // Here we have ideally only one folder to move into foreach ($move_into_folder as $folder_id => $msg_ary) { $dest_folder = $folder_id; $full_folder_action = FULL_FOLDER_NONE; ///// KILLL $_CLASS['core_user']->data['message_limit'] = 0; // Check Message Limit - we calculate with the complete array, most of the time it is one message // But we are making sure that the other way around works too (more messages in queue than allowed to be stored) if ($_CLASS['core_user']->data['message_limit'] && $folder[$folder_id] && $folder[$folder_id] + sizeof($msg_ary) > $_CLASS['core_user']->data['message_limit']) { // Determine Full Folder Action - we need the move to folder id later eventually $full_folder_action = $_CLASS['core_user']->data['user_full_folder'] == FULL_FOLDER_NONE ? $config['full_folder_action'] - FULL_FOLDER_NONE * -1 : $_CLASS['core_user']->data['user_full_folder']; if ($full_folder_action >= 0 && $folder[$full_folder_action] + sizeof($msg_ary) > $_CLASS['core_user']->data['message_limit']) { $full_folder_action = $config['full_folder_action'] - FULL_FOLDER_NONE * -1; } // If Full Folder Action is to move to another folder, we simply adjust the destination folder if ($full_folder_action >= 0) { $dest_folder = $full_folder_action; } else { if ($full_folder_action == FULL_FOLDER_DELETE) { // Delete some messages ;) $sql = 'SELECT t.msg_id FROM ' . FORUMS_PRIVMSGS_TO_TABLE . ' t, ' . FORUMS_PRIVMSGS_TABLE . " p\r\n\t\t\t\t\tWHERE t.msg_id = p.msg_id\r\n\t\t\t\t\t\tAND t.user_id = {$user_id}\r\n\t\t\t\t\t\tAND t.folder_id = {$dest_folder}\r\n\t\t\t\t\tORDER BY p.message_time ASC"; $result = $_CLASS['core_db']->query_limit($sql, $folder[$dest_folder] + sizeof($msg_ary) - $_CLASS['core_user']->data['message_limit']); $delete_ids = array(); while ($row = $_CLASS['core_db']->fetch_row_assoc($result)) { $delete_ids[] = $row['msg_id']; } $_CLASS['core_db']->free_result($result); delete_pm($user_id, $delete_ids, $dest_folder); } } } // if ($full_folder_action == FULL_FOLDER_HOLD) { $num_not_moved += sizeof($msg_ary); $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_HOLD_BOX . ' WHERE folder_id = ' . PRIVMSGS_NO_BOX . "\r\n\t\t\t\t\tAND user_id = {$user_id}\r\n\t\t\t\t\tAND msg_id IN (" . implode(', ', $msg_ary) . ')'; $_CLASS['core_db']->query($sql); } else { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . " \r\n\t\t\t\tSET folder_id = {$dest_folder}, pm_new = 0\r\n\t\t\t\tWHERE folder_id = " . PRIVMSGS_NO_BOX . "\r\n\t\t\t\t\tAND user_id = {$user_id}\r\n\t\t\t\t\tAND pm_new = 1\r\n\t\t\t\t\tAND msg_id IN (" . implode(', ', $msg_ary) . ')'; $_CLASS['core_db']->query($sql); if ($dest_folder != PRIVMSGS_INBOX) { $sql = 'UPDATE ' . FORUMS_PRIVMSGS_FOLDER_TABLE . ' SET pm_count = pm_count + ' . (int) $_CLASS['core_db']->affected_rows() . "\r\n\t\t\t\t\tWHERE folder_id = {$dest_folder}\r\n\t\t\t\t\t\tAND user_id = {$user_id}"; $_CLASS['core_db']->query($sql); } else { $num_new += (int) $_CLASS['core_db']->affected_rows(); } } } if (sizeof($action_ary)) { // Move from OUTBOX to SENTBOX // We are not checking any full folder status here... SENTBOX is a special treatment (old messages get deleted) $sql = 'UPDATE ' . FORUMS_PRIVMSGS_TO_TABLE . ' SET folder_id = ' . PRIVMSGS_SENTBOX . ' WHERE folder_id = ' . PRIVMSGS_OUTBOX . ' AND msg_id IN (' . implode(', ', array_keys($action_ary)) . ')'; $_CLASS['core_db']->query($sql); } // Update unread and new status field if ($num_unread || $num_new) { $set_sql = $num_unread ? 'user_unread_privmsg = user_unread_privmsg - ' . $num_unread : ''; if ($num_new) { $set_sql .= $set_sql != '' ? ', ' : ''; $set_sql .= 'user_new_privmsg = user_new_privmsg - ' . $num_new; } $_CLASS['core_db']->query('UPDATE ' . CORE_USERS_TABLE . " SET {$set_sql} WHERE user_id = {$user_id}"); $_CLASS['core_user']->data['user_new_privmsg'] -= $num_new; $_CLASS['core_user']->data['user_unread_privmsg'] -= $num_unread; } $_CLASS['core_db']->transaction('commit'); return $num_not_moved; }
<div class="content-tags"> <div class="note"> <h3>Общие заметки</h3> <form method="POST" class="detwork-control"> <textarea name="note" class="editor form-control data-control" rows="10"><?php echo get_option('admin_notes'); ?> </textarea> <?php if (check_rule('admin_settings')) { ?> <hr /> <button class="btn btn-primary input-control button-control" data-action="update_note"><span class="glyphicon glyphicon-ok"></span> Сохранить</button> <?php } ?> </form> </div> </div>