Ejemplo n.º 1
0
 protected function cleanMessage()
 {
     $this->message = Util::htmlspecialchars($this->message, ENT_QUOTES, 'UTF-8', true);
     $this->message = strtr($this->message, array("\r" => '', '[]' => '[]', '['' => '[''));
     // Clean up any cut/paste issues we may have
     $this->message = sanitizeMSCutPaste($this->message);
 }
 /**
  * Common actions for all methods in the class
  */
 public function pre_dispatch()
 {
     global $context;
     $context['page_title'] = $context['forum_name'];
     if (isset($context['page_title_html_safe'])) {
         $context['page_title_html_safe'] = Util::htmlspecialchars(un_htmlspecialchars($context['page_title']));
     }
     if (!empty($context['standalone'])) {
         setupMenuContext();
     }
 }
Ejemplo n.º 3
0
 /**
  * Show boxes with more detailed help on items, when the user clicks on their help icon.
  * It handles both administrative or user help.
  * Data: $_GET['help'] parameter, it holds what string to display
  * and where to get the string from. ($helptxt or $txt)
  * It is accessed via ?action=quickhelp;help=?.
  *
  * @uses ManagePermissions language file, if the help starts with permissionhelp.
  * @uses Help template, 'popup' sub-template.
  */
 public function action_quickhelp()
 {
     global $txt, $helptxt, $context, $scripturl;
     if (!isset($_GET['help']) || !is_string($_GET['help'])) {
         fatal_lang_error('no_access', false);
     }
     if (!isset($helptxt)) {
         $helptxt = array();
     }
     $help_str = Util::htmlspecialchars($_GET['help']);
     // Load the admin help language file and template.
     loadLanguage('Help');
     // Load permission specific help
     if (substr($help_str, 0, 14) == 'permissionhelp') {
         loadLanguage('ManagePermissions');
     }
     // Load our template
     loadTemplate('Help');
     // Allow addons to load their own language file here.
     call_integration_hook('integrate_quickhelp');
     // Set the page title to something relevant.
     $context['page_title'] = $context['forum_name'] . ' - ' . $txt['help'];
     // Only show the 'popup' sub-template, no layers.
     Template_Layers::getInstance()->removeAll();
     $context['sub_template'] = 'popup';
     $helps = explode('+', $help_str);
     $context['help_text'] = '';
     // Find what to display: the string will be in $helptxt['help'] or in $txt['help]
     foreach ($helps as $help) {
         if (isset($helptxt[$help])) {
             $context['help_text'] .= $helptxt[$help];
         } elseif (isset($txt[$help])) {
             $context['help_text'] .= $txt[$help];
         } else {
             // nothing :(
             $context['help_text'] .= $help;
         }
     }
     // Link to the forum URL, and include session id.
     if (preg_match('~%([0-9]+\\$)?s\\?~', $context['help_text'], $match)) {
         $context['help_text'] = sprintf($context['help_text'], $scripturl, $context['session_id'], $context['session_var']);
     }
 }
Ejemplo n.º 4
0
/**
 * Images cache
 *
 * @name      Images cache
 * @copyright Images cache contributors
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
 *
 * @version 0.1
 *
 */
function imageNeedsCache($img)
{
    global $boardurl, $txt;
    static $js_loaded = false;
    $parseboard = parse_url($boardurl);
    $parseimg = parse_url($img);
    if (!($parseboard['scheme'] === 'https') || $parseboard['scheme'] === $parseimg['scheme']) {
        return false;
    }
    if ($js_loaded === false) {
        $js_loaded = true;
        loadJavascriptFile('imgcache.js', array('defer' => true));
        loadLanguage('imgcache');
    }
    require_once SUBSDIR . '/Graphics.subs.php';
    $destination = CACHEDIR . '/img_cache_' . md5($img);
    if (!file_exists($destination)) {
        resizeImageFile($img, $destination, 200, 200, 3);
    }
    return $boardurl . '/imgcache.php?id=' . md5($img) . '" rel="cached" data-warn="' . Util::htmlspecialchars($txt['httpimgcache_warn_ext']) . '" data-url="' . Util::htmlspecialchars($img);
}
 /**
  * View a specific category, showing all articles it contains
  */
 public function action_sportal_category()
 {
     global $context, $scripturl, $modSettings;
     // Basic article support
     require_once SUBSDIR . '/PortalArticle.subs.php';
     $category_id = !empty($_REQUEST['category']) ? $_REQUEST['category'] : 0;
     if (is_int($category_id)) {
         $category_id = (int) $category_id;
     } else {
         $category_id = Util::htmlspecialchars($category_id, ENT_QUOTES);
     }
     $context['category'] = sportal_get_categories($category_id, true, true);
     if (empty($context['category']['id'])) {
         fatal_lang_error('error_sp_category_not_found', false);
     }
     // Set up the pages
     $total_articles = sportal_get_articles_in_cat_count($context['category']['id']);
     $per_page = min($total_articles, !empty($modSettings['sp_articles_per_page']) ? $modSettings['sp_articles_per_page'] : 10);
     $start = !empty($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
     if ($total_articles > $per_page) {
         $context['page_index'] = constructPageIndex($context['category']['href'] . ';start=%1$d', $start, $total_articles, $per_page, true);
     }
     // Load the articles in this category
     $context['articles'] = sportal_get_articles(0, true, true, 'spa.id_article DESC', $context['category']['id'], $per_page, $start);
     foreach ($context['articles'] as $article) {
         // Cut me mick
         if (($cutoff = Util::strpos($article['body'], '[cutoff]')) !== false) {
             $article['body'] = Util::substr($article['body'], 0, $cutoff);
             if ($article['type'] === 'bbc') {
                 require_once SUBSDIR . '/Post.subs.php';
                 preparsecode($article['body']);
             }
         }
         $context['articles'][$article['id']]['preview'] = sportal_parse_content($article['body'], $article['type'], 'return');
         $context['articles'][$article['id']]['date'] = htmlTime($article['date']);
     }
     $context['linktree'][] = array('url' => $scripturl . '?category=' . $context['category']['category_id'], 'name' => $context['category']['name']);
     $context['page_title'] = $context['category']['name'];
     $context['sub_template'] = 'view_category';
 }
Ejemplo n.º 6
0
 /**
  * Actually register the member.
  * @todo split this function in two functions:
  *  - a function that handles action=register2, which needs no parameter;
  *  - a function that processes the case of OpenID verification.
  *
  * @param bool $verifiedOpenID = false
  */
 public function action_register2($verifiedOpenID = false)
 {
     global $txt, $modSettings, $context, $user_info;
     // Start collecting together any errors.
     $reg_errors = Error_Context::context('register', 0);
     // We can't validate the token and the session with OpenID enabled.
     if (!$verifiedOpenID) {
         checkSession();
         if (!validateToken('register', 'post', true, false)) {
             $reg_errors->addError('token_verification');
         }
     }
     // Did we save some open ID fields?
     if ($verifiedOpenID && !empty($context['openid_save_fields'])) {
         foreach ($context['openid_save_fields'] as $id => $value) {
             $_POST[$id] = $value;
         }
     }
     // You can't register if it's disabled.
     if (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 3) {
         fatal_lang_error('registration_disabled', false);
     }
     // If we're using an agreement checkbox, did they check it?
     if (!empty($modSettings['checkboxAgreement']) && !empty($_POST['checkbox_agreement'])) {
         $_SESSION['registration_agreed'] = true;
     }
     // Things we don't do for people who have already confirmed their OpenID allegances via register.
     if (!$verifiedOpenID) {
         // Well, if you don't agree, you can't register.
         if (!empty($modSettings['requireAgreement']) && empty($_SESSION['registration_agreed'])) {
             redirectexit();
         }
         // Make sure they came from *somewhere*, have a session.
         if (!isset($_SESSION['old_url'])) {
             redirectexit('action=register');
         }
         // If we don't require an agreement, we need a extra check for coppa.
         if (empty($modSettings['requireAgreement']) && !empty($modSettings['coppaAge'])) {
             $_SESSION['skip_coppa'] = !empty($_POST['accept_agreement']);
         }
         // Are they under age, and under age users are banned?
         if (!empty($modSettings['coppaAge']) && empty($modSettings['coppaType']) && empty($_SESSION['skip_coppa'])) {
             loadLanguage('Login');
             fatal_lang_error('under_age_registration_prohibited', false, array($modSettings['coppaAge']));
         }
         // Check the time gate for miscreants. First make sure they came from somewhere that actually set it up.
         if (empty($_SESSION['register']['timenow']) || empty($_SESSION['register']['limit'])) {
             redirectexit('action=register');
         }
         // Failing that, check the time limit for exessive speed.
         if (time() - $_SESSION['register']['timenow'] < $_SESSION['register']['limit']) {
             loadLanguage('Login');
             $reg_errors->addError('too_quickly');
         }
         // Check whether the visual verification code was entered correctly.
         if (!empty($modSettings['reg_verification'])) {
             require_once SUBSDIR . '/VerificationControls.class.php';
             $verificationOptions = array('id' => 'register');
             $context['visual_verification'] = create_control_verification($verificationOptions, true);
             if (is_array($context['visual_verification'])) {
                 foreach ($context['visual_verification'] as $error) {
                     $reg_errors->addError($error);
                 }
             }
         }
     }
     foreach ($_POST as $key => $value) {
         if (!is_array($_POST[$key])) {
             $_POST[$key] = htmltrim__recursive(str_replace(array("\n", "\r"), '', $_POST[$key]));
         }
     }
     // Collect all extra registration fields someone might have filled in.
     $possible_strings = array('birthdate', 'time_format', 'buddy_list', 'pm_ignore_list', 'smiley_set', 'personal_text', 'avatar', 'lngfile', 'location', 'secret_question', 'secret_answer', 'website_url', 'website_title');
     $possible_ints = array('pm_email_notify', 'notify_types', 'id_theme', 'gender');
     $possible_floats = array('time_offset');
     $possible_bools = array('notify_announcements', 'notify_regularity', 'notify_send_body', 'hide_email', 'show_online');
     if (isset($_POST['secret_answer']) && $_POST['secret_answer'] != '') {
         $_POST['secret_answer'] = md5($_POST['secret_answer']);
     }
     // Needed for isReservedName() and registerMember().
     require_once SUBSDIR . '/Members.subs.php';
     // Validation... even if we're not a mall.
     if (isset($_POST['real_name']) && (!empty($modSettings['allow_editDisplayName']) || allowedTo('moderate_forum'))) {
         $_POST['real_name'] = trim(preg_replace('~[\\t\\n\\r \\x0B\\0\\x{A0}\\x{AD}\\x{2000}-\\x{200F}\\x{201F}\\x{202F}\\x{3000}\\x{FEFF}]+~u', ' ', $_POST['real_name']));
         if (trim($_POST['real_name']) != '' && !isReservedName($_POST['real_name']) && Util::strlen($_POST['real_name']) < 60) {
             $possible_strings[] = 'real_name';
         }
     }
     // Handle a string as a birthdate...
     if (isset($_POST['birthdate']) && $_POST['birthdate'] != '') {
         $_POST['birthdate'] = strftime('%Y-%m-%d', strtotime($_POST['birthdate']));
     } elseif (!empty($_POST['bday1']) && !empty($_POST['bday2'])) {
         $_POST['birthdate'] = sprintf('%04d-%02d-%02d', empty($_POST['bday3']) ? 0 : (int) $_POST['bday3'], (int) $_POST['bday1'], (int) $_POST['bday2']);
     }
     // By default assume email is hidden, only show it if we tell it to.
     $_POST['hide_email'] = !empty($_POST['allow_email']) ? 0 : 1;
     // Validate the passed language file.
     if (isset($_POST['lngfile']) && !empty($modSettings['userLanguage'])) {
         // Do we have any languages?
         $context['languages'] = getLanguages();
         // Did we find it?
         if (isset($context['languages'][$_POST['lngfile']])) {
             $_SESSION['language'] = $_POST['lngfile'];
         } else {
             unset($_POST['lngfile']);
         }
     } else {
         unset($_POST['lngfile']);
     }
     // Some of these fields we may not want.
     if (!empty($modSettings['registration_fields'])) {
         // But we might want some of them if the admin asks for them.
         $standard_fields = array('location', 'gender');
         $reg_fields = explode(',', $modSettings['registration_fields']);
         $exclude_fields = array_diff($standard_fields, $reg_fields);
         // Website is a little different
         if (!in_array('website', $reg_fields)) {
             $exclude_fields = array_merge($exclude_fields, array('website_url', 'website_title'));
         }
         // We used to accept signature on registration but it's being abused by spammers these days, so no more.
         $exclude_fields[] = 'signature';
     } else {
         $exclude_fields = array('signature', 'location', 'gender', 'website_url', 'website_title');
     }
     $possible_strings = array_diff($possible_strings, $exclude_fields);
     $possible_ints = array_diff($possible_ints, $exclude_fields);
     $possible_floats = array_diff($possible_floats, $exclude_fields);
     $possible_bools = array_diff($possible_bools, $exclude_fields);
     // Set the options needed for registration.
     $regOptions = array('interface' => 'guest', 'username' => !empty($_POST['user']) ? $_POST['user'] : '', 'email' => !empty($_POST['email']) ? $_POST['email'] : '', 'password' => !empty($_POST['passwrd1']) ? $_POST['passwrd1'] : '', 'password_check' => !empty($_POST['passwrd2']) ? $_POST['passwrd2'] : '', 'openid' => !empty($_POST['openid_identifier']) ? $_POST['openid_identifier'] : '', 'auth_method' => !empty($_POST['authenticate']) ? $_POST['authenticate'] : '', 'check_reserved_name' => true, 'check_password_strength' => true, 'check_email_ban' => true, 'send_welcome_email' => !empty($modSettings['send_welcomeEmail']), 'require' => !empty($modSettings['coppaAge']) && !$verifiedOpenID && empty($_SESSION['skip_coppa']) ? 'coppa' : (empty($modSettings['registration_method']) ? 'nothing' : ($modSettings['registration_method'] == 1 ? 'activation' : 'approval')), 'extra_register_vars' => array(), 'theme_vars' => array());
     // Include the additional options that might have been filled in.
     foreach ($possible_strings as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = Util::htmlspecialchars($_POST[$var], ENT_QUOTES);
         }
     }
     foreach ($possible_ints as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = (int) $_POST[$var];
         }
     }
     foreach ($possible_floats as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = (double) $_POST[$var];
         }
     }
     foreach ($possible_bools as $var) {
         if (isset($_POST[$var])) {
             $regOptions['extra_register_vars'][$var] = empty($_POST[$var]) ? 0 : 1;
         }
     }
     // Registration options are always default options...
     if (isset($_POST['default_options'])) {
         $_POST['options'] = isset($_POST['options']) ? $_POST['options'] + $_POST['default_options'] : $_POST['default_options'];
     }
     $regOptions['theme_vars'] = isset($_POST['options']) && is_array($_POST['options']) ? $_POST['options'] : array();
     // Make sure they are clean, dammit!
     $regOptions['theme_vars'] = htmlspecialchars__recursive($regOptions['theme_vars']);
     // Check whether we have fields that simply MUST be displayed?
     require_once SUBSDIR . '/Profile.subs.php';
     loadCustomFields(0, 'register');
     foreach ($context['custom_fields'] as $row) {
         // Don't allow overriding of the theme variables.
         if (isset($regOptions['theme_vars'][$row['colname']])) {
             unset($regOptions['theme_vars'][$row['colname']]);
         }
         // Prepare the value!
         $value = isset($_POST['customfield'][$row['colname']]) ? trim($_POST['customfield'][$row['colname']]) : '';
         // We only care for text fields as the others are valid to be empty.
         if (!in_array($row['type'], array('check', 'select', 'radio'))) {
             // Is it too long?
             if ($row['field_length'] && $row['field_length'] < Util::strlen($value)) {
                 $reg_errors->addError(array('custom_field_too_long', array($row['name'], $row['field_length'])));
             }
             // Any masks to apply?
             if ($row['type'] == 'text' && !empty($row['mask']) && $row['mask'] != 'none') {
                 // @todo We never error on this - just ignore it at the moment...
                 if ($row['mask'] == 'email' && !isValidEmail($value)) {
                     $reg_errors->addError(array('custom_field_invalid_email', array($row['name'])));
                 } elseif ($row['mask'] == 'number' && preg_match('~[^\\d]~', $value)) {
                     $reg_errors->addError(array('custom_field_not_number', array($row['name'])));
                 } elseif (substr($row['mask'], 0, 5) == 'regex' && trim($value) !== '' && preg_match(substr($row['mask'], 5), $value) === 0) {
                     $reg_errors->addError(array('custom_field_inproper_format', array($row['name'])));
                 }
             }
         }
         // Is this required but not there?
         if (trim($value) == '' && $row['show_reg'] > 1) {
             $reg_errors->addError(array('custom_field_empty', array($row['name'])));
         }
     }
     // Lets check for other errors before trying to register the member.
     if ($reg_errors->hasErrors()) {
         $_REQUEST['step'] = 2;
         // If they've filled in some details but made an error then they need less time to finish
         $_SESSION['register']['limit'] = 4;
         return $this->action_register();
     }
     // If they're wanting to use OpenID we need to validate them first.
     if (empty($_SESSION['openid']['verified']) && !empty($_POST['authenticate']) && $_POST['authenticate'] == 'openid') {
         // What do we need to save?
         $save_variables = array();
         foreach ($_POST as $k => $v) {
             if (!in_array($k, array('sc', 'sesc', $context['session_var'], 'passwrd1', 'passwrd2', 'regSubmit'))) {
                 $save_variables[$k] = $v;
             }
         }
         require_once SUBSDIR . '/OpenID.subs.php';
         $openID = new OpenID();
         $openID->validate($_POST['openid_identifier'], false, $save_variables);
     } elseif ($verifiedOpenID || (!empty($_POST['openid_identifier']) || !empty($_SESSION['openid']['openid_uri'])) && $_POST['authenticate'] == 'openid') {
         $regOptions['username'] = !empty($_POST['user']) && trim($_POST['user']) != '' ? $_POST['user'] : $_SESSION['openid']['nickname'];
         $regOptions['email'] = !empty($_POST['email']) && trim($_POST['email']) != '' ? $_POST['email'] : $_SESSION['openid']['email'];
         $regOptions['auth_method'] = 'openid';
         $regOptions['openid'] = !empty($_SESSION['openid']['openid_uri']) ? $_SESSION['openid']['openid_uri'] : (!empty($_POST['openid_identifier']) ? $_POST['openid_identifier'] : '');
     }
     // Registration needs to know your IP
     $req = request();
     $regOptions['ip'] = $user_info['ip'];
     $regOptions['ip2'] = $req->ban_ip();
     $memberID = registerMember($regOptions, 'register');
     // If there are "important" errors and you are not an admin: log the first error
     // Otherwise grab all of them and don't log anything
     if ($reg_errors->hasErrors(1) && !$user_info['is_admin']) {
         foreach ($reg_errors->prepareErrors(1) as $error) {
             fatal_error($error, 'general');
         }
     }
     // Was there actually an error of some kind dear boy?
     if ($reg_errors->hasErrors()) {
         $_REQUEST['step'] = 2;
         return $this->action_register();
     }
     // Do our spam protection now.
     spamProtection('register');
     // We'll do custom fields after as then we get to use the helper function!
     if (!empty($_POST['customfield'])) {
         require_once SUBSDIR . '/Profile.subs.php';
         makeCustomFieldChanges($memberID, 'register');
     }
     // If COPPA has been selected then things get complicated, setup the template.
     if (!empty($modSettings['coppaAge']) && empty($_SESSION['skip_coppa'])) {
         redirectexit('action=coppa;member=' . $memberID);
     } elseif (!empty($modSettings['registration_method'])) {
         loadTemplate('Register');
         $context += array('page_title' => $txt['register'], 'title' => $txt['registration_successful'], 'sub_template' => 'after', 'description' => $modSettings['registration_method'] == 2 ? $txt['approval_after_registration'] : $txt['activate_after_registration']);
     } else {
         call_integration_hook('integrate_activate', array($regOptions['username']));
         setLoginCookie(60 * $modSettings['cookieTime'], $memberID, hash('sha256', Util::strtolower($regOptions['username']) . $regOptions['password'] . $regOptions['register_vars']['password_salt']));
         redirectexit('action=auth;sa=check;member=' . $memberID, $context['server']['needs_login_fix']);
     }
 }
Ejemplo n.º 7
0
/**
 * Modifies an event.
 *
 * - allows to either set a time span (in days) or an end_date.
 * - does not check any permissions of any sort.
 *
 * @package Calendar
 * @param int $event_id
 * @param mixed[] $eventOptions
 */
function modifyEvent($event_id, &$eventOptions)
{
    $db = database();
    // Properly sanitize the title.
    $eventOptions['title'] = Util::htmlspecialchars($eventOptions['title'], ENT_QUOTES);
    // Scan the start date for validity and get its components.
    if (($num_results = sscanf($eventOptions['start_date'], '%d-%d-%d', $year, $month, $day)) !== 3) {
        trigger_error('modifyEvent(): invalid start date format given', E_USER_ERROR);
    }
    // Default span to 0 days.
    $eventOptions['span'] = isset($eventOptions['span']) ? (int) $eventOptions['span'] : 0;
    // Set the end date to the start date + span (if the end date wasn't already given).
    if (!isset($eventOptions['end_date'])) {
        $eventOptions['end_date'] = strftime('%Y-%m-%d', mktime(0, 0, 0, $month, $day, $year) + $eventOptions['span'] * 86400);
    }
    $event_columns = array('start_date' => 'start_date = {date:start_date}', 'end_date' => 'end_date = {date:end_date}', 'title' => 'title = SUBSTRING({string:title}, 1, 60)', 'id_board' => 'id_board = {int:id_board}', 'id_topic' => 'id_topic = {int:id_topic}');
    call_integration_hook('integrate_modify_event', array($event_id, &$eventOptions, &$event_columns));
    $eventOptions['id_event'] = $event_id;
    $to_update = array();
    foreach ($event_columns as $key => $value) {
        if (isset($eventOptions[$key])) {
            $to_update[] = $value;
        }
    }
    if (empty($to_update)) {
        return;
    }
    $db->query('', '
		UPDATE {db_prefix}calendar
		SET
			' . implode(', ', $to_update) . '
		WHERE id_event = {int:id_event}', $eventOptions);
    updateSettings(array('calendar_updated' => time()));
}
Ejemplo n.º 8
0
/**
 * This function validates the ban triggers
 *
 * @package Bans
 * @param mixed[] $triggers
 */
function validateTriggers(&$triggers)
{
    $db = database();
    $ban_errors = Error_Context::context('ban', 1);
    if (empty($triggers)) {
        $ban_errors->addError('ban_empty_triggers');
    }
    $ban_triggers = array();
    $log_info = array();
    // Go through each trigger and make sure its valid
    foreach ($triggers as $key => $value) {
        if (!empty($value)) {
            if ($key == 'member') {
                continue;
            }
            if ($key == 'main_ip') {
                $value = trim($value);
                $ip_parts = ip2range($value);
                if (!checkExistingTriggerIP($ip_parts, $value)) {
                    $ban_errors->addError('invalid_ip');
                } else {
                    $ban_triggers['main_ip'] = array('ip_low1' => $ip_parts[0]['low'], 'ip_high1' => $ip_parts[0]['high'], 'ip_low2' => $ip_parts[1]['low'], 'ip_high2' => $ip_parts[1]['high'], 'ip_low3' => $ip_parts[2]['low'], 'ip_high3' => $ip_parts[2]['high'], 'ip_low4' => $ip_parts[3]['low'], 'ip_high4' => $ip_parts[3]['high'], 'ip_low5' => $ip_parts[4]['low'], 'ip_high5' => $ip_parts[4]['high'], 'ip_low6' => $ip_parts[5]['low'], 'ip_high6' => $ip_parts[5]['high'], 'ip_low7' => $ip_parts[6]['low'], 'ip_high7' => $ip_parts[6]['high'], 'ip_low8' => $ip_parts[7]['low'], 'ip_high8' => $ip_parts[7]['high']);
                }
            } elseif ($key == 'hostname') {
                if (preg_match('/[^\\w.\\-*]/', $value) == 1) {
                    $ban_errors->addError('invalid_hostname');
                } else {
                    // Replace the * wildcard by a MySQL wildcard %.
                    $value = substr(str_replace('*', '%', $value), 0, 255);
                    $ban_triggers['hostname']['hostname'] = $value;
                }
            } elseif ($key == 'email') {
                if (preg_match('/[^\\w.\\-\\+*@]/', $value) == 1) {
                    $ban_errors->addError('invalid_email');
                }
                // Check the user is not banning an admin.
                $request = $db->query('', '
					SELECT id_member
					FROM {db_prefix}members
					WHERE (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0)
						AND email_address LIKE {string:email}
					LIMIT 1', array('admin_group' => 1, 'email' => $value));
                if ($db->num_rows($request) != 0) {
                    $ban_errors->addError('no_ban_admin');
                }
                $db->free_result($request);
                $value = substr(strtolower(str_replace('*', '%', $value)), 0, 255);
                $ban_triggers['email']['email_address'] = $value;
            } elseif ($key == 'user') {
                $user = preg_replace('~&amp;#(\\d{4,5}|[2-9]\\d{2,4}|1[2-9]\\d);~', '&#$1;', Util::htmlspecialchars($value, ENT_QUOTES));
                $request = $db->query('', '
					SELECT id_member, (id_group = {int:admin_group} OR FIND_IN_SET({int:admin_group}, additional_groups) != 0) AS isAdmin
					FROM {db_prefix}members
					WHERE member_name = {string:username} OR real_name = {string:username}
					LIMIT 1', array('admin_group' => 1, 'username' => $user));
                if ($db->num_rows($request) == 0) {
                    $ban_errors->addError('invalid_username');
                }
                list($value, $isAdmin) = $db->fetch_row($request);
                $db->free_result($request);
                if ($isAdmin && strtolower($isAdmin) != 'f') {
                    unset($value);
                    $ban_errors->addError('no_ban_admin');
                } else {
                    $ban_triggers['user']['id_member'] = $value;
                }
            } elseif (in_array($key, array('ips_in_messages', 'ips_in_errors'))) {
                // Special case, those two are arrays themselves
                $values = array_unique($value);
                // Don't add the main IP again.
                if (isset($triggers['main_ip'])) {
                    $values = array_diff($values, array($triggers['main_ip']));
                }
                unset($value);
                foreach ($values as $val) {
                    $val = trim($val);
                    $ip_parts = ip2range($val);
                    if (!checkExistingTriggerIP($ip_parts, $val)) {
                        $ban_errors->addError('invalid_ip');
                    } else {
                        $ban_triggers[$key][] = array('ip_low1' => $ip_parts[0]['low'], 'ip_high1' => $ip_parts[0]['high'], 'ip_low2' => $ip_parts[1]['low'], 'ip_high2' => $ip_parts[1]['high'], 'ip_low3' => $ip_parts[2]['low'], 'ip_high3' => $ip_parts[2]['high'], 'ip_low4' => $ip_parts[3]['low'], 'ip_high4' => $ip_parts[3]['high'], 'ip_low5' => $ip_parts[4]['low'], 'ip_high5' => $ip_parts[4]['high'], 'ip_low6' => $ip_parts[5]['low'], 'ip_high6' => $ip_parts[5]['high'], 'ip_low7' => $ip_parts[6]['low'], 'ip_high7' => $ip_parts[6]['high'], 'ip_low8' => $ip_parts[7]['low'], 'ip_high8' => $ip_parts[7]['high']);
                        $log_info[] = array('value' => $val, 'bantype' => 'ip_range');
                    }
                }
            } else {
                $ban_errors->addError('no_bantype_selected');
            }
            if (isset($value) && !is_array($value)) {
                $log_info[] = array('value' => $value, 'bantype' => $key);
            }
        }
    }
    return array('ban_triggers' => $ban_triggers, 'log_info' => $log_info);
}
/**
 * Gets a members ID from their userid or display name, used to
 * prune a members shouts from a box
 *
 * @param string $member
 */
function sp_shoutbox_prune_member($member)
{
    $db = database();
    $request = $db->query('', '
		SELECT id_member
		FROM {db_prefix}members
		WHERE member_name = {string:member}
			OR real_name = {string:member}
		LIMIT {int:limit}', array('member' => strtr(trim(Util::htmlspecialchars($member, ENT_QUOTES)), array('\'' => '&#039;')), 'limit' => 1));
    list($member_id) = $db->fetch_row($request);
    $db->free_result($request);
    return (int) $member_id;
}
Ejemplo n.º 10
0
 /**
  * Checks if an the answers to anti-spam questions are correct
  *
  * @return boolean
  */
 private function _verifyAnswers()
 {
     // Get the answers and see if they are all right!
     $questions = $this->_loadAntispamQuestions(array('type' => 'id_question', 'value' => $_SESSION[$this->_options['id'] . '_vv']['q']));
     $this->_incorrectQuestions = array();
     foreach ($questions as $row) {
         // Everything lowercase
         $answers = array();
         foreach ($row['answer'] as $answer) {
             $answers[] = Util::strtolower($answer);
         }
         if (!isset($_REQUEST[$this->_options['id'] . '_vv']['q'][$row['id_question']]) || trim($_REQUEST[$this->_options['id'] . '_vv']['q'][$row['id_question']]) == '' || !in_array(trim(Util::htmlspecialchars(Util::strtolower($_REQUEST[$this->_options['id'] . '_vv']['q'][$row['id_question']]))), $answers)) {
             $this->_incorrectQuestions[] = $row['id_question'];
         }
     }
     return empty($this->_incorrectQuestions);
 }
Ejemplo n.º 11
0
/**
 * Do some important security checks:
 *
 * What it does:
 * - checks the existence of critical files e.g. install.php
 * - checks for an active admin session.
 * - checks cache directory is writable.
 * - calls secureDirectory to protect attachments & cache.
 * - checks if the forum is in maintance mode.
 */
function doSecurityChecks()
{
    global $modSettings, $context, $maintenance, $user_info, $txt, $scripturl, $user_settings, $options;
    $show_warnings = false;
    if (allowedTo('admin_forum') && !$user_info['is_guest']) {
        // If agreement is enabled, at least the english version shall exists
        if ($modSettings['requireAgreement'] && !file_exists(BOARDDIR . '/agreement.txt')) {
            $context['security_controls_files']['title'] = $txt['generic_warning'];
            $context['security_controls_files']['errors']['agreement'] = $txt['agreement_missing'];
            $show_warnings = true;
        }
        // Cache directory writeable?
        if (!empty($modSettings['cache_enable']) && !is_writable(CACHEDIR)) {
            $context['security_controls_files']['title'] = $txt['generic_warning'];
            $context['security_controls_files']['errors']['cache'] = $txt['cache_writable'];
            $show_warnings = true;
        }
        // @todo add a hook here
        $securityFiles = array('install.php', 'upgrade.php', 'convert.php', 'repair_paths.php', 'repair_settings.php', 'Settings.php~', 'Settings_bak.php~');
        foreach ($securityFiles as $securityFile) {
            if (file_exists(BOARDDIR . '/' . $securityFile)) {
                $context['security_controls_files']['title'] = $txt['security_risk'];
                $context['security_controls_files']['errors'][$securityFile] = sprintf($txt['not_removed'], $securityFile);
                $show_warnings = true;
                if ($securityFile == 'Settings.php~' || $securityFile == 'Settings_bak.php~') {
                    $context['security_controls_files']['errors'][$securityFile] .= '<span class="smalltext">' . sprintf($txt['not_removed_extra'], $securityFile, substr($securityFile, 0, -1)) . '</span>';
                }
            }
        }
        // We are already checking so many files...just few more doesn't make any difference! :P
        require_once SUBSDIR . '/Attachments.subs.php';
        $path = getAttachmentPath();
        secureDirectory($path, true);
        secureDirectory(CACHEDIR);
        // Active admin session?
        if (empty($modSettings['securityDisable']) && (isset($_SESSION['admin_time']) && $_SESSION['admin_time'] + $modSettings['admin_session_lifetime'] * 60 > time())) {
            $context['warning_controls']['admin_session'] = sprintf($txt['admin_session_active'], $scripturl . '?action=admin;area=adminlogoff;redir;' . $context['session_var'] . '=' . $context['session_id']);
        }
        // Maintenance mode enabled?
        if (!empty($maintenance)) {
            $context['warning_controls']['maintenance'] = sprintf($txt['admin_maintenance_active'], $scripturl . '?action=admin;area=serversettings;' . $context['session_var'] . '=' . $context['session_id']);
        }
        // New updates
        if (defined('FORUM_VERSION')) {
            $index = 'new_in_' . str_replace(array('ElkArte ', '.'), array('', '_'), FORUM_VERSION);
            if (!empty($modSettings[$index]) && empty($options['dismissed_' . $index])) {
                $show_warnings = true;
                $context['new_version_updates'] = array('title' => $txt['new_version_updates'], 'errors' => array(replaceBasicActionUrl($txt['new_version_updates_text'])));
            }
        }
    }
    // Check for database errors.
    if (!empty($_SESSION['query_command_denied'])) {
        if ($user_info['is_admin']) {
            $context['security_controls_query']['title'] = $txt['query_command_denied'];
            $show_warnings = true;
            foreach ($_SESSION['query_command_denied'] as $command => $error) {
                $context['security_controls_query']['errors'][$command] = '<pre>' . Util::htmlspecialchars($error) . '</pre>';
            }
        } else {
            $context['security_controls_query']['title'] = $txt['query_command_denied_guests'];
            foreach ($_SESSION['query_command_denied'] as $command => $error) {
                $context['security_controls_query']['errors'][$command] = '<pre>' . sprintf($txt['query_command_denied_guests_msg'], Util::htmlspecialchars($command)) . '</pre>';
            }
        }
    }
    // Are there any members waiting for approval?
    if (allowedTo('moderate_forum') && (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 2 || !empty($modSettings['approveAccountDeletion'])) && !empty($modSettings['unapprovedMembers'])) {
        $context['warning_controls']['unapproved_members'] = sprintf($txt[$modSettings['unapprovedMembers'] == 1 ? 'approve_one_member_waiting' : 'approve_many_members_waiting'], $scripturl . '?action=admin;area=viewmembers;sa=browse;type=approve', $modSettings['unapprovedMembers']);
    }
    if (!empty($context['open_mod_reports']) && (empty($user_settings['mod_prefs']) || $user_settings['mod_prefs'][0] == 1)) {
        $context['warning_controls']['open_mod_reports'] = '<a href="' . $scripturl . '?action=moderate;area=reports">' . sprintf($txt['mod_reports_waiting'], $context['open_mod_reports']) . '</a>';
    }
    if (isset($_SESSION['ban']['cannot_post'])) {
        // An admin cannot be banned (technically he could), and if it is better he knows.
        $context['security_controls_ban']['title'] = sprintf($txt['you_are_post_banned'], $user_info['is_guest'] ? $txt['guest_title'] : $user_info['name']);
        $show_warnings = true;
        $context['security_controls_ban']['errors']['reason'] = '';
        if (!empty($_SESSION['ban']['cannot_post']['reason'])) {
            $context['security_controls_ban']['errors']['reason'] = $_SESSION['ban']['cannot_post']['reason'];
        }
        if (!empty($_SESSION['ban']['expire_time'])) {
            $context['security_controls_ban']['errors']['reason'] .= '<span class="smalltext">' . sprintf($txt['your_ban_expires'], standardTime($_SESSION['ban']['expire_time'], false)) . '</span>';
        } else {
            $context['security_controls_ban']['errors']['reason'] .= '<span class="smalltext">' . $txt['your_ban_expires_never'] . '</span>';
        }
    }
    // Finally, let's show the layer.
    if ($show_warnings || !empty($context['warning_controls'])) {
        Template_Layers::getInstance()->addAfter('admin_warning', 'body');
    }
}
Ejemplo n.º 12
0
    /**
     * Prepares the information from the moderation log for viewing.
     * Show the moderation log, or admin log...
     * Disallows the deletion of events within twenty-four hours of now.
     * Requires the admin_forum permission for admin log.
     * Accessed via ?action=moderate;area=modlog.
     *
     * @uses Modlog template, main sub-template.
     */
    public function action_log()
    {
        global $txt, $context, $scripturl;
        require_once SUBSDIR . '/Modlog.subs.php';
        // Are we looking at the moderation log or the administration log.
        $context['log_type'] = isset($_REQUEST['sa']) && $_REQUEST['sa'] == 'adminlog' ? 3 : 1;
        if ($context['log_type'] == 3) {
            isAllowedTo('admin_forum');
        }
        // These change dependant on whether we are viewing the moderation or admin log.
        if ($context['log_type'] == 3 || $_REQUEST['action'] == 'admin') {
            $context['url_start'] = '?action=admin;area=logs;sa=' . ($context['log_type'] == 3 ? 'adminlog' : 'modlog') . ';type=' . $context['log_type'];
        } else {
            $context['url_start'] = '?action=moderate;area=modlog;type=' . $context['log_type'];
        }
        $context['can_delete'] = allowedTo('admin_forum');
        loadLanguage('Modlog');
        $context['page_title'] = $context['log_type'] == 3 ? $txt['modlog_admin_log'] : $txt['modlog_view'];
        // The number of entries to show per page of log file.
        $context['displaypage'] = 30;
        // Amount of hours that must pass before allowed to delete file.
        $context['hoursdisable'] = 24;
        // Handle deletion...
        if (isset($_POST['removeall']) && $context['can_delete']) {
            checkSession();
            validateToken('mod-ml');
            deleteLogAction($context['log_type'], $context['hoursdisable']);
        } elseif (!empty($_POST['remove']) && isset($_POST['delete']) && $context['can_delete']) {
            checkSession();
            validateToken('mod-ml');
            deleteLogAction($context['log_type'], $context['hoursdisable'], $_POST['delete']);
        }
        // If we're coming from a search, get the variables.
        if (!empty($_REQUEST['params']) && empty($_REQUEST['is_search'])) {
            $search_params = base64_decode(strtr($_REQUEST['params'], array(' ' => '+')));
            $search_params = @unserialize($search_params);
        }
        // This array houses all the valid quick search types.
        $searchTypes = array('action' => array('sql' => 'lm.action', 'label' => $txt['modlog_action']), 'member' => array('sql' => 'mem.real_name', 'label' => $txt['modlog_member']), 'position' => array('sql' => 'mg.group_name', 'label' => $txt['modlog_position']), 'ip' => array('sql' => 'lm.ip', 'label' => $txt['modlog_ip']));
        // Setup the allowed search
        $context['order'] = isset($_REQUEST['sort']) && isset($searchTypes[$_REQUEST['sort']]) ? $_REQUEST['sort'] : 'member';
        if (!isset($search_params['string']) || !empty($_REQUEST['search']) && $search_params['string'] != $_REQUEST['search']) {
            $search_params_string = empty($_REQUEST['search']) ? '' : $_REQUEST['search'];
        } else {
            $search_params_string = $search_params['string'];
        }
        if (isset($_REQUEST['search_type']) || empty($search_params['type']) || !isset($searchTypes[$search_params['type']])) {
            $search_params_type = isset($_REQUEST['search_type']) && isset($searchTypes[$_REQUEST['search_type']]) ? $_REQUEST['search_type'] : $context['order'];
        } else {
            $search_params_type = $search_params['type'];
        }
        $search_params_column = $searchTypes[$search_params_type]['sql'];
        $search_params = array('string' => $search_params_string, 'type' => $search_params_type);
        // Setup the search context.
        $context['search_params'] = empty($search_params['string']) ? '' : base64_encode(serialize($search_params));
        $context['search'] = array('string' => $search_params['string'], 'type' => $search_params['type'], 'label' => $searchTypes[$search_params_type]['label']);
        // If they are searching by action, then we must do some manual intervention to search in their language!
        if ($search_params['type'] == 'action' && !empty($search_params['string'])) {
            // Build a regex which looks for the words
            $regex = '';
            $search = explode(' ', $search_params['string']);
            foreach ($search as $word) {
                $regex .= '(?=[\\w\\s]*' . $word . ')';
            }
            // For the moment they can only search for ONE action!
            foreach ($txt as $key => $text) {
                if (strpos($key, 'modlog_ac_') === 0 && preg_match('~' . $regex . '~i', $text)) {
                    $search_params['string'] = substr($key, 10);
                    break;
                }
            }
        }
        require_once SUBSDIR . '/GenericList.class.php';
        // This is all the information required for a moderation/admin log listing.
        $listOptions = array('id' => 'moderation_log_list', 'width' => '100%', 'items_per_page' => $context['displaypage'], 'no_items_label' => $txt['modlog_' . ($context['log_type'] == 3 ? 'admin_log_' : '') . 'no_entries_found'], 'base_href' => $scripturl . $context['url_start'] . (!empty($context['search_params']) ? ';params=' . $context['search_params'] : ''), 'default_sort_col' => 'time', 'get_items' => array('function' => array($this, 'getModLogEntries'), 'params' => array(!empty($search_params['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : '', array('sql_type' => $search_params_column, 'search_string' => $search_params['string']), $context['log_type'])), 'get_count' => array('function' => array($this, 'getModLogEntryCount'), 'params' => array(!empty($search_params['string']) ? ' INSTR({raw:sql_type}, {string:search_string})' : '', array('sql_type' => $search_params_column, 'search_string' => $search_params['string']), $context['log_type'])), 'columns' => array('action' => array('header' => array('value' => $txt['modlog_action'], 'class' => 'lefttext'), 'data' => array('db' => 'action_text', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.action', 'reverse' => 'lm.action DESC')), 'time' => array('header' => array('value' => $txt['modlog_date'], 'class' => 'lefttext'), 'data' => array('db' => 'time', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.log_time DESC', 'reverse' => 'lm.log_time')), 'moderator' => array('header' => array('value' => $txt['modlog_member'], 'class' => 'lefttext'), 'data' => array('db' => 'moderator_link', 'class' => 'smalltext'), 'sort' => array('default' => 'mem.real_name', 'reverse' => 'mem.real_name DESC')), 'position' => array('header' => array('value' => $txt['modlog_position'], 'class' => 'lefttext'), 'data' => array('db' => 'position', 'class' => 'smalltext'), 'sort' => array('default' => 'mg.group_name', 'reverse' => 'mg.group_name DESC')), 'ip' => array('header' => array('value' => $txt['modlog_ip'], 'class' => 'lefttext'), 'data' => array('db' => 'ip', 'class' => 'smalltext'), 'sort' => array('default' => 'lm.ip', 'reverse' => 'lm.ip DESC')), 'delete' => array('header' => array('value' => '<input type="checkbox" name="all" class="input_check" onclick="invertAll(this, this.form);" />', 'class' => 'centertext'), 'data' => array('function' => create_function('$entry', '
							return \'<input type="checkbox" class="input_check" name="delete[]" value="\' . $entry[\'id\'] . \'"\' . ($entry[\'editable\'] ? \'\' : \' disabled="disabled"\') . \' />\';
						'), 'class' => 'centertext'))), 'form' => array('href' => $scripturl . $context['url_start'], 'include_sort' => true, 'include_start' => true, 'hidden_fields' => array($context['session_var'] => $context['session_id'], 'params' => $context['search_params']), 'token' => 'mod-ml'), 'additional_rows' => array(array('class' => 'submitbutton', 'position' => 'below_table_data', 'value' => '
						<div id="quick_log_search">
							' . $txt['modlog_search'] . ' (' . $txt['modlog_by'] . ': ' . $context['search']['label'] . ')
							<input type="text" name="search" size="18" value="' . Util::htmlspecialchars($context['search']['string']) . '" class="input_text" />
							<input type="submit" name="is_search" value="' . $txt['modlog_go'] . '" class="button_submit" />
							' . ($context['can_delete'] ? '|&nbsp;
							<input type="submit" name="remove" value="' . $txt['modlog_remove'] . '" onclick="return confirm(\'' . $txt['modlog_remove_selected_confirm'] . '\');" class="right_submit" />
							<input type="submit" name="removeall" value="' . $txt['modlog_removeall'] . '" onclick="return confirm(\'' . $txt['modlog_remove_all_confirm'] . '\');" class="right_submit" />' : '') . '
						</div>')));
        createToken('mod-ml');
        // Create the log listing
        createList($listOptions);
        $context['sub_template'] = 'show_list';
        $context['default_list'] = 'moderation_log_list';
    }
/**
 * Main template for displaying the list of boards
 *
 * @param int $boards
 * @param string $id
 */
function template_list_boards($boards, $id)
{
    global $context, $settings, $txt, $scripturl, $theme_bi_alternating_row;
    echo '
			<ul class="category_boards" id="', $id, '">';
    // Each board in each category's boards has:
    // new (is it new?), id, name, description, moderators (see below), link_moderators (just a list.),
    // children (see below.), link_children (easier to use.), children_new (are they new?),
    // topics (# of), posts (# of), link, href, and last_post. (see below.)
    foreach ($boards as $board) {
        echo '
				<li class="board_row', !empty($board['children']) ? ' parent_board' : '', $board['is_redirect'] ? ' board_row_redirect' : '', $theme_bi_alternating_row ? ' alternating_row' : '', '" id="board_', $board['id'], '">
					<div class="board_info">
						<a class="icon_anchor" href="', $board['is_redirect'] || $context['user']['is_guest'] ? $board['href'] : $scripturl . '?action=unread;board=' . $board['id'] . '.0;children', '">';
        // If the board or children is new, show an indicator.
        if ($board['new'] || $board['children_new']) {
            echo '
							<span class="board_icon ', $board['new'] ? 'on_board' : 'on2_board', '" title="', $txt['new_posts'], '"></span>';
        } elseif ($board['is_redirect']) {
            echo '
							<span class="board_icon redirect_board" title="', sprintf($txt['redirect_board_to'], Util::htmlspecialchars($board['name'])), '"></span>';
        } else {
            echo '
							<span class="board_icon off_board" title="', $txt['old_posts'], '"></span>';
        }
        echo '
						</a>
						<h3 class="board_name">
							<a href="', $board['href'], '" id="b', $board['id'], '">', $board['name'], '</a>';
        // Has it outstanding posts for approval? @todo - Might change presentation here.
        if ($board['can_approve_posts'] && ($board['unapproved_posts'] || $board['unapproved_topics'])) {
            echo '
							<a href="', $scripturl, '?action=moderate;area=postmod;sa=', $board['unapproved_topics'] > 0 ? 'topics' : 'posts', ';brd=', $board['id'], ';', $context['session_var'], '=', $context['session_id'], '" title="', sprintf($txt['unapproved_posts'], $board['unapproved_topics'], $board['unapproved_posts']), '" class="moderation_link"><img class="icon" src="', $settings['images_url'], '/icons/field_invalid.png" alt="(!)" /></a>';
        }
        echo '
						</h3>
						<p class="board_description">', $board['description'], '</p>';
        // Show the "Moderators: ". Each has name, href, link, and id. (but we're gonna use link_moderators.)
        if (!empty($board['moderators'])) {
            echo '
						<p class="moderators">', count($board['moderators']) === 1 ? $txt['moderator'] : $txt['moderators'], ': ', implode(', ', $board['link_moderators']), '</p>';
        }
        // Show some basic information about the number of posts, etc.
        echo '
					</div>
					<div class="board_latest">
						<p class="board_stats">
							', comma_format($board['posts']), ' ', $board['is_redirect'] ? $txt['redirects'] : $txt['posts'], $board['is_redirect'] ? '' : '<br /> ' . comma_format($board['topics']) . ' ' . $txt['board_topics'], '
						</p>';
        // @todo - Last post message still needs some work. Probably split the language string into three chunks.
        // Example:
        // <chunk>Re: Nunc aliquam justo e...</chunk>  <chunk>by Whoever</chunk> <chunk>Last post: Today at 08:00:37 am</chunk>
        // That should still allow sufficient scope for any language, if done sensibly.
        if (!empty($board['last_post']['id'])) {
            echo '
						<p class="board_lastpost">';
            if (!empty($settings['avatars_on_indexes'])) {
                echo '
							<span class="board_avatar"><a href="', $board['last_post']['member']['href'], '"><img class="avatar" src="', $board['last_post']['member']['avatar']['href'], '" alt="" /></a></span>';
            }
            echo '
							', $board['last_post']['last_post_message'], '
						</p>';
        }
        echo '
					</div>
				</li>';
        // Show the "Sub-boards: ". (there's a link_children but we're going to bold the new ones...)
        if (!empty($board['children'])) {
            // Sort the links into an array with new boards bold so it can be imploded.
            $children = array();
            // Each child in each board's children has:
            // id, name, description, new (is it new?), topics (#), posts (#), href, link, and last_post.
            foreach ($board['children'] as $child) {
                if (!$child['is_redirect']) {
                    $child['link'] = '<a href="' . $child['href'] . '" ' . ($child['new'] ? 'class="board_new_posts" ' : '') . 'title="' . ($child['new'] ? $txt['new_posts'] : $txt['old_posts']) . ' (' . $txt['board_topics'] . ': ' . comma_format($child['topics']) . ', ' . $txt['posts'] . ': ' . comma_format($child['posts']) . ')">' . $child['name'] . ($child['new'] ? '</a> <a ' . ($child['new'] ? 'class="new_posts" ' : '') . 'href="' . $scripturl . '?action=unread;board=' . $child['id'] . '" title="' . $txt['new_posts'] . ' (' . $txt['board_topics'] . ': ' . comma_format($child['topics']) . ', ' . $txt['posts'] . ': ' . comma_format($child['posts']) . ')"><span class="new_posts">' . $txt['new'] . '</span>' : '') . '</a>';
                } else {
                    $child['link'] = '<a href="' . $child['href'] . '" title="' . comma_format($child['posts']) . ' ' . $txt['redirects'] . '">' . $child['name'] . '</a>';
                }
                // Has it posts awaiting approval?
                if ($child['can_approve_posts'] && ($child['unapproved_posts'] || $child['unapproved_topics'])) {
                    $child['link'] .= ' <a href="' . $scripturl . '?action=moderate;area=postmod;sa=' . ($child['unapproved_topics'] > 0 ? 'topics' : 'posts') . ';brd=' . $child['id'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . sprintf($txt['unapproved_posts'], $child['unapproved_topics'], $child['unapproved_posts']) . '" class="moderation_link"><img class="icon" src="' . $settings['images_url'] . '/icons/field_invalid.png" alt="(!)" /></a>';
                }
                $children[] = $child['link'];
            }
            // New <li> for sub-boards (if any). Can be styled to look like part of previous <li>.
            // Use h4 tag here for better a11y. Use <ul> for list of sub-boards.
            // Having sub-board links in <li>'s will allow "tidy sub-boards" via easy CSS tweaks. ;)
            echo '
				<li class="childboard_row', $theme_bi_alternating_row ? ' alternating_row' : '', '" id="board_', $board['id'], '_children">
					<ul class="childboards">
						<li>
							<h4>', $txt['parent_boards'], ':</h4>
						</li>
						<li>
							', implode('</li><li>', $children), '
						</li>
					</ul>
				</li>';
        }
        $theme_bi_alternating_row = $theme_bi_alternating_row ? 0 : 1;
    }
    echo '
			</ul>';
}
Ejemplo n.º 14
0
/**
 * Adds html entities to the array/variable.  Uses two underscores to guard against overloading.
 *
 * What it does:
 * - adds entities (&quot;, &lt;, &gt;) to the array or string var.
 * - importantly, does not effect keys, only values.
 * - calls itself recursively if necessary.
 *
 * @param string[]|string $var
 * @param int $level = 0
 * @return mixed[]|string
 */
function htmlspecialchars__recursive($var, $level = 0)
{
    if (!is_array($var)) {
        return Util::htmlspecialchars($var, ENT_QUOTES);
    }
    // Add the htmlspecialchars to every element.
    foreach ($var as $k => $v) {
        $var[$k] = $level > 25 ? null : htmlspecialchars__recursive($v, $level + 1);
    }
    return $var;
}
Ejemplo n.º 15
0
 /**
  * This function allocates out all the search stuff.
  */
 public function action_search()
 {
     global $txt, $context;
     // What can we search for?
     $subActions = array('internal' => array($this, 'action_search_internal', 'permission' => 'admin_forum'), 'online' => array($this, 'action_search_doc', 'permission' => 'admin_forum'), 'member' => array($this, 'action_search_member', 'permission' => 'admin_forum'));
     // Set the subaction
     $action = new Action();
     $subAction = $action->initialize($subActions, 'internal');
     // Keep track of what the admin wants in terms of advanced or not
     if (empty($context['admin_preferences']['sb']) || $context['admin_preferences']['sb'] != $subAction) {
         $context['admin_preferences']['sb'] = $subAction;
         // Update the preferences.
         require_once SUBSDIR . '/Admin.subs.php';
         updateAdminPreferences();
     }
     // Setup for the template
     $context['search_type'] = $subAction;
     $context['search_term'] = isset($_REQUEST['search_term']) ? Util::htmlspecialchars($_REQUEST['search_term'], ENT_QUOTES) : '';
     $context['sub_template'] = 'admin_search_results';
     $context['page_title'] = $txt['admin_search_results'];
     // You did remember to enter something to search for, otherwise its easy
     if (trim($context['search_term']) == '') {
         $context['search_results'] = array();
     } else {
         $action->dispatch($subAction);
     }
 }
Ejemplo n.º 16
0
/**
 * General function to split off a topic.
 * creates a new topic and moves the messages with the IDs in
 * array messagesToBeSplit to the new topic.
 * the subject of the newly created topic is set to 'newSubject'.
 * marks the newly created message as read for the user splitting it.
 * updates the statistics to reflect a newly created topic.
 * logs the action in the moderation log.
 * a notification is sent to all users monitoring this topic.
 *
 * @param int $split1_ID_TOPIC
 * @param int[] $splitMessages
 * @param string $new_subject
 * @return int the topic ID of the new split topic.
 */
function splitTopic($split1_ID_TOPIC, $splitMessages, $new_subject)
{
    global $txt;
    $db = database();
    // Nothing to split?
    if (empty($splitMessages)) {
        fatal_lang_error('no_posts_selected', false);
    }
    // Get some board info.
    $request = $db->query('', '
		SELECT id_board, approved
		FROM {db_prefix}topics
		WHERE id_topic = {int:id_topic}
		LIMIT 1', array('id_topic' => $split1_ID_TOPIC));
    list($id_board, $split1_approved) = $db->fetch_row($request);
    $db->free_result($request);
    // Find the new first and last not in the list. (old topic)
    $request = $db->query('', '
		SELECT
			MIN(m.id_msg) AS myid_first_msg, MAX(m.id_msg) AS myid_last_msg, COUNT(*) AS message_count, m.approved
		FROM {db_prefix}messages AS m
			INNER JOIN {db_prefix}topics AS t ON (t.id_topic = {int:id_topic})
		WHERE m.id_msg NOT IN ({array_int:no_msg_list})
			AND m.id_topic = {int:id_topic}
		GROUP BY m.approved
		ORDER BY m.approved DESC
		LIMIT 2', array('id_topic' => $split1_ID_TOPIC, 'no_msg_list' => $splitMessages));
    // You can't select ALL the messages!
    if ($db->num_rows($request) == 0) {
        fatal_lang_error('selected_all_posts', false);
    }
    $split1_first_msg = null;
    $split1_last_msg = null;
    while ($row = $db->fetch_assoc($request)) {
        // Get the right first and last message dependant on approved state...
        if (empty($split1_first_msg) || $row['myid_first_msg'] < $split1_first_msg) {
            $split1_first_msg = $row['myid_first_msg'];
        }
        if (empty($split1_last_msg) || $row['approved']) {
            $split1_last_msg = $row['myid_last_msg'];
        }
        // Get the counts correct...
        if ($row['approved']) {
            $split1_replies = $row['message_count'] - 1;
            $split1_unapprovedposts = 0;
        } else {
            if (!isset($split1_replies)) {
                $split1_replies = 0;
            } elseif (!$split1_approved) {
                $split1_replies++;
            }
            $split1_unapprovedposts = $row['message_count'];
        }
    }
    $db->free_result($request);
    $split1_firstMem = getMsgMemberID($split1_first_msg);
    $split1_lastMem = getMsgMemberID($split1_last_msg);
    // Find the first and last in the list. (new topic)
    $request = $db->query('', '
		SELECT MIN(id_msg) AS myid_first_msg, MAX(id_msg) AS myid_last_msg, COUNT(*) AS message_count, approved
		FROM {db_prefix}messages
		WHERE id_msg IN ({array_int:msg_list})
			AND id_topic = {int:id_topic}
		GROUP BY id_topic, approved
		ORDER BY approved DESC
		LIMIT 2', array('msg_list' => $splitMessages, 'id_topic' => $split1_ID_TOPIC));
    while ($row = $db->fetch_assoc($request)) {
        // As before get the right first and last message dependant on approved state...
        if (empty($split2_first_msg) || $row['myid_first_msg'] < $split2_first_msg) {
            $split2_first_msg = $row['myid_first_msg'];
        }
        if (empty($split2_last_msg) || $row['approved']) {
            $split2_last_msg = $row['myid_last_msg'];
        }
        // Then do the counts again...
        if ($row['approved']) {
            $split2_approved = true;
            $split2_replies = $row['message_count'] - 1;
            $split2_unapprovedposts = 0;
        } else {
            // Should this one be approved??
            if ($split2_first_msg == $row['myid_first_msg']) {
                $split2_approved = false;
            }
            if (!isset($split2_replies)) {
                $split2_replies = 0;
            } elseif (!$split2_approved) {
                $split2_replies++;
            }
            $split2_unapprovedposts = $row['message_count'];
        }
    }
    $db->free_result($request);
    $split2_firstMem = getMsgMemberID($split2_first_msg);
    $split2_lastMem = getMsgMemberID($split2_last_msg);
    // No database changes yet, so let's double check to see if everything makes at least a little sense.
    if ($split1_first_msg <= 0 || $split1_last_msg <= 0 || $split2_first_msg <= 0 || $split2_last_msg <= 0 || $split1_replies < 0 || $split2_replies < 0 || $split1_unapprovedposts < 0 || $split2_unapprovedposts < 0 || !isset($split1_approved) || !isset($split2_approved)) {
        fatal_lang_error('cant_find_messages');
    }
    // You cannot split off the first message of a topic.
    if ($split1_first_msg > $split2_first_msg) {
        fatal_lang_error('split_first_post', false);
    }
    // We're off to insert the new topic!  Use 0 for now to avoid UNIQUE errors.
    $db->insert('', '{db_prefix}topics', array('id_board' => 'int', 'id_member_started' => 'int', 'id_member_updated' => 'int', 'id_first_msg' => 'int', 'id_last_msg' => 'int', 'num_replies' => 'int', 'unapproved_posts' => 'int', 'approved' => 'int', 'is_sticky' => 'int'), array((int) $id_board, $split2_firstMem, $split2_lastMem, 0, 0, $split2_replies, $split2_unapprovedposts, (int) $split2_approved, 0), array('id_topic'));
    $split2_ID_TOPIC = $db->insert_id('{db_prefix}topics', 'id_topic');
    if ($split2_ID_TOPIC <= 0) {
        fatal_lang_error('cant_insert_topic');
    }
    // Move the messages over to the other topic.
    $new_subject = strtr(Util::htmltrim(Util::htmlspecialchars($new_subject)), array("\r" => '', "\n" => '', "\t" => ''));
    // Check the subject length.
    if (Util::strlen($new_subject) > 100) {
        $new_subject = Util::substr($new_subject, 0, 100);
    }
    // Valid subject?
    if ($new_subject != '') {
        $db->query('', '
			UPDATE {db_prefix}messages
			SET
				id_topic = {int:id_topic},
				subject = CASE WHEN id_msg = {int:split_first_msg} THEN {string:new_subject} ELSE {string:new_subject_replies} END
			WHERE id_msg IN ({array_int:split_msgs})', array('split_msgs' => $splitMessages, 'id_topic' => $split2_ID_TOPIC, 'new_subject' => $new_subject, 'split_first_msg' => $split2_first_msg, 'new_subject_replies' => $txt['response_prefix'] . $new_subject));
        // Cache the new topics subject... we can do it now as all the subjects are the same!
        updateStats('subject', $split2_ID_TOPIC, $new_subject);
    }
    // Any associated reported posts better follow...
    require_once SUBSDIR . '/Topic.subs.php';
    updateSplitTopics(array('splitMessages' => $splitMessages, 'split2_ID_TOPIC' => $split2_ID_TOPIC, 'split1_replies' => $split1_replies, 'split1_first_msg' => $split1_first_msg, 'split1_last_msg' => $split1_last_msg, 'split1_firstMem' => $split1_firstMem, 'split1_lastMem' => $split1_lastMem, 'split1_unapprovedposts' => $split1_unapprovedposts, 'split1_ID_TOPIC' => $split1_ID_TOPIC, 'split2_first_msg' => $split2_first_msg, 'split2_last_msg' => $split2_last_msg, 'split2_ID_TOPIC' => $split2_ID_TOPIC, 'split2_approved' => $split2_approved), $id_board);
    require_once SUBSDIR . '/FollowUps.subs.php';
    // Let's see if we can create a stronger bridge between the two topics
    // @todo not sure what message from the oldest topic I should link to the new one, so I'll go with the first
    linkMessages($split1_first_msg, $split2_ID_TOPIC);
    // Copy log topic entries.
    // @todo This should really be chunked.
    $request = $db->query('', '
		SELECT id_member, id_msg, unwatched
		FROM {db_prefix}log_topics
		WHERE id_topic = {int:id_topic}', array('id_topic' => (int) $split1_ID_TOPIC));
    if ($db->num_rows($request) > 0) {
        $replaceEntries = array();
        while ($row = $db->fetch_assoc($request)) {
            $replaceEntries[] = array($row['id_member'], $split2_ID_TOPIC, $row['id_msg'], $row['unwatched']);
        }
        require_once SUBSDIR . '/Topic.subs.php';
        markTopicsRead($replaceEntries, false);
        unset($replaceEntries);
    }
    $db->free_result($request);
    // Housekeeping.
    updateTopicStats();
    updateLastMessages($id_board);
    logAction('split', array('topic' => $split1_ID_TOPIC, 'new_topic' => $split2_ID_TOPIC, 'board' => $id_board));
    // Notify people that this topic has been split?
    require_once SUBSDIR . '/Notification.subs.php';
    sendNotifications($split1_ID_TOPIC, 'split');
    // If there's a search index that needs updating, update it...
    require_once SUBSDIR . '/Search.subs.php';
    $searchAPI = findSearchAPI();
    if (is_callable(array($searchAPI, 'topicSplit'))) {
        $searchAPI->topicSplit($split2_ID_TOPIC, $splitMessages);
    }
    // Return the ID of the newly created topic.
    return $split2_ID_TOPIC;
}
/**
 * Sends a personal message from the specified person to the specified people
 * ($from defaults to the user)
 *
 * @package PersonalMessage
 * @param mixed[] $recipients - an array containing the arrays 'to' and 'bcc', both containing id_member's.
 * @param string $subject - should have no slashes and no html entities
 * @param string $message - should have no slashes and no html entities
 * @param bool $store_outbox
 * @param mixed[]|null $from - an array with the id, name, and username of the member.
 * @param int $pm_head - the ID of the chain being replied to - if any.
 * @return mixed[] an array with log entries telling how many recipients were successful and which recipients it failed to send to.
 */
function sendpm($recipients, $subject, $message, $store_outbox = true, $from = null, $pm_head = 0)
{
    global $scripturl, $txt, $user_info, $language, $modSettings, $webmaster_email;
    $db = database();
    // Make sure the PM language file is loaded, we might need something out of it.
    loadLanguage('PersonalMessage');
    // Needed for our email and post functions
    require_once SUBSDIR . '/Mail.subs.php';
    require_once SUBSDIR . '/Post.subs.php';
    // Initialize log array.
    $log = array('failed' => array(), 'sent' => array());
    if ($from === null) {
        $from = array('id' => $user_info['id'], 'name' => $user_info['name'], 'username' => $user_info['username']);
    } else {
        $user_info['name'] = $from['name'];
    }
    // This is the one that will go in their inbox.
    $htmlmessage = Util::htmlspecialchars($message, ENT_QUOTES, 'UTF-8', true);
    preparsecode($htmlmessage);
    $htmlsubject = strtr(Util::htmlspecialchars($subject), array("\r" => '', "\n" => '', "\t" => ''));
    if (Util::strlen($htmlsubject) > 100) {
        $htmlsubject = Util::substr($htmlsubject, 0, 100);
    }
    // Make sure is an array
    if (!is_array($recipients)) {
        $recipients = array($recipients);
    }
    // Integrated PMs
    call_integration_hook('integrate_personal_message', array(&$recipients, &$from, &$subject, &$message));
    // Get a list of usernames and convert them to IDs.
    $usernames = array();
    foreach ($recipients as $rec_type => $rec) {
        foreach ($rec as $id => $member) {
            if (!is_numeric($recipients[$rec_type][$id])) {
                $recipients[$rec_type][$id] = Util::strtolower(trim(preg_replace('/[<>&"\'=\\\\]/', '', $recipients[$rec_type][$id])));
                $usernames[$recipients[$rec_type][$id]] = 0;
            }
        }
    }
    if (!empty($usernames)) {
        $request = $db->query('pm_find_username', '
			SELECT
				id_member, member_name
			FROM {db_prefix}members
			WHERE ' . (defined('DB_CASE_SENSITIVE') ? 'LOWER(member_name)' : 'member_name') . ' IN ({array_string:usernames})', array('usernames' => array_keys($usernames)));
        while ($row = $db->fetch_assoc($request)) {
            if (isset($usernames[Util::strtolower($row['member_name'])])) {
                $usernames[Util::strtolower($row['member_name'])] = $row['id_member'];
            }
        }
        $db->free_result($request);
        // Replace the usernames with IDs. Drop usernames that couldn't be found.
        foreach ($recipients as $rec_type => $rec) {
            foreach ($rec as $id => $member) {
                if (is_numeric($recipients[$rec_type][$id])) {
                    continue;
                }
                if (!empty($usernames[$member])) {
                    $recipients[$rec_type][$id] = $usernames[$member];
                } else {
                    $log['failed'][$id] = sprintf($txt['pm_error_user_not_found'], $recipients[$rec_type][$id]);
                    unset($recipients[$rec_type][$id]);
                }
            }
        }
    }
    // Make sure there are no duplicate 'to' members.
    $recipients['to'] = array_unique($recipients['to']);
    // Only 'bcc' members that aren't already in 'to'.
    $recipients['bcc'] = array_diff(array_unique($recipients['bcc']), $recipients['to']);
    // Combine 'to' and 'bcc' recipients.
    $all_to = array_merge($recipients['to'], $recipients['bcc']);
    // Check no-one will want it deleted right away!
    $request = $db->query('', '
		SELECT
			id_member, criteria, is_or
		FROM {db_prefix}pm_rules
		WHERE id_member IN ({array_int:to_members})
			AND delete_pm = {int:delete_pm}', array('to_members' => $all_to, 'delete_pm' => 1));
    $deletes = array();
    // Check whether we have to apply anything...
    while ($row = $db->fetch_assoc($request)) {
        $criteria = unserialize($row['criteria']);
        // Note we don't check the buddy status, cause deletion from buddy = madness!
        $delete = false;
        foreach ($criteria as $criterium) {
            if ($criterium['t'] == 'mid' && $criterium['v'] == $from['id'] || $criterium['t'] == 'gid' && in_array($criterium['v'], $user_info['groups']) || $criterium['t'] == 'sub' && strpos($subject, $criterium['v']) !== false || $criterium['t'] == 'msg' && strpos($message, $criterium['v']) !== false) {
                $delete = true;
            } elseif (!$row['is_or']) {
                $delete = false;
                break;
            }
        }
        if ($delete) {
            $deletes[$row['id_member']] = 1;
        }
    }
    $db->free_result($request);
    // Load the membergrounp message limits.
    static $message_limit_cache = array();
    if (!allowedTo('moderate_forum') && empty($message_limit_cache)) {
        $request = $db->query('', '
			SELECT
				id_group, max_messages
			FROM {db_prefix}membergroups', array());
        while ($row = $db->fetch_assoc($request)) {
            $message_limit_cache[$row['id_group']] = $row['max_messages'];
        }
        $db->free_result($request);
    }
    // Load the groups that are allowed to read PMs.
    // @todo move into a separate function on $permission.
    $allowed_groups = array();
    $disallowed_groups = array();
    $request = $db->query('', '
		SELECT
			id_group, add_deny
		FROM {db_prefix}permissions
		WHERE permission = {string:read_permission}', array('read_permission' => 'pm_read'));
    while ($row = $db->fetch_assoc($request)) {
        if (empty($row['add_deny'])) {
            $disallowed_groups[] = $row['id_group'];
        } else {
            $allowed_groups[] = $row['id_group'];
        }
    }
    $db->free_result($request);
    if (empty($modSettings['permission_enable_deny'])) {
        $disallowed_groups = array();
    }
    $request = $db->query('', '
		SELECT
			member_name, real_name, id_member, email_address, lngfile,
			pm_email_notify, personal_messages,' . (allowedTo('moderate_forum') ? ' 0' : '
			(receive_from = {int:admins_only}' . (empty($modSettings['enable_buddylist']) ? '' : ' OR
			(receive_from = {int:buddies_only} AND FIND_IN_SET({string:from_id}, buddy_list) = 0) OR
			(receive_from = {int:not_on_ignore_list} AND FIND_IN_SET({string:from_id}, pm_ignore_list) != 0)') . ')') . ' AS ignored,
			FIND_IN_SET({string:from_id}, buddy_list) != 0 AS is_buddy, is_activated,
			additional_groups, id_group, id_post_group
		FROM {db_prefix}members
		WHERE id_member IN ({array_int:recipients})
		ORDER BY lngfile
		LIMIT {int:count_recipients}', array('not_on_ignore_list' => 1, 'buddies_only' => 2, 'admins_only' => 3, 'recipients' => $all_to, 'count_recipients' => count($all_to), 'from_id' => $from['id']));
    $notifications = array();
    while ($row = $db->fetch_assoc($request)) {
        // Don't do anything for members to be deleted!
        if (isset($deletes[$row['id_member']])) {
            continue;
        }
        // We need to know this members groups.
        $groups = explode(',', $row['additional_groups']);
        $groups[] = $row['id_group'];
        $groups[] = $row['id_post_group'];
        $message_limit = -1;
        // For each group see whether they've gone over their limit - assuming they're not an admin.
        if (!in_array(1, $groups)) {
            foreach ($groups as $id) {
                if (isset($message_limit_cache[$id]) && $message_limit != 0 && $message_limit < $message_limit_cache[$id]) {
                    $message_limit = $message_limit_cache[$id];
                }
            }
            if ($message_limit > 0 && $message_limit <= $row['personal_messages']) {
                $log['failed'][$row['id_member']] = sprintf($txt['pm_error_data_limit_reached'], $row['real_name']);
                unset($all_to[array_search($row['id_member'], $all_to)]);
                continue;
            }
            // Do they have any of the allowed groups?
            if (count(array_intersect($allowed_groups, $groups)) == 0 || count(array_intersect($disallowed_groups, $groups)) != 0) {
                $log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
                unset($all_to[array_search($row['id_member'], $all_to)]);
                continue;
            }
        }
        // Note that PostgreSQL can return a lowercase t/f for FIND_IN_SET
        if (!empty($row['ignored']) && $row['ignored'] != 'f' && $row['id_member'] != $from['id']) {
            $log['failed'][$row['id_member']] = sprintf($txt['pm_error_ignored_by_user'], $row['real_name']);
            unset($all_to[array_search($row['id_member'], $all_to)]);
            continue;
        }
        // If the receiving account is banned (>=10) or pending deletion (4), refuse to send the PM.
        if ($row['is_activated'] >= 10 || $row['is_activated'] == 4 && !$user_info['is_admin']) {
            $log['failed'][$row['id_member']] = sprintf($txt['pm_error_user_cannot_read'], $row['real_name']);
            unset($all_to[array_search($row['id_member'], $all_to)]);
            continue;
        }
        // Send a notification, if enabled - taking the buddy list into account.
        if (!empty($row['email_address']) && ($row['pm_email_notify'] == 1 || $row['pm_email_notify'] > 1 && (!empty($modSettings['enable_buddylist']) && $row['is_buddy'])) && $row['is_activated'] == 1) {
            $notifications[empty($row['lngfile']) || empty($modSettings['userLanguage']) ? $language : $row['lngfile']][] = $row['email_address'];
        }
        $log['sent'][$row['id_member']] = sprintf(isset($txt['pm_successfully_sent']) ? $txt['pm_successfully_sent'] : '', $row['real_name']);
    }
    $db->free_result($request);
    // Only 'send' the message if there are any recipients left.
    if (empty($all_to)) {
        return $log;
    }
    // Track the pm count for our stats
    if (!empty($modSettings['trackStats'])) {
        trackStats(array('pm' => '+'));
    }
    // Insert the message itself and then grab the last insert id.
    $db->insert('', '{db_prefix}personal_messages', array('id_pm_head' => 'int', 'id_member_from' => 'int', 'deleted_by_sender' => 'int', 'from_name' => 'string-255', 'msgtime' => 'int', 'subject' => 'string-255', 'body' => 'string-65534'), array($pm_head, $from['id'], $store_outbox ? 0 : 1, $from['username'], time(), $htmlsubject, $htmlmessage), array('id_pm'));
    $id_pm = $db->insert_id('{db_prefix}personal_messages', 'id_pm');
    // Add the recipients.
    if (!empty($id_pm)) {
        // If this is new we need to set it part of it's own conversation.
        if (empty($pm_head)) {
            $db->query('', '
				UPDATE {db_prefix}personal_messages
				SET id_pm_head = {int:id_pm_head}
				WHERE id_pm = {int:id_pm_head}', array('id_pm_head' => $id_pm));
        }
        // Some people think manually deleting personal_messages is fun... it's not. We protect against it though :)
        $db->query('', '
			DELETE FROM {db_prefix}pm_recipients
			WHERE id_pm = {int:id_pm}', array('id_pm' => $id_pm));
        $insertRows = array();
        $to_list = array();
        foreach ($all_to as $to) {
            $insertRows[] = array($id_pm, $to, in_array($to, $recipients['bcc']) ? 1 : 0, isset($deletes[$to]) ? 1 : 0, 1);
            if (!in_array($to, $recipients['bcc'])) {
                $to_list[] = $to;
            }
        }
        $db->insert('insert', '{db_prefix}pm_recipients', array('id_pm' => 'int', 'id_member' => 'int', 'bcc' => 'int', 'deleted' => 'int', 'is_new' => 'int'), $insertRows, array('id_pm', 'id_member'));
    }
    $maillist = !empty($modSettings['maillist_enabled']) && !empty($modSettings['pbe_pm_enabled']);
    // If they have post by email enabled, override disallow_sendBody
    if (!$maillist && !empty($modSettings['disallow_sendBody'])) {
        $message = '';
        censorText($subject);
    } else {
        require_once SUBSDIR . '/Emailpost.subs.php';
        pbe_prepare_text($message, $subject);
    }
    $to_names = array();
    if (count($to_list) > 1) {
        require_once SUBSDIR . '/Members.subs.php';
        $result = getBasicMemberData($to_list);
        foreach ($result as $row) {
            $to_names[] = un_htmlspecialchars($row['real_name']);
        }
    }
    $replacements = array('SUBJECT' => $subject, 'MESSAGE' => $message, 'SENDER' => un_htmlspecialchars($from['name']), 'READLINK' => $scripturl . '?action=pm;pmsg=' . $id_pm . '#msg' . $id_pm, 'REPLYLINK' => $scripturl . '?action=pm;sa=send;f=inbox;pmsg=' . $id_pm . ';quote;u=' . $from['id'], 'TOLIST' => implode(', ', $to_names));
    // Select the right template
    $email_template = ($maillist && empty($modSettings['disallow_sendBody']) ? 'pbe_' : '') . 'new_pm' . (empty($modSettings['disallow_sendBody']) ? '_body' : '') . (!empty($to_names) ? '_tolist' : '');
    foreach ($notifications as $lang => $notification_list) {
        // Using maillist functionality
        if ($maillist) {
            $sender_details = query_sender_wrapper($from['id']);
            $from_wrapper = !empty($modSettings['maillist_mail_from']) ? $modSettings['maillist_mail_from'] : (empty($modSettings['maillist_sitename_address']) ? $webmaster_email : $modSettings['maillist_sitename_address']);
            // Add in the signature
            $replacements['SIGNATURE'] = $sender_details['signature'];
            // And off it goes, looking a bit more personal
            $mail = loadEmailTemplate($email_template, $replacements, $lang);
            $reference = !empty($pm_head) ? $pm_head : null;
            sendmail($notification_list, $mail['subject'], $mail['body'], $from['name'], 'p' . $id_pm, false, 2, null, true, $from_wrapper, $reference);
        } else {
            // Off the notification email goes!
            $mail = loadEmailTemplate($email_template, $replacements, $lang);
            sendmail($notification_list, $mail['subject'], $mail['body'], null, 'p' . $id_pm, false, 2, null, true);
        }
    }
    // Integrated After PMs
    call_integration_hook('integrate_personal_message_after', array(&$id_pm, &$log, &$recipients, &$from, &$subject, &$message));
    // Back to what we were on before!
    loadLanguage('index+PersonalMessage');
    // Add one to their unread and read message counts.
    foreach ($all_to as $k => $id) {
        if (isset($deletes[$id])) {
            unset($all_to[$k]);
        }
    }
    if (!empty($all_to)) {
        updateMemberData($all_to, array('personal_messages' => '+', 'unread_messages' => '+', 'new_pm' => 1));
    }
    return $log;
}
Ejemplo n.º 18
0
 /**
  * Used to preview custom email bounce templates before they are saved for use
  */
 public function action_bounce_preview()
 {
     global $context, $txt, $scripturl, $mbname, $modSettings;
     require_once SUBSDIR . '/Post.subs.php';
     loadLanguage('Errors');
     loadLanguage('ModerationCenter');
     $context['post_error']['errors'] = array();
     // If you can't approve emails, what are you doing here?
     if (allowedTo('approve_emails')) {
         $body = !empty($_POST['body']) ? trim(censorText($_POST['body'])) : '';
         $context['preview_subject'] = !empty($_POST['title']) ? trim(Util::htmlspecialchars($_POST['title'])) : '';
         if (isset($_POST['issuing'])) {
             if (empty($_POST['title']) || empty($_POST['body'])) {
                 $context['post_error']['errors'][] = $txt['warning_notify_blank'];
             }
         } else {
             if (empty($_POST['title'])) {
                 $context['post_error']['errors'][] = $txt['mc_warning_template_error_no_title'];
             }
             if (empty($_POST['body'])) {
                 $context['post_error']['errors'][] = $txt['mc_warning_template_error_no_body'];
             }
             // Add in few replacements.
             /**
              * These are the defaults:
              * - {FORUMNAME} - Forum Name, the full name with all the bells
              * - {FORUMNAMESHORT} - Short and simple name
              * - {SCRIPTURL} - Web address of forum.
              * - {ERROR} - The error that was generated by the post, its unique to the post so can't render it here
              * - {SUBJECT} - The subject of the email thats being discussed, unique to the post so can't render it here
              * - {REGARDS} - Standard email sign-off.
              * - {EMAILREGARDS} - Maybe a bit more friendly sign-off.
              */
             $find = array('{FORUMNAME}', '{FORUMNAMESHORT}', '{SCRIPTURL}', '{REGARDS}', '{EMAILREGARDS}');
             $replace = array($mbname, !empty($modSettings['maillist_sitename']) ? $modSettings['maillist_sitename'] : $mbname, $scripturl, replaceBasicActionUrl($txt['regards_team']), !empty($modSettings['maillist_sitename_regards']) ? $modSettings['maillist_sitename_regards'] : '');
             $body = str_replace($find, $replace, $body);
         }
         // Deal with any BBC so it looks good for the preview
         if (!empty($_POST['body'])) {
             preparsecode($body);
             $body = parse_bbc($body, true);
         }
         $context['preview_message'] = $body;
     }
     $context['sub_template'] = 'generic_preview';
 }
Ejemplo n.º 19
0
 /**
  * Edit a 'it bounced' template.
  *
  * @uses bounce_template sub template
  */
 public function action_modify_bounce_templates()
 {
     global $context, $txt, $user_info;
     require_once SUBSDIR . '/Moderation.subs.php';
     $context['id_template'] = isset($_REQUEST['tid']) ? (int) $_REQUEST['tid'] : 0;
     $context['is_edit'] = (bool) $context['id_template'];
     // Standard template things, you know the drill
     $context['page_title'] = $context['is_edit'] ? $txt['ml_bounce_template_modify'] : $txt['ml_bounce_template_add'];
     $context['sub_template'] = 'bounce_template';
     $context[$context['admin_menu_name']]['current_subsection'] = 'templates';
     // Defaults to show
     $context['template_data'] = array('title' => '', 'body' => $txt['ml_bounce_template_body_default'], 'subject' => $txt['ml_bounce_template_subject_default'], 'personal' => false, 'can_edit_personal' => true);
     // If it's an edit load it.
     if ($context['is_edit']) {
         modLoadTemplate($context['id_template'], 'bnctpl');
     }
     // Wait, we are saving?
     if (isset($_POST['save'])) {
         checkSession('post');
         validateToken('mod-mlt');
         // To check the BBC is good...
         require_once SUBSDIR . '/Post.subs.php';
         // Bit of cleaning!
         $template_body = trim($_POST['template_body']);
         $template_title = trim($_POST['template_title']);
         // Need something in both boxes.
         if (!empty($template_body) && !empty($template_title)) {
             // Safety first.
             $template_title = Util::htmlspecialchars($template_title);
             // Clean up BBC.
             preparsecode($template_body);
             // But put line breaks back!
             $template_body = strtr($template_body, array('<br />' => "\n"));
             // Is this personal?
             $recipient_id = !empty($_POST['make_personal']) ? $user_info['id'] : 0;
             // Updating or adding ?
             if ($context['is_edit']) {
                 // Simple update...
                 modAddUpdateTemplate($recipient_id, $template_title, $template_body, $context['id_template'], true, 'bnctpl');
                 // If it wasn't visible and now is they've effectively added it.
                 if ($context['template_data']['personal'] && !$recipient_id) {
                     logAction('add_bounce_template', array('template' => $template_title));
                 } elseif (!$context['template_data']['personal'] && $recipient_id) {
                     logAction('delete_bounce_template', array('template' => $template_title));
                 } else {
                     logAction('modify_bounce_template', array('template' => $template_title));
                 }
             } else {
                 modAddUpdateTemplate($recipient_id, $template_title, $template_body, $context['id_template'], false, 'bnctpl');
                 logAction('add_bounce_template', array('template' => $template_title));
             }
             // Get out of town...
             redirectexit('action=admin;area=maillist;sa=emailtemplates');
         } else {
             $context['warning_errors'] = array();
             $context['template_data']['title'] = !empty($template_title) ? $template_title : '';
             $context['template_data']['body'] = !empty($template_body) ? $template_body : $txt['ml_bounce_template_body_default'];
             $context['template_data']['personal'] = !empty($recipient_id);
             if (empty($template_title)) {
                 $context['warning_errors'][] = $txt['ml_bounce_template_error_no_title'];
             }
             if (empty($template_body)) {
                 $context['warning_errors'][] = $txt['ml_bounce_template_error_no_body'];
             }
         }
     }
     createToken('mod-mlt');
 }
Ejemplo n.º 20
0
 /**
  * Edit some profile fields?
  *
  * - Accessed with ?action=admin;area=featuresettings;sa=profileedit
  *
  * @uses sub template edit_profile_field
  */
 public function action_profileedit()
 {
     global $txt, $scripturl, $context;
     require_once SUBSDIR . '/ManageFeatures.subs.php';
     loadTemplate('ManageFeatures');
     // Sort out the context!
     $context['fid'] = isset($_GET['fid']) ? (int) $_GET['fid'] : 0;
     $context[$context['admin_menu_name']]['current_subsection'] = 'profile';
     $context['page_title'] = $context['fid'] ? $txt['custom_edit_title'] : $txt['custom_add_title'];
     $context['sub_template'] = 'edit_profile_field';
     // any errors messages to show?
     if (isset($_GET['msg'])) {
         loadLanguage('Errors');
         if (isset($txt['custom_option_' . $_GET['msg']])) {
             $context['custom_option__error'] = $txt['custom_option_' . $_GET['msg']];
         }
     }
     // Load the profile language for section names.
     loadLanguage('Profile');
     // Load up the profile field, if one was supplied
     if ($context['fid']) {
         $context['field'] = getProfileField($context['fid']);
     }
     // Setup the default values as needed.
     if (empty($context['field'])) {
         $context['field'] = array('name' => '', 'colname' => '???', 'desc' => '', 'profile_area' => 'forumprofile', 'reg' => false, 'display' => false, 'memberlist' => false, 'type' => 'text', 'max_length' => 255, 'rows' => 4, 'cols' => 30, 'bbc' => false, 'default_check' => false, 'default_select' => '', 'options' => array('', '', ''), 'active' => true, 'private' => false, 'can_search' => false, 'mask' => 'nohtml', 'regex' => '', 'enclose' => '', 'placement' => 0);
     }
     // All the javascript for this page... everything else is in admin.js
     addJavascriptVar(array('startOptID' => count($context['field']['options'])));
     addInlineJavascript('updateInputBoxes();', true);
     // Are we toggling which ones are active?
     if (isset($_POST['onoff'])) {
         checkSession();
         validateToken('admin-scp');
         // Enable and disable custom fields as required.
         $enabled = array(0);
         foreach ($_POST['cust'] as $id) {
             $enabled[] = (int) $id;
         }
         updateRenamedProfileStatus($enabled);
     } elseif (isset($_POST['save'])) {
         checkSession();
         validateToken('admin-ecp');
         // Everyone needs a name - even the (bracket) unknown...
         if (trim($_POST['field_name']) == '') {
             redirectexit($scripturl . '?action=admin;area=featuresettings;sa=profileedit;fid=' . $_GET['fid'] . ';msg=need_name');
         }
         // Regex you say?  Do a very basic test to see if the pattern is valid
         if (!empty($_POST['regex']) && @preg_match($_POST['regex'], 'dummy') === false) {
             redirectexit($scripturl . '?action=admin;area=featuresettings;sa=profileedit;fid=' . $_GET['fid'] . ';msg=regex_error');
         }
         $_POST['field_name'] = Util::htmlspecialchars($_POST['field_name']);
         $_POST['field_desc'] = Util::htmlspecialchars($_POST['field_desc']);
         // Checkboxes...
         $show_reg = isset($_POST['reg']) ? (int) $_POST['reg'] : 0;
         $show_display = isset($_POST['display']) ? 1 : 0;
         $show_memberlist = isset($_POST['memberlist']) ? 1 : 0;
         $bbc = isset($_POST['bbc']) ? 1 : 0;
         $show_profile = $_POST['profile_area'];
         $active = isset($_POST['active']) ? 1 : 0;
         $private = isset($_POST['private']) ? (int) $_POST['private'] : 0;
         $can_search = isset($_POST['can_search']) ? 1 : 0;
         // Some masking stuff...
         $mask = isset($_POST['mask']) ? $_POST['mask'] : '';
         if ($mask == 'regex' && isset($_POST['regex'])) {
             $mask .= $_POST['regex'];
         }
         $field_length = isset($_POST['max_length']) ? (int) $_POST['max_length'] : 255;
         $enclose = isset($_POST['enclose']) ? $_POST['enclose'] : '';
         $placement = isset($_POST['placement']) ? (int) $_POST['placement'] : 0;
         // Select options?
         $field_options = '';
         $newOptions = array();
         $default = isset($_POST['default_check']) && $_POST['field_type'] == 'check' ? 1 : '';
         if (!empty($_POST['select_option']) && ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio')) {
             foreach ($_POST['select_option'] as $k => $v) {
                 // Clean, clean, clean...
                 $v = Util::htmlspecialchars($v);
                 $v = strtr($v, array(',' => ''));
                 // Nada, zip, etc...
                 if (trim($v) == '') {
                     continue;
                 }
                 // Otherwise, save it boy.
                 $field_options .= $v . ',';
                 // This is just for working out what happened with old options...
                 $newOptions[$k] = $v;
                 // Is it default?
                 if (isset($_POST['default_select']) && $_POST['default_select'] == $k) {
                     $default = $v;
                 }
             }
             if (isset($_POST['default_select']) && $_POST['default_select'] == 'no_default') {
                 $default = 'no_default';
             }
             $field_options = substr($field_options, 0, -1);
         }
         // Text area by default has dimensions
         if ($_POST['field_type'] == 'textarea') {
             $default = (int) $_POST['rows'] . ',' . (int) $_POST['cols'];
         }
         // Come up with the unique name?
         if (empty($context['fid'])) {
             $colname = Util::substr(strtr($_POST['field_name'], array(' ' => '')), 0, 6);
             preg_match('~([\\w\\d_-]+)~', $colname, $matches);
             // If there is nothing to the name, then let's start our own - for foreign languages etc.
             if (isset($matches[1])) {
                 $colname = $initial_colname = 'cust_' . strtolower($matches[1]);
             } else {
                 $colname = $initial_colname = 'cust_' . mt_rand(1, 999999);
             }
             $unique = ensureUniqueProfileField($colname, $initial_colname);
             // Still not a unique colum name? Leave it up to the user, then.
             if (!$unique) {
                 fatal_lang_error('custom_option_not_unique');
             }
         } else {
             // Anything going to check or select is pointless keeping - as is anything coming from check!
             if ($_POST['field_type'] == 'check' && $context['field']['type'] != 'check' || ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') && $context['field']['type'] != 'select' && $context['field']['type'] != 'radio' || $context['field']['type'] == 'check' && $_POST['field_type'] != 'check') {
                 deleteProfileFieldUserData($context['field']['colname']);
             } elseif ($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') {
                 $optionChanges = array();
                 $takenKeys = array();
                 // Work out what's changed!
                 foreach ($context['field']['options'] as $k => $option) {
                     if (trim($option) == '') {
                         continue;
                     }
                     // Still exists?
                     if (in_array($option, $newOptions)) {
                         $takenKeys[] = $k;
                         continue;
                     }
                 }
                 // Finally - have we renamed it - or is it really gone?
                 foreach ($optionChanges as $k => $option) {
                     // Just been renamed?
                     if (!in_array($k, $takenKeys) && !empty($newOptions[$k])) {
                         updateRenamedProfileField($k, $newOptions, $context['field']['colname'], $option);
                     }
                 }
             }
             // @todo Maybe we should adjust based on new text length limits?
         }
         // Updating an existing field?
         if ($context['fid']) {
             $field_data = array('field_length' => $field_length, 'show_reg' => $show_reg, 'show_display' => $show_display, 'show_memberlist' => $show_memberlist, 'private' => $private, 'active' => $active, 'can_search' => $can_search, 'bbc' => $bbc, 'current_field' => $context['fid'], 'field_name' => $_POST['field_name'], 'field_desc' => $_POST['field_desc'], 'field_type' => $_POST['field_type'], 'field_options' => $field_options, 'show_profile' => $show_profile, 'default_value' => $default, 'mask' => $mask, 'enclose' => $enclose, 'placement' => $placement);
             updateProfileField($field_data);
             // Just clean up any old selects - these are a pain!
             if (($_POST['field_type'] == 'select' || $_POST['field_type'] == 'radio') && !empty($newOptions)) {
                 deleteOldProfileFieldSelects($newOptions, $context['field']['colname']);
             }
         } else {
             $new_field = array('col_name' => $colname, 'field_name' => $_POST['field_name'], 'field_desc' => $_POST['field_desc'], 'field_type' => $_POST['field_type'], 'field_length' => $field_length, 'field_options' => $field_options, 'show_reg' => $show_reg, 'show_display' => $show_display, 'show_memberlist' => $show_memberlist, 'show_profile' => $show_profile, 'private' => $private, 'active' => $active, 'default' => $default, 'can_search' => $can_search, 'bbc' => $bbc, 'mask' => $mask, 'enclose' => $enclose, 'placement' => $placement, 'vieworder' => list_getProfileFieldSize() + 1);
             addProfileField($new_field);
         }
     } elseif (isset($_POST['delete']) && $context['field']['colname']) {
         checkSession();
         validateToken('admin-ecp');
         // Delete the old data first, then the field.
         deleteProfileFieldUserData($context['field']['colname']);
         deleteProfileField($context['fid']);
     }
     // Rebuild display cache etc.
     if (isset($_POST['delete']) || isset($_POST['save']) || isset($_POST['onoff'])) {
         checkSession();
         // Update the display cache
         updateDisplayCache();
         redirectexit('action=admin;area=featuresettings;sa=profile');
     }
     createToken('admin-ecp');
 }
 /**
  * Add or edit a portal wide permissions profile
  */
 public function action_sportal_admin_permission_profiles_edit()
 {
     global $context, $txt;
     // New or an edit?
     $context['is_new'] = empty($_REQUEST['profile_id']);
     // Saving the form
     if (!empty($_POST['submit'])) {
         // Security first
         checkSession();
         // Always clean the name
         if (!isset($_POST['name']) || Util::htmltrim(Util::htmlspecialchars($_POST['name'], ENT_QUOTES)) === '') {
             fatal_lang_error('sp_error_profile_name_empty', false);
         }
         $groups_allowed = $groups_denied = '';
         // If specific member groups were picked, build the allow/deny arrays
         if (!empty($_POST['membergroups']) && is_array($_POST['membergroups'])) {
             $groups_allowed = $groups_denied = array();
             foreach ($_POST['membergroups'] as $id => $value) {
                 if ($value == 1) {
                     $groups_allowed[] = (int) $id;
                 } elseif ($value == -1) {
                     $groups_denied[] = (int) $id;
                 }
             }
             $groups_allowed = implode(',', $groups_allowed);
             $groups_denied = implode(',', $groups_denied);
         }
         // Add the data to place in the fields
         $profile_info = array('id' => (int) $_POST['profile_id'], 'type' => 1, 'name' => Util::htmlspecialchars($_POST['name'], ENT_QUOTES), 'value' => implode('|', array($groups_allowed, $groups_denied)));
         // New we simply insert
         $profile_info['id'] = sp_add_permission_profile($profile_info, $context['is_new']);
         redirectexit('action=admin;area=portalprofiles');
     }
     // Not saving, then its time to show the permission form
     if ($context['is_new']) {
         $context['profile'] = array('id' => 0, 'name' => $txt['sp_profiles_default_name'], 'label' => $txt['sp_profiles_default_name'], 'groups_allowed' => array(), 'groups_denied' => array());
     } else {
         $_REQUEST['profile_id'] = (int) $_REQUEST['profile_id'];
         $context['profile'] = sportal_get_profiles($_REQUEST['profile_id']);
     }
     // Sub template time
     $context['profile']['groups'] = sp_load_membergroups();
     $context['page_title'] = $context['is_new'] ? $txt['sp_admin_profiles_add'] : $txt['sp_admin_profiles_edit'];
     $context['sub_template'] = 'permission_profiles_edit';
 }
    /**
     * 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'])));
        }
    }
Ejemplo n.º 23
0
 /**
  * Used when a temp FTP access is needed to package functions
  */
 public function action_options()
 {
     global $txt, $context, $modSettings;
     if (isset($_POST['save'])) {
         checkSession('post');
         updateSettings(array('package_server' => trim(Util::htmlspecialchars($_POST['pack_server'])), 'package_port' => trim(Util::htmlspecialchars($_POST['pack_port'])), 'package_username' => trim(Util::htmlspecialchars($_POST['pack_user'])), 'package_make_backups' => !empty($_POST['package_make_backups']), 'package_make_full_backups' => !empty($_POST['package_make_full_backups'])));
         redirectexit('action=admin;area=packages;sa=options');
     }
     if (preg_match('~^/home\\d*/([^/]+?)/public_html~', $_SERVER['DOCUMENT_ROOT'], $match)) {
         $default_username = $match[1];
     } else {
         $default_username = '';
     }
     $context['page_title'] = $txt['package_settings'];
     $context['sub_template'] = 'install_options';
     $context['package_ftp_server'] = isset($modSettings['package_server']) ? $modSettings['package_server'] : 'localhost';
     $context['package_ftp_port'] = isset($modSettings['package_port']) ? $modSettings['package_port'] : '21';
     $context['package_ftp_username'] = isset($modSettings['package_username']) ? $modSettings['package_username'] : $default_username;
     $context['package_make_backups'] = !empty($modSettings['package_make_backups']);
     $context['package_make_full_backups'] = !empty($modSettings['package_make_full_backups']);
 }
Ejemplo n.º 24
0
/**
 * Load a page by ID
 *
 * @param int|null $page_id
 * @param boolean $active
 * @param boolean $allowed
 * @param string $sort
 */
function sportal_get_pages($page_id = null, $active = false, $allowed = false, $sort = 'title')
{
    global $context, $scripturl;
    static $cache;
    $db = database();
    // If we already have the information, just return it
    $cache_name = implode(':', array($page_id, $active, $allowed));
    if (isset($cache[$cache_name])) {
        $return = $cache[$cache_name];
    } else {
        $query = array();
        $parameters = array('sort' => $sort);
        // Page id or Page Namespace
        if (!empty($page_id) && is_int($page_id)) {
            $query[] = 'id_page = {int:page_id}';
            $parameters['page_id'] = $page_id;
        } elseif (!empty($page_id)) {
            $query[] = 'namespace = {string:namespace}';
            $parameters['namespace'] = Util::htmlspecialchars((string) $page_id, ENT_QUOTES);
        }
        // Use permissions?
        if (!empty($allowed)) {
            $query[] = sprintf($context['SPortal']['permissions']['query'], 'permissions');
        }
        // Only active pages?
        if (!empty($active)) {
            $query[] = 'status = {int:status}';
            $parameters['status'] = 1;
        }
        // Make the page request
        $request = $db->query('', '
			SELECT
				id_page, namespace, title, body, type, permissions, views, style, status
			FROM {db_prefix}sp_pages' . (!empty($query) ? '
			WHERE ' . implode(' AND ', $query) : '') . '
			ORDER BY {raw:sort}', $parameters);
        $return = array();
        while ($row = $db->fetch_assoc($request)) {
            $return[$row['id_page']] = array('id' => $row['id_page'], 'page_id' => $row['namespace'], 'title' => $row['title'], 'href' => $scripturl . '?page=' . $row['namespace'], 'link' => '<a href="' . $scripturl . '?page=' . $row['namespace'] . '">' . $row['title'] . '</a>', 'body' => $row['body'], 'type' => $row['type'], 'permissions' => $row['permissions'], 'views' => $row['views'], 'style' => $row['style'], 'status' => $row['status']);
        }
        $db->free_result($request);
        // Save this so we don't have to do it again
        $cache[$cache_name] = $return;
    }
    return !empty($page_id) ? current($return) : $return;
}
Ejemplo n.º 25
0
 /**
  * Edit some general settings related to the search function.
  *
  * - Called by ?action=admin;area=managesearch;sa=settings.
  * - Requires the admin_forum permission.
  *
  * @uses ManageSearch template, 'modify_settings' sub-template.
  */
 public function action_searchSettings_display()
 {
     global $txt, $context, $scripturl, $modSettings;
     // Initialize the form
     $this->_initSearchSettingsForm();
     $config_vars = $this->_searchSettings->settings();
     // Perhaps the search method wants to add some settings?
     require_once SUBSDIR . '/Search.subs.php';
     $searchAPI = findSearchAPI();
     if (is_callable(array($searchAPI, 'searchSettings'))) {
         call_user_func_array($searchAPI->searchSettings, array(&$config_vars));
     }
     $context['page_title'] = $txt['search_settings_title'];
     $context['sub_template'] = 'show_settings';
     $context['search_engines'] = array();
     if (!empty($modSettings['additional_search_engines'])) {
         $context['search_engines'] = unserialize($modSettings['additional_search_engines']);
     }
     for ($count = 0; $count < 3; $count++) {
         $context['search_engines'][] = array('name' => '', 'url' => '', 'separator' => '');
     }
     // A form was submitted.
     if (isset($_REQUEST['save'])) {
         checkSession();
         call_integration_hook('integrate_save_search_settings');
         if (empty($_POST['search_results_per_page'])) {
             $_POST['search_results_per_page'] = !empty($modSettings['search_results_per_page']) ? $modSettings['search_results_per_page'] : $modSettings['defaultMaxMessages'];
         }
         $new_engines = array();
         foreach ($_POST['engine_name'] as $id => $searchengine) {
             // If no url, forget it
             if (!empty($_POST['engine_url'][$id])) {
                 $new_engines[] = array('name' => trim(Util::htmlspecialchars($searchengine, ENT_COMPAT)), 'url' => trim(Util::htmlspecialchars($_POST['engine_url'][$id], ENT_COMPAT)), 'separator' => trim(Util::htmlspecialchars(!empty($_POST['engine_separator'][$id]) ? $_POST['engine_separator'][$id] : '+', ENT_COMPAT)));
             }
         }
         updateSettings(array('additional_search_engines' => !empty($new_engines) ? serialize($new_engines) : ''));
         Settings_Form::save_db($config_vars);
         redirectexit('action=admin;area=managesearch;sa=settings;' . $context['session_var'] . '=' . $context['session_id']);
     }
     // Prep the template!
     $context['post_url'] = $scripturl . '?action=admin;area=managesearch;save;sa=settings';
     $context['settings_title'] = $txt['search_settings_title'];
     // We need this for the in-line permissions
     createToken('admin-mp');
     Settings_Form::prepare_db($config_vars);
 }
 public function action_save()
 {
     global $context, $txt;
     require_once SUBSDIR . '/Post.subs.php';
     if (empty($_POST['expire_alt'])) {
         $expire = strtotime($_POST['expire']);
     } else {
         // This is the case date-picker doesn't kick in and the format is still an unix timestamp
         if (is_numeric($_POST['expire_alt'])) {
             $expire = $_POST['expire_alt'];
         } else {
             $expire = strtotime($_POST['expire_alt']);
         }
     }
     $expire = (int) $expire;
     $id = isset($_REQUEST['idnotice']) ? (int) $_REQUEST['idnotice'] : 0;
     $body = isset($_REQUEST['body']) ? Util::htmlspecialchars($_REQUEST['body']) : '';
     $class = isset($_REQUEST['class']) ? Util::htmlspecialchars($_REQUEST['class']) : 'success';
     preparsecode($body);
     $groups = json_encode(array_map('intval', array_keys($_POST['default_groups_list'])));
     $positioning = array('element' => $this->validPositioning(isset($_REQUEST['positioning']) ? $_REQUEST['positioning'] : null), 'element_name' => isset($_REQUEST['element_name']) ? Util::htmlspecialchars($_REQUEST['element_name']) : '', 'position' => isset($_REQUEST['position']) ? (int) $_REQUEST['position'] : 0);
     require_once SUBSDIR . '/DismissibleNotices.class.php';
     $notice = new Dismissible_Notices();
     $new = $notice->save($id, $expire, $body, $class, $groups, $positioning);
     loadTemplate('Json');
     $context['sub_template'] = 'send_json';
     $context['json_data'] = array('id' => $new['id_notice'], 'added' => standardTime($new['added']), 'expire' => Dismissible_Notices_Integrate::formatExpireCol($expire), 'body' => un_htmlspecialchars($body), 'class' => $new['class'], 'groups' => $new['show_to'], 'edit' => '<a data-idnotice="' . $new['id_notice'] . '" class="dismissnotice_editable" href="#">' . $txt['modify'] . '</a>');
 }
Ejemplo n.º 27
0
 /**
  * Shows a form to edit a forum mailing and its recipients.
  *
  * What it does:
  * - Called by ?action=admin;area=news;sa=mailingcompose.
  * - Requires the send_mail permission.
  * - Form is submitted to ?action=admin;area=news;sa=mailingsend.
  *
  * @uses ManageNews template, email_members_compose sub-template.
  */
 public function action_mailingcompose()
 {
     global $txt, $context;
     // Setup the template!
     $context['page_title'] = $txt['admin_newsletters'];
     $context['sub_template'] = 'email_members_compose';
     $context['subject'] = !empty($_POST['subject']) ? $_POST['subject'] : $context['forum_name'] . ': ' . htmlspecialchars($txt['subject'], ENT_COMPAT, 'UTF-8');
     $context['message'] = !empty($_POST['message']) ? $_POST['message'] : htmlspecialchars($txt['message'] . "\n\n" . replaceBasicActionUrl($txt['regards_team']) . "\n\n" . '{$board_url}', ENT_COMPAT, 'UTF-8');
     // Needed for the WYSIWYG editor.
     require_once SUBSDIR . '/Editor.subs.php';
     // Now create the editor.
     $editorOptions = array('id' => 'message', 'value' => $context['message'], 'height' => '250px', 'width' => '100%', 'labels' => array('post_button' => $txt['sendtopic_send']), 'preview_type' => 2);
     create_control_richedit($editorOptions);
     if (isset($context['preview'])) {
         require_once SUBSDIR . '/Mail.subs.php';
         $context['recipients']['members'] = !empty($_POST['members']) ? explode(',', $_POST['members']) : array();
         $context['recipients']['exclude_members'] = !empty($_POST['exclude_members']) ? explode(',', $_POST['exclude_members']) : array();
         $context['recipients']['groups'] = !empty($_POST['groups']) ? explode(',', $_POST['groups']) : array();
         $context['recipients']['exclude_groups'] = !empty($_POST['exclude_groups']) ? explode(',', $_POST['exclude_groups']) : array();
         $context['recipients']['emails'] = !empty($_POST['emails']) ? explode(';', $_POST['emails']) : array();
         $context['email_force'] = !empty($_POST['email_force']) ? 1 : 0;
         $context['total_emails'] = !empty($_POST['total_emails']) ? (int) $_POST['total_emails'] : 0;
         $context['max_id_member'] = !empty($_POST['max_id_member']) ? (int) $_POST['max_id_member'] : 0;
         $context['send_pm'] = !empty($_POST['send_pm']) ? 1 : 0;
         $context['send_html'] = !empty($_POST['send_html']) ? '1' : '0';
         return prepareMailingForPreview();
     }
     // Start by finding any members!
     $toClean = array();
     if (!empty($_POST['members'])) {
         $toClean[] = 'members';
     }
     if (!empty($_POST['exclude_members'])) {
         $toClean[] = 'exclude_members';
     }
     if (!empty($toClean)) {
         require_once SUBSDIR . '/Auth.subs.php';
         foreach ($toClean as $type) {
             // Remove the quotes.
             $_POST[$type] = strtr((string) $_POST[$type], array('\\"' => '"'));
             preg_match_all('~"([^"]+)"~', $_POST[$type], $matches);
             $_POST[$type] = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_POST[$type]))));
             foreach ($_POST[$type] as $index => $member) {
                 if (strlen(trim($member)) > 0) {
                     $_POST[$type][$index] = Util::htmlspecialchars(Util::strtolower(trim($member)));
                 } else {
                     unset($_POST[$type][$index]);
                 }
             }
             // Find the members
             $_POST[$type] = implode(',', array_keys(findMembers($_POST[$type])));
         }
     }
     if (isset($_POST['member_list']) && is_array($_POST['member_list'])) {
         $members = array();
         foreach ($_POST['member_list'] as $member_id) {
             $members[] = (int) $member_id;
         }
         $_POST['members'] = implode(',', $members);
     }
     if (isset($_POST['exclude_member_list']) && is_array($_POST['exclude_member_list'])) {
         $members = array();
         foreach ($_POST['exclude_member_list'] as $member_id) {
             $members[] = (int) $member_id;
         }
         $_POST['exclude_members'] = implode(',', $members);
     }
     // Clean the other vars.
     $this->action_mailingsend(true);
     // We need a couple strings from the email template file
     loadLanguage('EmailTemplates');
     require_once SUBSDIR . '/News.subs.php';
     // Get a list of all full banned users.  Use their Username and email to find them.
     // Only get the ones that can't login to turn off notification.
     $context['recipients']['exclude_members'] = excludeBannedMembers();
     // Did they select moderators - if so add them as specific members...
     if (!empty($context['recipients']['groups']) && in_array(3, $context['recipients']['groups']) || !empty($context['recipients']['exclude_groups']) && in_array(3, $context['recipients']['exclude_groups'])) {
         $mods = getModerators();
         foreach ($mods as $row) {
             if (in_array(3, $context['recipients'])) {
                 $context['recipients']['exclude_members'][] = $row;
             } else {
                 $context['recipients']['members'][] = $row;
             }
         }
     }
     require_once SUBSDIR . '/Members.subs.php';
     // For progress bar!
     $context['total_emails'] = count($context['recipients']['emails']);
     $context['max_id_member'] = maxMemberID();
     // Clean up the arrays.
     $context['recipients']['members'] = array_unique($context['recipients']['members']);
     $context['recipients']['exclude_members'] = array_unique($context['recipients']['exclude_members']);
 }
Ejemplo n.º 28
0
/**
 * Log an error then exit
 *
 * @param string $text
 */
function generateSubscriptionError($text)
{
    global $modSettings, $notify_users;
    // Send an email?
    if (!empty($modSettings['paid_email'])) {
        $replacements = array('ERROR' => $text);
        emailAdmins('paid_subscription_error', $replacements, $notify_users);
    }
    // Maybe we can try to give them the post data?
    if (!empty($_POST)) {
        foreach ($_POST as $key => $val) {
            $text .= '<br />' . Util::htmlspecialchars($key) . ': ' . Util::htmlspecialchars($val);
        }
    }
    // Then just log and die.
    log_error($text);
    exit;
}
Ejemplo n.º 29
0
/**
 * This function reads from the database the addons credits,
 * and returns them in an array for display in credits section of the site.
 * The addons copyright, license, title informations are those saved from <license>
 * and <credits> tags in package.xml.
 *
 * @return array
 */
function addonsCredits()
{
    global $txt;
    $db = database();
    if (($credits = cache_get_data('addons_credits', 86400)) === null) {
        $credits = array();
        $request = $db->query('substring', '
			SELECT version, name, credits
			FROM {db_prefix}log_packages
			WHERE install_state = {int:installed_adds}
				AND credits != {string:empty}
				AND SUBSTRING(filename, 1, 9) != {string:old_patch_name}
				AND SUBSTRING(filename, 1, 9) != {string:patch_name}', array('installed_adds' => 1, 'old_patch_name' => 'smf_patch', 'patch_name' => 'elk_patch', 'empty' => ''));
        while ($row = $db->fetch_assoc($request)) {
            $credit_info = unserialize($row['credits']);
            $copyright = empty($credit_info['copyright']) ? '' : $txt['credits_copyright'] . ' &copy; ' . Util::htmlspecialchars($credit_info['copyright']);
            $license = empty($credit_info['license']) ? '' : $txt['credits_license'] . ': ' . Util::htmlspecialchars($credit_info['license']);
            $version = $txt['credits_version'] . '' . $row['version'];
            $title = (empty($credit_info['title']) ? $row['name'] : Util::htmlspecialchars($credit_info['title'])) . ': ' . $version;
            // build this one out and stash it away
            $name = empty($credit_info['url']) ? $title : '<a href="' . $credit_info['url'] . '">' . $title . '</a>';
            $credits[] = $name . (!empty($license) ? ' | ' . $license : '') . (!empty($copyright) ? ' | ' . $copyright : '');
        }
        cache_put_data('addons_credits', $credits, 86400);
    }
    return $credits;
}
Ejemplo n.º 30
0
 /**
  * Set the values for this split session
  */
 private function _set_session_values()
 {
     global $txt;
     // Clean up the subject.
     if (isset($_POST['subname']) && empty($this->_new_topic_subject)) {
         $this->_new_topic_subject = trim(Util::htmlspecialchars($_POST['subname']));
     }
     if (empty($this->_new_topic_subject)) {
         $this->_new_topic_subject = $txt['new_topic'];
     }
     // Save in session so its available across all the form pages
     if (empty($_SESSION['move_to_board'])) {
         $_SESSION['move_to_board'] = !empty($_POST['move_new_topic']) && !empty($_POST['move_to_board']) ? (int) $_POST['move_to_board'] : 0;
         $_SESSION['reason'] = !empty($_POST['reason']) ? trim(Util::htmlspecialchars($_POST['reason'], ENT_QUOTES)) : '';
         $_SESSION['messageRedirect'] = !empty($_POST['messageRedirect']);
         $_SESSION['new_topic_subject'] = $this->_new_topic_subject;
     }
 }