/** * 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']); }
/** * Display configuration settings for signatures on forum. * * - Accessed from ?action=admin;area=featuresettings;sa=sig; */ public function action_signatureSettings_display() { global $context, $txt, $modSettings, $sig_start, $scripturl; // Initialize the form $this->_initSignatureSettingsForm(); // Retrieve the current config settings $config_vars = $this->_signatureSettings->settings(); // Setup the template. $context['page_title'] = $txt['signature_settings']; $context['sub_template'] = 'show_settings'; // Disable the max smileys option if we don't allow smileys at all! addInlineJavascript(' document.getElementById(\'signature_max_smileys\').disabled = !document.getElementById(\'signature_allow_smileys\').checked;', true); // Load all the signature settings. list($sig_limits, $sig_bbc) = explode(':', $modSettings['signature_settings']); $sig_limits = explode(',', $sig_limits); $disabledTags = !empty($sig_bbc) ? explode(',', $sig_bbc) : array(); // @todo temporary since it does not work, and seriously why would you do this? $disabledTags[] = 'footnote'; // Applying to ALL signatures?!! if (isset($_GET['apply'])) { // Security! checkSession('get'); require_once SUBSDIR . '/ManageFeatures.subs.php'; require_once SUBSDIR . '/Members.subs.php'; $sig_start = time(); // This is horrid - but I suppose some people will want the option to do it. $applied_sigs = isset($_GET['step']) ? (int) $_GET['step'] : 0; $done = false; $context['max_member'] = maxMemberID(); while (!$done) { $changes = array(); $update_sigs = getSignatureFromMembers($applied_sigs); if (empty($update_sigs)) { $done = true; } foreach ($update_sigs as $row) { // Apply all the rules we can realistically do. $sig = strtr($row['signature'], array('<br />' => "\n")); // Max characters... if (!empty($sig_limits[1])) { $sig = Util::substr($sig, 0, $sig_limits[1]); } // Max lines... if (!empty($sig_limits[2])) { $count = 0; $str_len = strlen($sig); for ($i = 0; $i < $str_len; $i++) { if ($sig[$i] == "\n") { $count++; if ($count >= $sig_limits[2]) { $sig = substr($sig, 0, $i) . strtr(substr($sig, $i), array("\n" => ' ')); } } } } if (!empty($sig_limits[7]) && preg_match_all('~\\[size=([\\d\\.]+)(\\]|px|pt|em|x-large|larger)~i', $sig, $matches) !== false) { // Same as parse_bbc $sizes = array(1 => 0.7, 2 => 1.0, 3 => 1.35, 4 => 1.45, 5 => 2.0, 6 => 2.65, 7 => 3.95); foreach ($matches[1] as $ind => $size) { $limit_broke = 0; // Just specifying as [size=x]? if (empty($matches[2][$ind])) { $matches[2][$ind] = 'em'; $size = isset($sizes[(int) $size]) ? $sizes[(int) $size] : 0; } // Attempt to allow all sizes of abuse, so to speak. if ($matches[2][$ind] == 'px' && $size > $sig_limits[7]) { $limit_broke = $sig_limits[7] . 'px'; } elseif ($matches[2][$ind] == 'pt' && $size > $sig_limits[7] * 0.75) { $limit_broke = (int) $sig_limits[7] * 0.75 . 'pt'; } elseif ($matches[2][$ind] == 'em' && $size > (double) $sig_limits[7] / 14) { $limit_broke = (double) $sig_limits[7] / 14 . 'em'; } elseif ($matches[2][$ind] != 'px' && $matches[2][$ind] != 'pt' && $matches[2][$ind] != 'em' && $sig_limits[7] < 18) { $limit_broke = 'large'; } if ($limit_broke) { $sig = str_replace($matches[0][$ind], '[size=' . $sig_limits[7] . 'px', $sig); } } } // Stupid images - this is stupidly, stupidly challenging. if (!empty($sig_limits[3]) || !empty($sig_limits[5]) || !empty($sig_limits[6])) { $replaces = array(); $img_count = 0; // Get all BBC tags... preg_match_all('~\\[img(\\s+width=([\\d]+))?(\\s+height=([\\d]+))?(\\s+width=([\\d]+))?\\s*\\](?:<br />)*([^<">]+?)(?:<br />)*\\[/img\\]~i', $sig, $matches); // ... and all HTML ones. preg_match_all('~<img\\s+src=(?:")?((?:http://|ftp://|https://|ftps://).+?)(?:")?(?:\\s+alt=(?:")?(.*?)(?:")?)?(?:\\s?/)?>~i', $sig, $matches2, PREG_PATTERN_ORDER); // And stick the HTML in the BBC. if (!empty($matches2)) { foreach ($matches2[0] as $ind => $dummy) { $matches[0][] = $matches2[0][$ind]; $matches[1][] = ''; $matches[2][] = ''; $matches[3][] = ''; $matches[4][] = ''; $matches[5][] = ''; $matches[6][] = ''; $matches[7][] = $matches2[1][$ind]; } } // Try to find all the images! if (!empty($matches)) { $image_count_holder = array(); foreach ($matches[0] as $key => $image) { $width = -1; $height = -1; $img_count++; // Too many images? if (!empty($sig_limits[3]) && $img_count > $sig_limits[3]) { // If we've already had this before we only want to remove the excess. if (isset($image_count_holder[$image])) { $img_offset = -1; $rep_img_count = 0; while ($img_offset !== false) { $img_offset = strpos($sig, $image, $img_offset + 1); $rep_img_count++; if ($rep_img_count > $image_count_holder[$image]) { // Only replace the excess. $sig = substr($sig, 0, $img_offset) . str_replace($image, '', substr($sig, $img_offset)); // Stop looping. $img_offset = false; } } } else { $replaces[$image] = ''; } continue; } // Does it have predefined restraints? Width first. if ($matches[6][$key]) { $matches[2][$key] = $matches[6][$key]; } if ($matches[2][$key] && $sig_limits[5] && $matches[2][$key] > $sig_limits[5]) { $width = $sig_limits[5]; $matches[4][$key] = $matches[4][$key] * ($width / $matches[2][$key]); } elseif ($matches[2][$key]) { $width = $matches[2][$key]; } // ... and height. if ($matches[4][$key] && $sig_limits[6] && $matches[4][$key] > $sig_limits[6]) { $height = $sig_limits[6]; if ($width != -1) { $width = $width * ($height / $matches[4][$key]); } } elseif ($matches[4][$key]) { $height = $matches[4][$key]; } // If the dimensions are still not fixed - we need to check the actual image. if ($width == -1 && $sig_limits[5] || $height == -1 && $sig_limits[6]) { // We'll mess up with images, who knows. require_once SUBSDIR . '/Attachments.subs.php'; $sizes = url_image_size($matches[7][$key]); if (is_array($sizes)) { // Too wide? if ($sizes[0] > $sig_limits[5] && $sig_limits[5]) { $width = $sig_limits[5]; $sizes[1] = $sizes[1] * ($width / $sizes[0]); } // Too high? if ($sizes[1] > $sig_limits[6] && $sig_limits[6]) { $height = $sig_limits[6]; if ($width == -1) { $width = $sizes[0]; } $width = $width * ($height / $sizes[1]); } elseif ($width != -1) { $height = $sizes[1]; } } } // Did we come up with some changes? If so remake the string. if ($width != -1 || $height != -1) { $replaces[$image] = '[img' . ($width != -1 ? ' width=' . round($width) : '') . ($height != -1 ? ' height=' . round($height) : '') . ']' . $matches[7][$key] . '[/img]'; } // Record that we got one. $image_count_holder[$image] = isset($image_count_holder[$image]) ? $image_count_holder[$image] + 1 : 1; } if (!empty($replaces)) { $sig = str_replace(array_keys($replaces), array_values($replaces), $sig); } } } // Try to fix disabled tags. if (!empty($disabledTags)) { $sig = preg_replace('~\\[(?:' . implode('|', $disabledTags) . ').+?\\]~i', '', $sig); $sig = preg_replace('~\\[/(?:' . implode('|', $disabledTags) . ')\\]~i', '', $sig); } $sig = strtr($sig, array("\n" => '<br />')); call_integration_hook('integrate_apply_signature_settings', array(&$sig, $sig_limits, $disabledTags)); if ($sig != $row['signature']) { $changes[$row['id_member']] = $sig; } } // Do we need to delete what we have? if (!empty($changes)) { foreach ($changes as $id => $sig) { updateSignature($id, $sig); } } $applied_sigs += 50; if (!$done) { pauseSignatureApplySettings($applied_sigs); } } $settings_applied = true; } $context['signature_settings'] = array('enable' => isset($sig_limits[0]) ? $sig_limits[0] : 0, 'max_length' => isset($sig_limits[1]) ? $sig_limits[1] : 0, 'max_lines' => isset($sig_limits[2]) ? $sig_limits[2] : 0, 'max_images' => isset($sig_limits[3]) ? $sig_limits[3] : 0, 'allow_smileys' => isset($sig_limits[4]) && $sig_limits[4] == -1 ? 0 : 1, 'max_smileys' => isset($sig_limits[4]) && $sig_limits[4] != -1 ? $sig_limits[4] : 0, 'max_image_width' => isset($sig_limits[5]) ? $sig_limits[5] : 0, 'max_image_height' => isset($sig_limits[6]) ? $sig_limits[6] : 0, 'max_font_size' => isset($sig_limits[7]) ? $sig_limits[7] : 0); // Temporarily make each setting a modSetting! foreach ($context['signature_settings'] as $key => $value) { $modSettings['signature_' . $key] = $value; } // Make sure we check the right tags! $modSettings['bbc_disabled_signature_bbc'] = $disabledTags; // We're working with them settings. require_once SUBSDIR . '/SettingsForm.class.php'; // Saving? if (isset($_GET['save'])) { checkSession(); // Clean up the tag stuff! $bbcTags = array(); foreach (parse_bbc(false) as $tag) { $bbcTags[] = $tag['tag']; } if (!isset($_POST['signature_bbc_enabledTags'])) { $_POST['signature_bbc_enabledTags'] = array(); } elseif (!is_array($_POST['signature_bbc_enabledTags'])) { $_POST['signature_bbc_enabledTags'] = array($_POST['signature_bbc_enabledTags']); } $sig_limits = array(); foreach ($context['signature_settings'] as $key => $value) { if ($key == 'allow_smileys') { continue; } elseif ($key == 'max_smileys' && empty($_POST['signature_allow_smileys'])) { $sig_limits[] = -1; } else { $sig_limits[] = !empty($_POST['signature_' . $key]) ? max(1, (int) $_POST['signature_' . $key]) : 0; } } call_integration_hook('integrate_save_signature_settings', array(&$sig_limits, &$bbcTags)); $_POST['signature_settings'] = implode(',', $sig_limits) . ':' . implode(',', array_diff($bbcTags, $_POST['signature_bbc_enabledTags'])); // Even though we have practically no settings let's keep the convention going! $save_vars = array(); $save_vars[] = array('text', 'signature_settings'); Settings_Form::save_db($save_vars); redirectexit('action=admin;area=featuresettings;sa=sig'); } $context['post_url'] = $scripturl . '?action=admin;area=featuresettings;save;sa=sig'; $context['settings_title'] = $txt['signature_settings']; $context['settings_message'] = !empty($settings_applied) ? $txt['signature_settings_applied'] : sprintf($txt['signature_settings_warning'], $scripturl . '?action=admin;area=featuresettings;sa=sig;apply;' . $context['session_var'] . '=' . $context['session_id']); Settings_Form::prepare_db($config_vars); }