/**
     * Issue/manage an user's warning status.
     * @uses ProfileAccount template issueWarning sub template
     * @uses Profile template
     */
    public function action_issuewarning()
    {
        global $txt, $scripturl, $modSettings, $mbname, $context, $cur_profile;
        $memID = currentMemberID();
        // make sure the sub-template is set...
        loadTemplate('ProfileAccount');
        $context['sub_template'] = 'issueWarning';
        // We need this because of template_load_warning_variables
        loadTemplate('Profile');
        loadJavascriptFile('profile.js');
        // jQuery-UI FTW!
        $modSettings['jquery_include_ui'] = true;
        loadCSSFile('jquery.ui.slider.css');
        loadCSSFile('jquery.ui.theme.css');
        // Get all the actual settings.
        list($modSettings['warning_enable'], $modSettings['user_limit']) = explode(',', $modSettings['warning_settings']);
        // This stores any legitimate errors.
        $issueErrors = array();
        // Doesn't hurt to be overly cautious.
        if (empty($modSettings['warning_enable']) || $context['user']['is_owner'] && !$cur_profile['warning'] || !allowedTo('issue_warning')) {
            fatal_lang_error('no_access', false);
        }
        // Get the base (errors related) stuff done.
        loadLanguage('Errors');
        $context['custom_error_title'] = $txt['profile_warning_errors_occurred'];
        // Make sure things which are disabled stay disabled.
        $modSettings['warning_watch'] = !empty($modSettings['warning_watch']) ? $modSettings['warning_watch'] : 110;
        $modSettings['warning_moderate'] = !empty($modSettings['warning_moderate']) && !empty($modSettings['postmod_active']) ? $modSettings['warning_moderate'] : 110;
        $modSettings['warning_mute'] = !empty($modSettings['warning_mute']) ? $modSettings['warning_mute'] : 110;
        $context['warning_limit'] = allowedTo('admin_forum') ? 0 : $modSettings['user_limit'];
        $context['member']['warning'] = $cur_profile['warning'];
        $context['member']['name'] = $cur_profile['real_name'];
        // What are the limits we can apply?
        $context['min_allowed'] = 0;
        $context['max_allowed'] = 100;
        if ($context['warning_limit'] > 0) {
            require_once SUBSDIR . '/Moderation.subs.php';
            $current_applied = warningDailyLimit($memID);
            $context['min_allowed'] = max(0, $cur_profile['warning'] - $current_applied - $context['warning_limit']);
            $context['max_allowed'] = min(100, $cur_profile['warning'] - $current_applied + $context['warning_limit']);
        }
        // Defaults.
        $context['warning_data'] = array('reason' => '', 'notify' => '', 'notify_subject' => '', 'notify_body' => '');
        // Are we saving?
        if (isset($_POST['save'])) {
            // Security is good here.
            checkSession('post');
            // This cannot be empty!
            $_POST['warn_reason'] = isset($_POST['warn_reason']) ? trim($_POST['warn_reason']) : '';
            if ($_POST['warn_reason'] == '' && !$context['user']['is_owner']) {
                $issueErrors[] = 'warning_no_reason';
            }
            $_POST['warn_reason'] = Util::htmlspecialchars($_POST['warn_reason']);
            // If the value hasn't changed it's either no JS or a real no change (Which this will pass)
            if ($_POST['warning_level'] == 'SAME') {
                $_POST['warning_level'] = $_POST['warning_level_nojs'];
            }
            $_POST['warning_level'] = (int) $_POST['warning_level'];
            $_POST['warning_level'] = max(0, min(100, $_POST['warning_level']));
            if ($_POST['warning_level'] < $context['min_allowed']) {
                $_POST['warning_level'] = $context['min_allowed'];
            } elseif ($_POST['warning_level'] > $context['max_allowed']) {
                $_POST['warning_level'] = $context['max_allowed'];
            }
            require_once SUBSDIR . '/Moderation.subs.php';
            // Do we actually have to issue them with a PM?
            $id_notice = 0;
            if (!empty($_POST['warn_notify']) && empty($issueErrors)) {
                $_POST['warn_sub'] = trim($_POST['warn_sub']);
                $_POST['warn_body'] = trim($_POST['warn_body']);
                if (empty($_POST['warn_sub']) || empty($_POST['warn_body'])) {
                    $issueErrors[] = 'warning_notify_blank';
                } else {
                    require_once SUBSDIR . '/PersonalMessage.subs.php';
                    $from = array('id' => 0, 'name' => $context['forum_name'], 'username' => $context['forum_name']);
                    sendpm(array('to' => array($memID), 'bcc' => array()), $_POST['warn_sub'], $_POST['warn_body'], false, $from);
                    // Log the notice.
                    $id_notice = logWarningNotice($_POST['warn_sub'], $_POST['warn_body']);
                }
            }
            // Just in case - make sure notice is valid!
            $id_notice = (int) $id_notice;
            // What have we changed?
            $level_change = $_POST['warning_level'] - $cur_profile['warning'];
            // No errors? Proceed! Only log if you're not the owner.
            if (empty($issueErrors)) {
                // Log what we've done!
                if (!$context['user']['is_owner']) {
                    logWarning($memID, $cur_profile['real_name'], $id_notice, $level_change, $_POST['warn_reason']);
                }
                // Make the change.
                updateMemberData($memID, array('warning' => $_POST['warning_level']));
                // Leave a lovely message.
                $context['profile_updated'] = $context['user']['is_owner'] ? $txt['profile_updated_own'] : $txt['profile_warning_success'];
            } else {
                // Try to remember some bits.
                $context['warning_data'] = array('reason' => $_POST['warn_reason'], 'notify' => !empty($_POST['warn_notify']), 'notify_subject' => isset($_POST['warn_sub']) ? $_POST['warn_sub'] : '', 'notify_body' => isset($_POST['warn_body']) ? $_POST['warn_body'] : '');
            }
            // Show the new improved warning level.
            $context['member']['warning'] = $_POST['warning_level'];
        }
        // Taking a look first, good idea that one.
        if (isset($_POST['preview'])) {
            $warning_body = !empty($_POST['warn_body']) ? trim(censorText($_POST['warn_body'])) : '';
            $context['preview_subject'] = !empty($_POST['warn_sub']) ? trim(Util::htmlspecialchars($_POST['warn_sub'])) : '';
            if (empty($_POST['warn_sub']) || empty($_POST['warn_body'])) {
                $issueErrors[] = 'warning_notify_blank';
            }
            if (!empty($_POST['warn_body'])) {
                require_once SUBSDIR . '/Post.subs.php';
                preparsecode($warning_body);
                $warning_body = parse_bbc($warning_body, true);
            }
            // Try to remember some bits.
            $context['warning_data'] = array('reason' => $_POST['warn_reason'], 'notify' => !empty($_POST['warn_notify']), 'notify_subject' => isset($_POST['warn_sub']) ? $_POST['warn_sub'] : '', 'notify_body' => isset($_POST['warn_body']) ? $_POST['warn_body'] : '', 'body_preview' => $warning_body);
        }
        if (!empty($issueErrors)) {
            // Fill in the suite of errors.
            $context['post_errors'] = array();
            foreach ($issueErrors as $error) {
                $context['post_errors'][] = $txt[$error];
            }
        }
        $context['page_title'] = $txt['profile_issue_warning'];
        // Let's use a generic list to get all the current warnings
        require_once SUBSDIR . '/GenericList.class.php';
        require_once SUBSDIR . '/Profile.subs.php';
        // Work our the various levels.
        $context['level_effects'] = array(0 => $txt['profile_warning_effect_none'], $modSettings['warning_watch'] => $txt['profile_warning_effect_watch'], $modSettings['warning_moderate'] => $txt['profile_warning_effect_moderation'], $modSettings['warning_mute'] => $txt['profile_warning_effect_mute']);
        $context['current_level'] = 0;
        foreach ($context['level_effects'] as $limit => $dummy) {
            if ($context['member']['warning'] >= $limit) {
                $context['current_level'] = $limit;
            }
        }
        // Build a list to view the warnings
        $listOptions = array('id' => 'issued_warnings', 'title' => $txt['profile_viewwarning_previous_warnings'], 'items_per_page' => $modSettings['defaultMaxMessages'], 'no_items_label' => $txt['profile_viewwarning_no_warnings'], 'base_href' => $scripturl . '?action=profile;area=issuewarning;sa=user;u=' . $memID, 'default_sort_col' => 'log_time', 'get_items' => array('function' => 'list_getUserWarnings', 'params' => array($memID)), 'get_count' => array('function' => 'list_getUserWarningCount', 'params' => array($memID)), 'columns' => array('issued_by' => array('header' => array('value' => $txt['profile_warning_previous_issued'], 'style' => 'width: 20%;'), 'data' => array('function' => create_function('$warning', '
							return $warning[\'issuer\'][\'link\'];
						')), 'sort' => array('default' => 'lc.member_name DESC', 'reverse' => 'lc.member_name')), 'log_time' => array('header' => array('value' => $txt['profile_warning_previous_time'], 'style' => 'width: 30%;'), 'data' => array('db' => 'time'), 'sort' => array('default' => 'lc.log_time DESC', 'reverse' => 'lc.log_time')), 'reason' => array('header' => array('value' => $txt['profile_warning_previous_reason']), 'data' => array('function' => create_function('$warning', '
							global $scripturl, $txt, $settings;

							$ret = \'
							<div class="floatleft">
								\' . $warning[\'reason\'] . \'
							</div>\';

							// If a notice was sent, provide a way to view it
							if (!empty($warning[\'id_notice\']))
								$ret .= \'
							<div class="floatright">
								<a href="\' . $scripturl . \'?action=moderate;area=notice;nid=\' . $warning[\'id_notice\'] . \'" onclick="window.open(this.href, \\\'\\\', \\\'scrollbars=yes,resizable=yes,width=400,height=250\\\');return false;" target="_blank" class="new_win" title="\' . $txt[\'profile_warning_previous_notice\'] . \'"><img src="\' . $settings[\'images_url\'] . \'/filter.png" alt="" /></a>
							</div>\';

							return $ret;'))), 'level' => array('header' => array('value' => $txt['profile_warning_previous_level'], 'style' => 'width: 6%;'), 'data' => array('db' => 'counter'), 'sort' => array('default' => 'lc.counter DESC', 'reverse' => 'lc.counter'))));
        // Create the list for viewing.
        createList($listOptions);
        $warning_for_message = isset($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : false;
        $warned_message_subject = '';
        // Are they warning because of a message?
        if (isset($_REQUEST['msg']) && 0 < (int) $_REQUEST['msg']) {
            require_once SUBSDIR . '/Messages.subs.php';
            $message = basicMessageInfo((int) $_REQUEST['msg']);
            if (!empty($message)) {
                $warned_message_subject = $message['subject'];
            }
        }
        require_once SUBSDIR . '/Maillist.subs.php';
        // Any custom templates?
        $context['notification_templates'] = array();
        $notification_templates = maillist_templates('warntpl');
        foreach ($notification_templates as $row) {
            // If we're not warning for a message skip any that are.
            if (!$warning_for_message && strpos($row['body'], '{MESSAGE}') !== false) {
                continue;
            }
            $context['notification_templates'][] = array('title' => $row['title'], 'body' => $row['body']);
        }
        // Setup the "default" templates.
        foreach (array('spamming', 'offence', 'insulting') as $type) {
            $context['notification_templates'][] = array('title' => $txt['profile_warning_notify_title_' . $type], 'body' => sprintf($txt['profile_warning_notify_template_outline' . (!empty($warning_for_message) ? '_post' : '')], $txt['profile_warning_notify_for_' . $type]));
        }
        // Replace all the common variables in the templates.
        foreach ($context['notification_templates'] as $k => $name) {
            $context['notification_templates'][$k]['body'] = strtr($name['body'], array('{MEMBER}' => un_htmlspecialchars($context['member']['name']), '{MESSAGE}' => '[url=' . $scripturl . '?msg=' . $warning_for_message . ']' . un_htmlspecialchars($warned_message_subject) . '[/url]', '{SCRIPTURL}' => $scripturl, '{FORUMNAME}' => $mbname, '{REGARDS}' => replaceBasicActionUrl($txt['regards_team'])));
        }
    }
 /**
  * Allows the admin to choose from predefined and custom templates
  *
  * - Uses the selected template to send a bounce notification with
  * details as specified by the template
  * - Accessd by ?action=admin;area=maillist;sa=bounce;item=?'
  * - Redirects to action=admin;area=maillist;sa=bounced
  *
  * @uses bounce_email sub-template
  */
 public function action_bounce_email()
 {
     global $context, $txt, $modSettings, $scripturl, $mbname;
     if (!isset($_REQUEST['bounce'])) {
         checkSession('get');
         validateToken('admin-ml', 'get');
     }
     require_once SUBSDIR . '/Mail.subs.php';
     // We should have been sent an email ID
     if (isset($_REQUEST['item'])) {
         // Needs to be an int!
         $id = (int) $_REQUEST['item'];
         // Load up the email details, no funny biz yall ;)
         $temp_email = list_maillist_unapproved($id);
         if (!empty($temp_email)) {
             // Set the options
             $_POST['item'] = (int) $temp_email[0]['id_email'];
             $fullerrortext = $txt[$temp_email[0]['error_code']];
             // Build the template selection area, first the standard ones
             $bounce = array('bounce', 'inform');
             foreach ($bounce as $k => $type) {
                 $context['bounce_templates'][$k]['body'] = $txt['ml_' . $type . '_body'];
                 $context['bounce_templates'][$k]['subject'] = $txt['ml_' . $type . '_subject'];
                 $context['bounce_templates'][$k]['title'] = $txt['ml_' . $type . '_title'];
             }
             // And now any custom ones available for this moderator
             $context['bounce_templates'] += array_merge($context['bounce_templates'], maillist_templates('bnctpl', $txt['ml_bounce_template_subject_default']));
             // Replace all the variables in the templates
             foreach ($context['bounce_templates'] as $k => $name) {
                 $context['bounce_templates'][$k]['body'] = strtr($name['body'], array('{MEMBER}' => un_htmlspecialchars($temp_email[0]['name']), '{SCRIPTURL}' => $scripturl, '{FORUMNAME}' => $mbname, '{REGARDS}' => replaceBasicActionUrl($txt['regards_team']), '{SUBJECT}' => $temp_email[0]['subject'], '{ERROR}' => $fullerrortext, '{FORUMNAME}' => $mbname, '{FORUMNAMESHORT}' => !empty($modSettings['maillist_sitename']) ? $modSettings['maillist_sitename'] : $mbname, '{EMAILREGARDS}' => !empty($modSettings['maillist_sitename_regards']) ? $modSettings['maillist_sitename_regards'] : ''));
             }
         } else {
             $context['settings_message'] = $txt['badid'];
         }
     } else {
         $context['settings_message'] = $txt['badid'];
     }
     // Check if they are sending the notice
     if (isset($_REQUEST['bounce']) && isset($temp_email)) {
         checkSession('post');
         validateToken('admin-ml');
         // They did check the box, how else could they have posted
         if (isset($_POST['warn_notify'])) {
             // lets make sure we have the items to send it
             $check_emails = explode('=>', $temp_email[0]['from']);
             $to = trim($check_emails[0]);
             $subject = trim($_POST['warn_sub']);
             $body = trim($_POST['warn_body']);
             if (empty($body) || empty($subject)) {
                 $context['settings_message'] = $txt['bad_bounce'];
             } else {
                 // Time for someone to get a we're so sorry message!
                 sendmail($to, $subject, $body, null, null, false, 5);
                 redirectexit('action=admin;area=maillist;bounced');
             }
         }
     }
     // Prepare and show the template
     createToken('admin-ml');
     $context['warning_data'] = array('notify' => '', 'notify_subject' => '', 'notify_body' => '');
     $context['body'] = isset($fullerrortext) ? parse_bbc($fullerrortext) : '';
     $context['item'] = isset($_POST['item']) ? $_POST['item'] : '';
     $context['notice_to'] = $txt['to'] . ' ' . isset($temp_email[0]['from']) ? $temp_email[0]['from'] : '';
     $context['page_title'] = $txt['bounce_title'];
     $context['sub_template'] = 'bounce_email';
 }