/** * This will apply rules to all unread messages. If all_messages is set will, clearly, do it to all! * * @param bool $all_messages = false */ function ApplyRules($all_messages = false) { global $user_info, $smcFunc, $context, $options; // Want this - duh! loadRules(); // No rules? if (empty($context['rules'])) { return; } // Just unread ones? $ruleQuery = $all_messages ? '' : ' AND pmr.is_new = 1'; // @todo Apply all should have timeout protection! // Get all the messages that match this. $request = $smcFunc['db_query']('', ' SELECT pmr.id_pm, pm.id_member_from, pm.subject, pm.body, mem.id_group, pmr.labels FROM {db_prefix}pm_recipients AS pmr INNER JOIN {db_prefix}personal_messages AS pm ON (pm.id_pm = pmr.id_pm) LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = pm.id_member_from) WHERE pmr.id_member = {int:current_member} AND pmr.deleted = {int:not_deleted} ' . $ruleQuery, array('current_member' => $user_info['id'], 'not_deleted' => 0)); $actions = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { foreach ($context['rules'] as $rule) { $match = false; // Loop through all the criteria hoping to make a match. foreach ($rule['criteria'] as $criterium) { if ($criterium['t'] == 'mid' && $criterium['v'] == $row['id_member_from'] || $criterium['t'] == 'gid' && $criterium['v'] == $row['id_group'] || $criterium['t'] == 'sub' && strpos($row['subject'], $criterium['v']) !== false || $criterium['t'] == 'msg' && strpos($row['body'], $criterium['v']) !== false) { $match = true; } elseif ($rule['logic'] == 'and') { $match = false; break; } } // If we have a match the rule must be true - act! if ($match) { if ($rule['delete']) { $actions['deletes'][] = $row['id_pm']; } else { foreach ($rule['actions'] as $ruleAction) { if ($ruleAction['t'] == 'lab') { // Get a basic pot started! if (!isset($actions['labels'][$row['id_pm']])) { $actions['labels'][$row['id_pm']] = empty($row['labels']) ? array() : explode(',', $row['labels']); } $actions['labels'][$row['id_pm']][] = $ruleAction['v']; } } } } } } $smcFunc['db_free_result']($request); // Deletes are easy! if (!empty($actions['deletes'])) { deleteMessages($actions['deletes']); } // Relabel? if (!empty($actions['labels'])) { foreach ($actions['labels'] as $pm => $labels) { // Quickly check each label is valid! $realLabels = array(); foreach ($context['labels'] as $label) { if (in_array($label['id'], $labels) && ($label['id'] != -1 || empty($options['pm_remove_inbox_label']))) { $realLabels[] = $label['id']; } } $smcFunc['db_query']('', ' UPDATE {db_prefix}pm_recipients SET labels = {string:new_labels} WHERE id_pm = {int:id_pm} AND id_member = {int:current_member}', array('current_member' => $user_info['id'], 'id_pm' => $pm, 'new_labels' => empty($realLabels) ? '' : implode(',', $realLabels))); } } }
/** * List and allow adding/entering all man rules, such as * * What it does: * - If it itches, it will be scratched. * - Yes or No are perfectly acceptable answers to almost every question. * - Men see in only 16 colors, Peach, for example, is a fruit, not a color. * * @uses sub template rules */ public function action_manrules() { global $txt, $context, $user_info, $scripturl; require_once SUBSDIR . '/PersonalMessage.subs.php'; // The link tree - gotta have this :o $context['linktree'][] = array('url' => $scripturl . '?action=pm;sa=manrules', 'name' => $txt['pm_manage_rules']); $context['page_title'] = $txt['pm_manage_rules']; $context['sub_template'] = 'rules'; // Load them... load them!! loadRules(); // Likely to need all the groups! require_once SUBSDIR . '/Membergroups.subs.php'; $context['groups'] = accessibleGroups(); // Applying all rules? if (isset($_GET['apply'])) { checkSession('get'); applyRules(true); redirectexit('action=pm;sa=manrules'); } // Editing a specific rule? if (isset($_GET['add'])) { $context['rid'] = isset($_GET['rid']) && isset($context['rules'][$_GET['rid']]) ? (int) $_GET['rid'] : 0; $context['sub_template'] = 'add_rule'; // Any known rule $js_rules = ''; foreach ($context['known_rules'] as $rule) { $js_rules .= JavaScriptEscape($rule) . ': ' . JavaScriptEscape($txt['pm_rule_' . $rule]) . ','; } $js_rules = '{' . substr($js_rules, 0, -1) . '}'; // Any known label $js_labels = ''; foreach ($context['labels'] as $label) { if ($label['id'] != -1) { $js_labels .= JavaScriptEscape($label['id'] + 1) . ': ' . JavaScriptEscape($label['name']) . ','; } } $js_labels = '{' . substr($js_labels, 0, -1) . '}'; // And all of the groups as well $js_groups = ''; foreach ($context['groups'] as $id => $title) { $js_groups .= JavaScriptEscape($id) . ': ' . JavaScriptEscape($title) . ','; } $js_groups = '{' . substr($js_groups, 0, -1) . '}'; // Oh my, we have a lot of text strings for this addJavascriptVar(array('criteriaNum' => 0, 'actionNum' => 0, 'groups' => $js_groups, 'labels' => $js_labels, 'rules' => $js_rules, 'txt_pm_readable_and' => $txt['pm_readable_and'], 'txt_pm_readable_or' => $txt['pm_readable_or'], 'txt_pm_readable_member' => $txt['pm_readable_member'], 'txt_pm_readable_group' => $txt['pm_readable_group'], 'txt_pm_readable_subject ' => $txt['pm_readable_subject'], 'txt_pm_readable_body' => $txt['pm_readable_body'], 'txt_pm_readable_buddy' => $txt['pm_readable_buddy'], 'txt_pm_readable_label' => $txt['pm_readable_label'], 'txt_pm_readable_delete' => $txt['pm_readable_delete'], 'txt_pm_readable_start' => $txt['pm_readable_start'], 'txt_pm_readable_end' => $txt['pm_readable_end'], 'txt_pm_readable_then' => $txt['pm_readable_then'], 'txt_pm_rule_not_defined' => $txt['pm_rule_not_defined'], 'txt_pm_rule_criteria_pick' => $txt['pm_rule_criteria_pick'], 'txt_pm_rule_sel_group' => $txt['pm_rule_sel_group'], 'txt_pm_rule_sel_action' => $txt['pm_rule_sel_action'], 'txt_pm_rule_label' => $txt['pm_rule_label'], 'txt_pm_rule_delete' => $txt['pm_rule_delete'], 'txt_pm_rule_sel_label' => $txt['pm_rule_sel_label']), true); // Current rule information... if ($context['rid']) { $context['rule'] = $context['rules'][$context['rid']]; $members = array(); // Need to get member names! foreach ($context['rule']['criteria'] as $k => $criteria) { if ($criteria['t'] == 'mid' && !empty($criteria['v'])) { $members[(int) $criteria['v']] = $k; } } if (!empty($members)) { require_once SUBSDIR . '/Members.subs.php'; $result = getBasicMemberData(array_keys($members)); foreach ($result as $row) { $context['rule']['criteria'][$members[$row['id_member']]]['v'] = $row['member_name']; } } } else { $context['rule'] = array('id' => '', 'name' => '', 'criteria' => array(), 'actions' => array(), 'logic' => 'and'); } // Add a dummy criteria to allow expansion for none js users. $context['rule']['criteria'][] = array('t' => '', 'v' => ''); } elseif (isset($_GET['save'])) { checkSession('post'); $context['rid'] = isset($_GET['rid']) && isset($context['rules'][$_GET['rid']]) ? (int) $_GET['rid'] : 0; // Name is easy! $ruleName = Util::htmlspecialchars(trim($_POST['rule_name'])); if (empty($ruleName)) { fatal_lang_error('pm_rule_no_name', false); } // Sanity check... if (empty($_POST['ruletype']) || empty($_POST['acttype'])) { fatal_lang_error('pm_rule_no_criteria', false); } // Let's do the criteria first - it's also hardest! $criteria = array(); foreach ($_POST['ruletype'] as $ind => $type) { // Check everything is here... if ($type == 'gid' && (!isset($_POST['ruledefgroup'][$ind]) || !isset($context['groups'][$_POST['ruledefgroup'][$ind]]))) { continue; } elseif ($type != 'bud' && !isset($_POST['ruledef'][$ind])) { continue; } // Members need to be found. if ($type == 'mid') { require_once SUBSDIR . '/Members.subs.php'; $name = trim($_POST['ruledef'][$ind]); $member = getMemberByName($name, true); if (empty($member)) { continue; } $criteria[] = array('t' => 'mid', 'v' => $member['id_member']); } elseif ($type == 'bud') { $criteria[] = array('t' => 'bud', 'v' => 1); } elseif ($type == 'gid') { $criteria[] = array('t' => 'gid', 'v' => (int) $_POST['ruledefgroup'][$ind]); } elseif (in_array($type, array('sub', 'msg')) && trim($_POST['ruledef'][$ind]) != '') { $criteria[] = array('t' => $type, 'v' => Util::htmlspecialchars(trim($_POST['ruledef'][$ind]))); } } // Also do the actions! $actions = array(); $doDelete = 0; $isOr = $_POST['rule_logic'] == 'or' ? 1 : 0; foreach ($_POST['acttype'] as $ind => $type) { // Picking a valid label? if ($type == 'lab' && (!isset($_POST['labdef'][$ind]) || !isset($context['labels'][$_POST['labdef'][$ind] - 1]))) { continue; } // Record what we're doing. if ($type == 'del') { $doDelete = 1; } elseif ($type == 'lab') { $actions[] = array('t' => 'lab', 'v' => (int) $_POST['labdef'][$ind] - 1); } } if (empty($criteria) || empty($actions) && !$doDelete) { fatal_lang_error('pm_rule_no_criteria', false); } // What are we storing? $criteria = serialize($criteria); $actions = serialize($actions); // Create the rule? if (empty($context['rid'])) { addPMRule($user_info['id'], $ruleName, $criteria, $actions, $doDelete, $isOr); } else { updatePMRule($user_info['id'], $context['rid'], $ruleName, $criteria, $actions, $doDelete, $isOr); } redirectexit('action=pm;sa=manrules'); } elseif (isset($_POST['delselected']) && !empty($_POST['delrule'])) { checkSession('post'); $toDelete = array(); foreach ($_POST['delrule'] as $k => $v) { $toDelete[] = (int) $k; } if (!empty($toDelete)) { deletePMRules($user_info['id'], $toDelete); } redirectexit('action=pm;sa=manrules'); } }