/**
  * The UI to confirm sending of our newsletter.
  *
  * @return tempcode		The UI
  */
 function confirm_send()
 {
     $title = get_page_title('NEWSLETTER_SEND');
     $message = post_param('message');
     $subject = post_param('subject');
     $lang = choose_language($title);
     $template = post_param('template', 'MAIL');
     $in_full = post_param_integer('in_full', 0);
     $html_only = post_param_integer('html_only', 0);
     $from_email = post_param('from_email', '');
     $from_name = post_param('from_name', '');
     $extra_post_data = array();
     require_code('uploads');
     if (is_swf_upload(true) && array_key_exists('file', $_FILES) || array_key_exists('file', $_FILES) && is_uploaded_file($_FILES['file']['tmp_name'])) {
         $_csv_data = array();
         $myfile = fopen($_FILES['file']['tmp_name'], 'rt');
         $del = ',';
         $csv_test_line = fgetcsv($myfile, 4096, $del);
         if (count($csv_test_line) == 1 && strpos($csv_test_line[0], ';') !== false) {
             $del = ';';
         }
         rewind($myfile);
         while (($csv_line = fgetcsv($myfile, 4096, $del)) !== false) {
             $_csv_data[] = $csv_line;
         }
         fclose($myfile);
         $extra_post_data['csv_data'] = serialize($_csv_data);
     }
     if (post_param_integer('make_periodic', 0) == 1) {
         // We're making a periodic newsletter. Thus we need to pass this info
         // through to the next step
         $extra_post_data['make_periodic'] = '1';
         // Re-generate preview from latest chosen_categories
         $message = $this->generate_whats_new_comcode(post_param('chosen_categories', ''), $in_full, $lang, get_input_date('cutoff'));
     }
     $address = $GLOBALS['FORUM_DRIVER']->get_member_email_address(get_member());
     if ($address == '') {
         $address = get_option('staff_address');
     }
     $username = $GLOBALS['FORUM_DRIVER']->get_username(get_member());
     $message = newsletter_variable_substitution($message, $subject, '', '', do_lang('UNKNOWN'), $address, 'test', '');
     require_code('mail');
     require_code('tempcode_compiler');
     $in_html = false;
     if (strpos($message, '<html') !== false) {
         $_preview = template_to_tempcode($message);
         $in_html = true;
     } else {
         $comcode_version = comcode_to_tempcode($message, get_member(), true);
         $_preview = do_template('MAIL', array('TITLE' => $subject, 'CSS' => css_tempcode(true, true, $comcode_version->evaluate()), 'LANG' => get_site_default_lang(), 'LOGOURL' => get_logo_url(''), 'CONTENT' => $comcode_version), NULL, false, NULL, '.tpl', 'templates', $GLOBALS['FORUM_DRIVER']->get_theme(''));
         $in_html = $html_only == 1;
     }
     $text_preview = $html_only == 1 ? '' : comcode_to_clean_text(static_evaluate_tempcode(template_to_tempcode($message)));
     require_code('mail');
     $preview_subject = $subject;
     if (post_param_integer('make_periodic', 0) == 1) {
         $preview_subject .= ' - ' . get_timezoned_date(time(), false, false, false, true);
     }
     require_code('comcode_text');
     $preview = do_template('NEWSLETTER_CONFIRM_WRAP', array('_GUID' => '02bd5a782620141f8589e647e2c6d90b', 'TEXT_PREVIEW' => $text_preview, 'PREVIEW' => $_preview, 'SUBJECT' => $subject));
     mail_wrap($preview_subject, $html_only == 1 ? $_preview->evaluate() : $message, array($address), $username, $from_email, $from_name, 3, NULL, true, NULL, true, $in_html);
     breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('MANAGE_NEWSLETTER')), array('_SELF:_SELF:new', do_lang_tempcode('NEWSLETTER_SEND'))));
     breadcrumb_set_self(do_lang_tempcode('CONFIRM'));
     require_code('templates_confirm_screen');
     return form_confirm_screen($title, $preview, 'send', get_param('old_type', 'new'), $extra_post_data);
 }
Beispiel #2
0
/**
 * Attempt to send an e-mail to the specified recipient. The mail will be forwarding to the CC address specified in the options (if there is one, and if not specified not to cc).
 * The mail will be sent in dual HTML/text format, where the text is the unconverted comcode source: if a member does not read HTML mail, they may wish to fallback to reading that.
 *
 * @param  string			The subject of the mail in plain text
 * @param  LONG_TEXT		The message, as Comcode
 * @param  ?array			The destination (recipient) e-mail addresses [array of strings] (NULL: site staff address)
 * @param  ?mixed			The recipient name. Array or string. (NULL: site name)
 * @param  EMAIL			The from address (blank: site staff address)
 * @param  string			The from name (blank: site name)
 * @param  integer		The message priority (1=urgent, 3=normal, 5=low)
 * @range  1 5
 * @param  ?array			An list of attachments (each attachment being a map, path=>filename) (NULL: none)
 * @param  boolean		Whether to NOT CC to the CC address
 * @param  ?MEMBER		Convert comcode->tempcode as this member (a privilege thing: we don't want people being able to use admin rights by default!) (NULL: guest)
 * @param  boolean		Replace above with arbitrary admin
 * @param  boolean		HTML-only
 * @param  boolean		Whether to bypass queueing, because this code is running as a part of the queue management tools
 * @param  ID_TEXT		The template used to show the email
 * @param  boolean		Whether to bypass queueing
 * @return ?tempcode		A full page (not complete XHTML) piece of tempcode to output (NULL: it worked so no tempcode message)
 */
function mail_wrap($subject_tag, $message_raw, $to_email = NULL, $to_name = NULL, $from_email = '', $from_name = '', $priority = 3, $attachments = NULL, $no_cc = false, $as = NULL, $as_admin = false, $in_html = false, $coming_out_of_queue = false, $mail_template = 'MAIL', $bypass_queue = false)
{
    if (get_option('smtp_sockets_use') == '0') {
        return non_overrided__mail_wrap($subject_tag, $message_raw, $to_email, $to_name, $from_email, $from_name, $priority, $attachments, $no_cc, $as, $as_admin, $in_html, $coming_out_of_queue);
    }
    if (running_script('stress_test_loader')) {
        return NULL;
    }
    if (is_null($bypass_queue)) {
        $bypass_queue = $priority < 3 || strpos(serialize($attachments), 'tmpfile') !== false;
    }
    global $EMAIL_ATTACHMENTS;
    $EMAIL_ATTACHMENTS = array();
    require_code('site');
    require_code('mime_types');
    if (is_null($as)) {
        $as = $GLOBALS['FORUM_DRIVER']->get_guest_id();
    }
    if (!$coming_out_of_queue) {
        $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'logged_mail_messages WHERE m_date_and_time<' . strval(time() - 60 * 60 * 24 * 14) . ' AND m_queued=0');
        // Log it all for 2 weeks, then delete
        $through_queue = !$bypass_queue && (get_option('mail_queue_debug') === '1' || get_option('mail_queue') === '1' && cron_installed());
        $GLOBALS['SITE_DB']->query_insert('logged_mail_messages', array('m_subject' => $subject_tag, 'm_message' => $message_raw, 'm_to_email' => serialize($to_email), 'm_to_name' => serialize($to_name), 'm_from_email' => $from_email, 'm_from_name' => $from_name, 'm_priority' => 3, 'm_attachments' => serialize($attachments), 'm_no_cc' => $no_cc ? 1 : 0, 'm_as' => $as, 'm_as_admin' => $as_admin ? 1 : 0, 'm_in_html' => $in_html ? 1 : 0, 'm_date_and_time' => time(), 'm_member_id' => get_member(), 'm_url' => get_self_url(true), 'm_queued' => $through_queue ? 1 : 0, 'm_template' => $mail_template));
        if ($through_queue) {
            return NULL;
        }
    }
    if (count($attachments) == 0) {
        $attachments = NULL;
    }
    global $SENDING_MAIL;
    if ($SENDING_MAIL) {
        return NULL;
    }
    $SENDING_MAIL = true;
    // To and from, and language
    $staff_address = get_option('staff_address');
    if (is_null($to_email)) {
        $to_email = array($staff_address);
    }
    $to_email_new = array();
    foreach ($to_email as $test_address) {
        if ($test_address != '') {
            $to_email_new[] = $test_address;
        }
    }
    $to_email = $to_email_new;
    if ($to_email == array()) {
        $SENDING_MAIL = false;
        return NULL;
    }
    if ($to_email[0] == $staff_address) {
        $lang = get_site_default_lang();
    } else {
        $lang = user_lang();
        if (method_exists($GLOBALS['FORUM_DRIVER'], 'get_member_from_email_address')) {
            $member_id = $GLOBALS['FORUM_DRIVER']->get_member_from_email_address($to_email[0]);
            if (!is_null($member_id)) {
                $lang = get_lang($member_id);
            }
        }
    }
    if (is_null($to_name)) {
        if ($to_email[0] == $staff_address) {
            $to_name = get_site_name();
        } else {
            $to_name = '';
        }
    }
    if ($from_email == '') {
        $from_email = get_option('staff_address');
    }
    if ($from_name == '') {
        $from_name = get_site_name();
    }
    $theme = method_exists($GLOBALS['FORUM_DRIVER'], 'get_theme') ? $GLOBALS['FORUM_DRIVER']->get_theme() : 'default';
    if ($theme == 'default') {
        $theme = $GLOBALS['FORUM_DRIVER']->get_theme('');
        // ... So get theme of welcome zone
    }
    // Our subject
    $_subject = do_template('MAIL_SUBJECT', array('_GUID' => '44a57c666bb00f96723256e26aade9e5', 'SUBJECT_TAG' => $subject_tag), $lang, false, NULL, '.tpl', 'templates', $theme);
    $subject = $_subject->evaluate($lang);
    // Note that this is slightly against spec, because characters aren't forced to be printable us-ascii. But it's better we allow this (which works in practice) than risk incompatibility via charset-base64 encoding.
    // Evaluate message. Needs doing early so we know if we have any headers
    // Misc settings
    $website_email = get_option('website_email');
    if ($website_email == '') {
        $website_email = $from_email;
    }
    $cc_address = $no_cc ? '' : get_option("cc_address");
    global $CID_IMG_ATTACHMENT;
    $CID_IMG_ATTACHMENT = array();
    // Decide message
    $GLOBALS['NO_LINK_TITLES'] = true;
    global $LAX_COMCODE;
    $temp = $LAX_COMCODE;
    $LAX_COMCODE = true;
    $html_content = comcode_to_tempcode($message_raw, $as, $as_admin);
    $LAX_COMCODE = $temp;
    $GLOBALS['NO_LINK_TITLES'] = false;
    if (!$in_html) {
        $_html_content = $html_content->evaluate($lang);
        $_html_content = preg_replace('#(keep|for)_session=[\\d\\w]*#', 'filtered=1', $_html_content);
        $message_html = strpos($_html_content, '<html') !== false ? make_string_tempcode($_html_content) : do_template($mail_template, array('_GUID' => 'b23069c20202aa59b7450ebf8d49cde1', 'CSS' => '{CSS}', 'LOGOURL' => get_logo_url(''), 'LANG' => $lang, 'TITLE' => $subject, 'CONTENT' => $_html_content), $lang, false, NULL, '.tpl', 'templates', $theme);
        $css = css_tempcode(true, true, $message_html->evaluate($lang), $theme);
        $_css = $css->evaluate($lang);
        if (get_option('allow_ext_images') != '1') {
            $_css = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $_css);
        }
        $html_evaluated = $message_html->evaluate($lang);
        $html_evaluated = str_replace('{CSS}', $_css, $html_evaluated);
        // Cleanup the Comcode a bit
        $message_plain = comcode_to_clean_text($message_raw);
    } else {
        $html_evaluated = $message_raw;
    }
    // Character set
    $regexp = '#^[\\x' . dechex(32) . '-\\x' . dechex(126) . ']*$#';
    $charset = preg_match($regexp, $html_evaluated) == 0 ? do_lang('charset', NULL, NULL, NULL, $lang) : 'us-ascii';
    // CID attachments
    if (get_option('allow_ext_images') != '1') {
        $html_evaluated = preg_replace_callback('#<img\\s([^>]*)src="(http://[^"]*)"#U', '_mail_img_rep_callback', $html_evaluated);
        $matches = array();
        foreach (array('#<([^"<>]*\\s)style="([^"]*)"#', '#<style( [^<>]*)?' . '>(.*)</style>#Us') as $over) {
            $num_matches = preg_match_all($over, $html_evaluated, $matches);
            for ($i = 0; $i < $num_matches; $i++) {
                $altered_inner = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $matches[2][$i]);
                if ($matches[2][$i] != $altered_inner) {
                    $altered_outer = str_replace($matches[2][$i], $altered_inner, $matches[0][$i]);
                    $html_evaluated = str_replace($matches[0][$i], $altered_outer, $html_evaluated);
                }
            }
        }
    }
    $cid_attachments = array();
    foreach ($CID_IMG_ATTACHMENT as $id => $img) {
        $file_path_stub = convert_url_to_path($img);
        $mime_type = get_mime_type(get_file_extension($img));
        $filename = basename($img);
        if (!is_null($file_path_stub)) {
            $cid_attachment = array('mime' => $mime_type, 'filename' => $filename, 'path' => $file_path_stub, 'temp' => false, 'cid' => $id);
        } else {
            $myfile = ocp_tempnam('email_attachment');
            http_download_file($img, NULL, false, false, 'ocPortal', NULL, NULL, NULL, NULL, NULL, $myfile);
            if (!is_null($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'])) {
                $mime_type = $GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'];
            }
            if (!is_null($GLOBALS['HTTP_FILENAME'])) {
                $filename = $GLOBALS['HTTP_FILENAME'];
            }
            $cid_attachment = array('mime' => $mime_type, 'filename' => $filename, 'path' => $myfile, 'temp' => true, 'cid' => $id);
        }
        $cid_attachments[] = $cid_attachment;
    }
    // Attachments
    $real_attachments = array();
    $attachments = array_merge(is_null($attachments) ? array() : $attachments, $EMAIL_ATTACHMENTS);
    if (!is_null($attachments)) {
        foreach ($attachments as $path => $filename) {
            $mime_type = get_mime_type(get_file_extension($filename));
            if (strpos($path, '://') === false) {
                $real_attachment = array('mime' => $mime_type, 'filename' => $filename, 'path' => $path, 'temp' => false);
            } else {
                $myfile = ocp_tempnam('email_attachment');
                http_download_file($path, NULL, false, false, 'ocPortal', NULL, NULL, NULL, NULL, NULL, $myfile);
                if (!is_null($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'])) {
                    $mime_type = $GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'];
                }
                if (!is_null($GLOBALS['HTTP_FILENAME'])) {
                    $filename = $GLOBALS['HTTP_FILENAME'];
                }
                $real_attachment = array('mime' => $mime_type, 'filename' => $filename, 'path' => $myfile, 'temp' => true);
            }
            $real_attachments[] = $real_attachment;
        }
    }
    // ==========================
    // Interface with SwiftMailer
    // ==========================
    require_code('Swift-4.1.1/lib/swift_required');
    // Read in SMTP settings
    $host = get_option('smtp_sockets_host');
    $port = intval(get_option('smtp_sockets_port'));
    $username = get_option('smtp_sockets_username');
    $password = get_option('smtp_sockets_password');
    $smtp_from_address = get_option('smtp_from_address');
    if ($smtp_from_address != '') {
        $from_email = $smtp_from_address;
    }
    // Create the Transport
    $transport = Swift_SmtpTransport::newInstance($host, $port)->setUsername($username)->setPassword($password);
    if ($port == 419 || $port == 465 || $port == 587) {
        $transport->setEncryption('tls');
    }
    // Create the Mailer using your created Transport
    $mailer = Swift_Mailer::newInstance($transport);
    // Create a message
    $to_array = array();
    if ($to_name === '') {
        foreach ($to_email as $_to_email) {
            $to_array[] = $_to_email;
        }
    } else {
        foreach ($to_email as $i => $_to_email) {
            $to_array[$_to_email] = is_array($to_name) ? $to_name[$i] : $to_name;
        }
    }
    $message = Swift_Message::newInstance($subject)->setFrom(array($website_email => $from_name))->setReplyTo(array($from_email => $from_name))->setTo($to_array)->setPriority($priority)->setCharset($charset)->setBody($html_evaluated, 'text/html', $charset)->addPart($message_plain, 'text/plain', $charset);
    if ($cc_address != '') {
        $message->setCc($cc_address);
    }
    // Attachments
    foreach ($real_attachments as $r) {
        $attachment = Swift_Attachment::fromPath($r['path'], $r['mime'])->setFilename($r['filename'])->setDisposition('attachment');
        $message->attach($attachment);
    }
    foreach ($cid_attachments as $r) {
        $attachment = Swift_Attachment::fromPath($r['path'], $r['mime'])->setFilename($r['filename'])->setDisposition('attachment')->setId($r['cid']);
        $message->attach($attachment);
    }
    // Send the message, and error collection
    $error = '';
    try {
        $result = $mailer->send($message);
    } catch (Exception $e) {
        $error = $e->getMessage();
    }
    if ($error == '' && !$result) {
        $error = 'Unknown error';
    }
    // Attachment cleanup
    foreach ($real_attachments as $r) {
        if ($r['temp']) {
            @unlink($r['path']);
        }
    }
    foreach ($cid_attachments as $r) {
        if ($r['temp']) {
            @unlink($r['path']);
        }
    }
    // Return / Error handling
    $SENDING_MAIL = false;
    if ($error != '') {
        if (get_param_integer('keep_hide_mail_failure', 0) == 0) {
            require_code('site');
            attach_message(!is_null($error) ? make_string_tempcode($error) : do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address'))), 'warn');
        } else {
            return warn_screen(get_page_title('ERROR_OCCURRED'), do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address'))));
        }
    }
    return NULL;
}
Beispiel #3
0
/**
 * OcCLE entry script.
 */
function occle_script()
{
    $cli = php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']);
    // Closed site
    if (!$cli) {
        $site_closed = get_option('site_closed');
        if ($site_closed == '1' && !has_specific_permission(get_member(), 'access_closed_site') && !$GLOBALS['IS_ACTUALLY_ADMIN']) {
            header('Content-Type: text/plain');
            @exit(get_option('closed'));
        }
        if (get_file_base() != get_custom_file_base()) {
            warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT'));
        }
        if (!has_actual_page_access(get_member(), 'admin_occle')) {
            fatal_exit(do_lang_tempcode('ACCESS_DENIED__PAGE_ACCESS', escape_html($GLOBALS['FORUM_DRIVER']->get_username(get_member()))));
        }
    }
    // Check the action
    convert_data_encodings(true);
    $action = get_param('action', 'occle');
    if ($action == 'message') {
        // We're receiving an OcCLEchat message
        $url = get_param('base_url') . '/data/occle.php?action=confirm&message=' . urlencode(get_param('message'));
        $return = http_download_file($url, NULL, false);
        if ($return == '1') {
            if (ocp_srv('HTTP_USER_AGENT') == 'ocPortal') {
                $GLOBALS['SITE_DB']->query_insert('occlechat', array('c_message' => get_param('message'), 'c_url' => get_param('base_url'), 'c_incoming' => 1, 'c_timestamp' => time()));
                echo '1';
            } else {
                echo '0';
            }
        } else {
            echo '0';
        }
    } elseif ($action == 'confirm') {
        // We're confirming a received message
        if (ocp_srv('HTTP_USER_AGENT') == 'ocPortal') {
            $results = $GLOBALS['SITE_DB']->query_value_null_ok('occlechat', 'COUNT(*)', array('c_message' => get_param('message'), 'c_incoming' => false));
            if (!is_null($results)) {
                echo '1';
            } else {
                echo '0';
            }
        } else {
            echo '0';
        }
    } else {
        // Executing a command from the command-line
        $command = post_param('command', $cli ? NULL : false);
        if (is_null($command)) {
            require_code('comcode_from_html');
            require_code('mail');
            $stdin = @fopen('php://stdin', 'rt');
            $stderr = @fopen('php://stderr', 'wt');
            $stdout = @fopen('php://stdout', 'wt');
            while (true) {
                fwrite($stdout, "\n> ");
                $command = fgets($stdin, 102400);
                if (trim($command) == 'exit') {
                    break;
                }
                $temp = new virtual_bash(trim($command));
                if (trim($temp->output[STREAM_STDHTML]) != '') {
                    fwrite($stdout, trim(comcode_to_clean_text(semihtml_to_comcode(preg_replace('#<(\\w+) [^<>]*>#', '<${1}>', $temp->output[STREAM_STDHTML])))));
                }
                if (trim($temp->output[STREAM_STDOUT]) != '') {
                    fwrite($stdout, trim($temp->output[STREAM_STDOUT]));
                }
                if (trim($temp->output[STREAM_STDERR]) != '') {
                    fwrite($stderr, trim($temp->output[STREAM_STDERR]));
                }
            }
            fclose($stdin);
            fclose($stderr);
            fclose($stdout);
        } else {
            $temp = new virtual_bash(trim($command));
            $temp->output_xml();
        }
        if (get_option('occle_chat_announce') == '1') {
            http_download_file('http://ocportal.com/data_custom/occle.php?title=' . urlencode(get_site_name()) . '&url=' . urlencode(get_custom_base_url()), NULL, false, true);
        }
    }
}
Beispiel #4
0
/**
 * Attempt to send an e-mail to the specified recipient. The mail will be forwarding to the CC address specified in the options (if there is one, and if not specified not to cc).
 * The mail will be sent in dual HTML/text format, where the text is the unconverted comcode source: if a member does not read HTML mail, they may wish to fallback to reading that.
 *
 * @param  string			The subject of the mail in plain text
 * @param  LONG_TEXT		The message, as Comcode
 * @param  ?array			The destination (recipient) e-mail addresses [array of strings] (NULL: site staff address)
 * @param  ?mixed			The recipient name. Array or string. (NULL: site name)
 * @param  EMAIL			The from address (blank: site staff address)
 * @param  string			The from name (blank: site name)
 * @param  integer		The message priority (1=urgent, 3=normal, 5=low)
 * @range  1 5
 * @param  ?array			An list of attachments (each attachment being a map, path=>filename) (NULL: none)
 * @param  boolean		Whether to NOT CC to the CC address
 * @param  ?MEMBER		Convert comcode->tempcode as this member (a privilege thing: we don't want people being able to use admin rights by default!) (NULL: guest)
 * @param  boolean		Replace above with arbitrary admin
 * @param  boolean		HTML-only
 * @param  boolean		Whether to bypass queueing, because this code is running as a part of the queue management tools
 * @param  ID_TEXT		The template used to show the email
 * @param  boolean		Whether to bypass queueing
 * @return ?tempcode		A full page (not complete XHTML) piece of tempcode to output (NULL: it worked so no tempcode message)
 */
function mail_wrap($subject_tag, $message_raw, $to_email = NULL, $to_name = NULL, $from_email = '', $from_name = '', $priority = 3, $attachments = NULL, $no_cc = false, $as = NULL, $as_admin = false, $in_html = false, $coming_out_of_queue = false, $mail_template = 'MAIL', $bypass_queue = false)
{
    if (running_script('stress_test_loader')) {
        return NULL;
    }
    global $EMAIL_ATTACHMENTS;
    $EMAIL_ATTACHMENTS = array();
    require_code('site');
    require_code('mime_types');
    $bypass_queue = $bypass_queue || $priority < 3 || strpos(serialize($attachments), 'tmpfile') !== false;
    if (is_null($as)) {
        $as = $GLOBALS['FORUM_DRIVER']->get_guest_id();
    }
    if (!$coming_out_of_queue) {
        $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'logged_mail_messages WHERE m_date_and_time<' . strval(time() - 60 * 60 * 24 * 14) . ' AND m_queued=0');
        // Log it all for 2 weeks, then delete
        $through_queue = !$bypass_queue && (get_option('mail_queue_debug') === '1' || get_option('mail_queue') === '1' && cron_installed());
        $GLOBALS['SITE_DB']->query_insert('logged_mail_messages', array('m_subject' => substr($subject_tag, 0, 255), 'm_message' => $message_raw, 'm_to_email' => serialize($to_email), 'm_to_name' => serialize($to_name), 'm_from_email' => $from_email, 'm_from_name' => $from_name, 'm_priority' => $priority, 'm_attachments' => serialize($attachments), 'm_no_cc' => $no_cc ? 1 : 0, 'm_as' => $as, 'm_as_admin' => $as_admin ? 1 : 0, 'm_in_html' => $in_html ? 1 : 0, 'm_date_and_time' => time(), 'm_member_id' => get_member(), 'm_url' => get_self_url(true), 'm_queued' => $through_queue ? 1 : 0, 'm_template' => $mail_template), false, !$through_queue);
        // No errors if we don't NEED this to work
        if ($through_queue) {
            return NULL;
        }
    }
    if (count($attachments) == 0) {
        $attachments = NULL;
    }
    global $SENDING_MAIL;
    if ($SENDING_MAIL) {
        return NULL;
    }
    $SENDING_MAIL = true;
    // To and from, and language
    $staff_address = get_option('staff_address');
    if (is_null($to_email)) {
        $to_email = array($staff_address);
    }
    $to_email_new = array();
    foreach ($to_email as $test_address) {
        if ($test_address != '') {
            $to_email_new[] = $test_address;
        }
    }
    $to_email = $to_email_new;
    if ($to_email == array()) {
        $SENDING_MAIL = false;
        return NULL;
    }
    if ($to_email[0] == $staff_address) {
        $lang = get_site_default_lang();
    } else {
        $lang = user_lang();
        if (method_exists($GLOBALS['FORUM_DRIVER'], 'get_member_from_email_address')) {
            $member_id = $GLOBALS['FORUM_DRIVER']->get_member_from_email_address($to_email[0]);
            if (!is_null($member_id)) {
                $lang = get_lang($member_id);
            }
        }
    }
    if (is_null($to_name)) {
        if ($to_email[0] == $staff_address) {
            $to_name = get_site_name();
        } else {
            $to_name = '';
        }
    }
    if ($from_email == '') {
        $from_email = get_option('staff_address');
    }
    if ($from_name == '') {
        $from_name = get_site_name();
    }
    $from_email = str_replace("\r", '', $from_email);
    $from_email = str_replace("\n", '', $from_email);
    $from_name = str_replace("\r", '', $from_name);
    $from_name = str_replace("\n", '', $from_name);
    $theme = method_exists($GLOBALS['FORUM_DRIVER'], 'get_theme') ? $GLOBALS['FORUM_DRIVER']->get_theme() : 'default';
    if ($theme == 'default') {
        $theme = $GLOBALS['FORUM_DRIVER']->get_theme('');
        // ... So get theme of welcome zone
    }
    // Line termination is fiddly. It is safer to rely on sendmail supporting \n than undetectable-qmail/postfix-masquerading-as-sendmail not supporting the correct \r\n
    /*$sendmail_path=ini_get('sendmail_path');
    	if ((strpos($sendmail_path,'qmail')!==false) || (strpos($sendmail_path,'sendmail')!==false))
    		$line_term="\n";
    	else
    		$line_term="\r\n";
    	*/
    if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' || get_option('smtp_sockets_use') == '1') {
        $line_term = "\r\n";
        /*} elseif (strtoupper(substr(PHP_OS,0,3))=='MAC')
        	{
        		$line_term="\r";*/
    } else {
        $line_term = "\n";
    }
    // We use the boundary to seperate message parts
    $_boundary = uniqid('ocPortal', true);
    $boundary = $_boundary . '_1';
    $boundary2 = $_boundary . '_2';
    $boundary3 = $_boundary . '_3';
    // Our subject
    $subject = do_template('MAIL_SUBJECT', array('_GUID' => '44a57c666bb00f96723256e26aade9e5', 'SUBJECT_TAG' => $subject_tag), $lang, false, NULL, '.tpl', 'templates', $theme);
    $tightened_subject = $subject->evaluate($lang);
    // Note that this is slightly against spec, because characters aren't forced to be printable us-ascii. But it's better we allow this (which works in practice) than risk incompatibility via charset-base64 encoding.
    $tightened_subject = str_replace(chr(10), '', $tightened_subject);
    $tightened_subject = str_replace(chr(13), '', $tightened_subject);
    $regexp = '#^[\\x' . dechex(32) . '-\\x' . dechex(126) . ']*$#';
    if (preg_match($regexp, $tightened_subject) == 0) {
        $tightened_subject = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($tightened_subject) . "?=";
    }
    if (preg_match($regexp, $from_name) == 0) {
        $from_name = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($from_name) . "?=";
    }
    if (is_array($to_name)) {
        foreach ($to_name as $i => $_to_name) {
            if (preg_match($regexp, $_to_name) == 0) {
                $to_name[$i] = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($_to_name) . "?=";
            }
        }
    } else {
        if (preg_match($regexp, $to_name) == 0) {
            $to_name = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($to_name) . "?=";
        }
    }
    $simplify_when_can = true;
    // Used for testing. Not actually needed
    // Evaluate message. Needs doing early so we know if we have any headers
    $GLOBALS['NO_LINK_TITLES'] = true;
    global $LAX_COMCODE;
    $temp = $LAX_COMCODE;
    $LAX_COMCODE = true;
    $html_content = comcode_to_tempcode($message_raw, $as, $as_admin);
    $LAX_COMCODE = $temp;
    $GLOBALS['NO_LINK_TITLES'] = false;
    $attachments = array_merge(is_null($attachments) ? array() : $attachments, $EMAIL_ATTACHMENTS);
    // Headers
    $website_email = get_option('website_email');
    if ($website_email == '') {
        $website_email = $from_email;
    }
    if (get_value('use_true_from') !== '1') {
        $headers = 'From: "' . $from_name . '" <' . $website_email . '>' . $line_term;
    } else {
        $headers = 'From: <' . $from_email . '>' . $line_term;
    }
    $headers .= 'Reply-To: <' . $from_email . '>' . $line_term;
    $headers .= 'Return-Path: <' . $website_email . '>' . $line_term;
    $headers .= 'X-Sender: <' . $website_email . '>' . $line_term;
    $cc_address = $no_cc ? '' : get_option('cc_address');
    if ($cc_address != '' && !in_array($cc_address, $to_email)) {
        $headers .= (get_option('bcc') == '1' ? 'Bcc: <' : 'Cc: <') . $cc_address . '>' . $line_term;
    }
    $headers .= 'Message-ID: <' . $_boundary . '@' . get_domain() . '>' . $line_term;
    $headers .= 'X-Priority: ' . strval($priority) . $line_term;
    $brand_name = get_value('rebrand_name');
    if (is_null($brand_name)) {
        $brand_name = 'ocPortal';
    }
    $headers .= 'X-Mailer: ' . $brand_name . $line_term;
    $headers .= 'MIME-Version: 1.0' . $line_term;
    if (!is_null($attachments) || !$simplify_when_can) {
        $headers .= 'Content-Type: multipart/mixed;' . "\n\t" . 'boundary="' . $boundary . '"';
    } else {
        $headers .= 'Content-Type: multipart/alternative;' . "\n\t" . 'boundary="' . $boundary2 . '"';
    }
    $sending_message = '';
    $sending_message .= 'This is a multi-part message in MIME format.' . $line_term . $line_term;
    if (!is_null($attachments) || !$simplify_when_can) {
        $sending_message .= '--' . $boundary . $line_term;
        $sending_message .= 'Content-Type: multipart/alternative;' . "\n\t" . 'boundary="' . $boundary2 . '"' . $line_term . $line_term . $line_term;
    }
    global $CID_IMG_ATTACHMENT;
    $CID_IMG_ATTACHMENT = array();
    // Message starts (actually: it is kind of in header form also as it uses mime multi-part)
    if (!$in_html) {
        $_html_content = $html_content->evaluate($lang);
        $_html_content = preg_replace('#(keep|for)_session=[\\d\\w]*#', 'filtered=1', $_html_content);
        $message_html = strpos($_html_content, '<html') !== false ? make_string_tempcode($_html_content) : do_template($mail_template, array('_GUID' => 'b23069c20202aa59b7450ebf8d49cde1', 'CSS' => '{CSS}', 'LOGOURL' => get_logo_url(''), 'LANG' => $lang, 'TITLE' => $subject, 'CONTENT' => $_html_content), $lang, false, NULL, '.tpl', 'templates', $theme);
        $css = css_tempcode(true, true, $message_html->evaluate($lang), $theme);
        $_css = $css->evaluate($lang);
        if (get_option('allow_ext_images') != '1') {
            $_css = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $_css);
        }
        $html_evaluated = $message_html->evaluate($lang);
        $html_evaluated = str_replace('{CSS}', $_css, $html_evaluated);
        // Cleanup the Comcode a bit
        $message_plain = comcode_to_clean_text($message_raw);
    } else {
        $html_evaluated = $message_raw;
    }
    $base64_encode = get_value('base64_emails') === '1';
    // More robust, but more likely to be spam-blocked, and some servers can scramble it.
    // Plain version
    if (!$in_html) {
        $sending_message .= '--' . $boundary2 . $line_term;
        $sending_message .= 'Content-Type: text/plain; charset=' . (preg_match($regexp, $message_plain) == 0 ? do_lang('charset', NULL, NULL, NULL, $lang) : 'us-ascii') . $line_term;
        // '; name="message.txt"'.	Outlook doesn't like: makes it think it's an attachment
        if ($base64_encode) {
            $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term;
            $sending_message .= chunk_split(base64_encode(unixify_line_format($message_plain)) . $line_term, 76, $line_term);
        } else {
            $sending_message .= 'Content-Transfer-Encoding: 8bit' . $line_term . $line_term;
            $sending_message .= wordwrap(str_replace(chr(10), $line_term, unixify_line_format($message_plain)) . $line_term, 998, $line_term);
        }
    }
    // HTML version
    $sending_message .= '--' . $boundary2 . $line_term;
    $sending_message .= 'Content-Type: multipart/related;' . "\n\t" . 'type="text/html";' . "\n\t" . 'boundary="' . $boundary3 . '"' . $line_term . $line_term . $line_term;
    $sending_message .= '--' . $boundary3 . $line_term;
    $sending_message .= 'Content-Type: text/html; charset=' . (preg_match($regexp, $html_evaluated) == 0 ? do_lang('charset', NULL, NULL, NULL, $lang) : 'us-ascii') . $line_term;
    // .'; name="message.html"'.	Outlook doesn't like: makes it think it's an attachment
    if (get_option('allow_ext_images') != '1') {
        $html_evaluated = preg_replace_callback('#<img\\s([^>]*)src="(http://[^"]*)"#U', '_mail_img_rep_callback', $html_evaluated);
        $matches = array();
        foreach (array('#<([^"<>]*\\s)style="([^"]*)"#', '#<style( [^<>]*)?' . '>(.*)</style>#Us') as $over) {
            $num_matches = preg_match_all($over, $html_evaluated, $matches);
            for ($i = 0; $i < $num_matches; $i++) {
                $altered_inner = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $matches[2][$i]);
                if ($matches[2][$i] != $altered_inner) {
                    $altered_outer = str_replace($matches[2][$i], $altered_inner, $matches[0][$i]);
                    $html_evaluated = str_replace($matches[0][$i], $altered_outer, $html_evaluated);
                }
            }
        }
    }
    if ($base64_encode) {
        $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term;
        $sending_message .= chunk_split(base64_encode(unixify_line_format($html_evaluated)) . $line_term, 76, $line_term);
    } else {
        $sending_message .= 'Content-Transfer-Encoding: 8bit' . $line_term . $line_term;
        // Requires RFC 1652
        $sending_message .= wordwrap(str_replace(chr(10), $line_term, unixify_line_format($html_evaluated)) . $line_term, 998, $line_term);
    }
    $total_filesize = 0;
    foreach ($CID_IMG_ATTACHMENT as $id => $img) {
        $sending_message .= '--' . $boundary3 . $line_term;
        $file_path_stub = convert_url_to_path($img);
        $mime_type = get_mime_type(get_file_extension($img));
        $filename = basename($img);
        if (!is_null($file_path_stub)) {
            $total_filesize += @filesize($file_path_stub);
            if ($total_filesize > 1024 * 1024 * 5) {
                continue;
            }
            // Too large to process into an email
            $file_contents = @file_get_contents($file_path_stub);
        } else {
            $file_contents = http_download_file($img, NULL, false);
            $total_filesize += strlen($file_contents);
            if ($total_filesize >= 1024 * 1024 * 5) {
                continue;
            }
            // Too large to process into an email
            if (!is_null($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'])) {
                $mime_type = $GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'];
            }
            if (!is_null($GLOBALS['HTTP_FILENAME'])) {
                $filename = $GLOBALS['HTTP_FILENAME'];
            }
        }
        $sending_message .= 'Content-Type: ' . str_replace("\r", '', str_replace("\n", '', $mime_type)) . $line_term;
        $sending_message .= 'Content-ID: <' . $id . '>' . $line_term;
        $sending_message .= 'Content-Disposition: inline; filename="' . str_replace("\r", '', str_replace("\n", '', $filename)) . '"' . $line_term;
        $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term;
        if (is_string($file_contents)) {
            $sending_message .= chunk_split(base64_encode($file_contents), 76, $line_term);
        }
    }
    $sending_message .= $line_term . '--' . $boundary3 . '--' . $line_term . $line_term;
    $sending_message .= $line_term . '--' . $boundary2 . '--' . $line_term . $line_term;
    // Attachments
    if (!is_null($attachments)) {
        foreach ($attachments as $path => $filename) {
            $sending_message .= '--' . $boundary . $line_term;
            $sending_message .= 'Content-Type: ' . get_mime_type(get_file_extension($filename)) . $line_term;
            // .'; name="'.str_replace("\r",'',str_replace("\n",'',$filename)).'"'   http://www.imc.org/ietf-822/old-archive2/msg02121.html
            $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term;
            $sending_message .= 'Content-Disposition: attachment; filename="' . str_replace("\r", '', str_replace("\n", '', $filename)) . '"' . $line_term . $line_term;
            if (strpos($path, '://') === false) {
                $sending_message .= chunk_split(base64_encode(file_get_contents($path)), 76, $line_term);
            } else {
                require_code('files');
                $sending_message .= chunk_split(base64_encode(http_download_file($path)), 76, $line_term);
            }
        }
        $sending_message .= $line_term . '--' . $boundary . '--' . $line_term;
    }
    // Support for SMTP sockets rather than PHP mail()
    $error = NULL;
    if (get_option('smtp_sockets_use') == '1') {
        $worked = false;
        $host = get_option('smtp_sockets_host');
        $port = intval(get_option('smtp_sockets_port'));
        $errno = 0;
        $errstr = '';
        foreach ($to_email as $i => $to) {
            $socket = @fsockopen($host, $port, $errno, $errstr, 30.0);
            if ($socket !== false) {
                $rcv = fread($socket, 1024);
                $base_url = parse_url(get_base_url());
                $domain = $base_url['host'];
                // Login if necessary
                $username = get_option('smtp_sockets_username');
                $password = get_option('smtp_sockets_password');
                if ($username != '') {
                    fwrite($socket, 'EHLO ' . $domain . "\r\n");
                    $rcv = fread($socket, 1024);
                    fwrite($socket, "AUTH LOGIN\r\n");
                    $rcv = fread($socket, 1024);
                    if (strtolower(substr($rcv, 0, 3)) == '334') {
                        fwrite($socket, base64_encode($username) . "\r\n");
                        $rcv = fread($socket, 1024);
                        if (strtolower(substr($rcv, 0, 3)) == '235' || strtolower(substr($rcv, 0, 3)) == '334') {
                            fwrite($socket, base64_encode($password) . "\r\n");
                            $rcv = fread($socket, 1024);
                            if (strtolower(substr($rcv, 0, 3)) == '235') {
                            } else {
                                $error = do_lang('MAIL_ERROR_CONNECT_PASSWORD') . ' (' . str_replace($password, '*', $rcv) . ')';
                            }
                        } else {
                            $error = do_lang('MAIL_ERROR_CONNECT_USERNAME') . ' (' . $rcv . ')';
                        }
                    } else {
                        $error = do_lang('MAIL_ERROR_CONNECT_AUTH') . ' (' . $rcv . ')';
                    }
                } else {
                    fwrite($socket, 'HELO ' . $domain . "\r\n");
                    $rcv = fread($socket, 1024);
                }
                if (is_null($error)) {
                    $smtp_from_address = get_option('smtp_from_address');
                    if ($smtp_from_address == '') {
                        $smtp_from_address = $from_email;
                    }
                    fwrite($socket, 'MAIL FROM:<' . $website_email . ">\r\n");
                    $rcv = fread($socket, 1024);
                    if (strtolower(substr($rcv, 0, 3)) == '250' || strtolower(substr($rcv, 0, 3)) == '251') {
                        $sent_one = false;
                        fwrite($socket, "RCPT TO:<" . $to_email[$i] . ">\r\n");
                        $rcv = fread($socket, 1024);
                        if (strtolower(substr($rcv, 0, 3)) != '250' && strtolower(substr($rcv, 0, 3)) != '251') {
                            $error = do_lang('MAIL_ERROR_TO') . ' (' . $rcv . ')' . ' ' . $to_email[$i];
                        } else {
                            $sent_one = true;
                        }
                        if ($sent_one) {
                            fwrite($socket, "DATA\r\n");
                            $rcv = fread($socket, 1024);
                            if (strtolower(substr($rcv, 0, 3)) == '354') {
                                $attractive_date = strftime('%d %B %Y  %H:%M:%S', time());
                                $_to_name = preg_replace('#@.*$#', '', is_array($to_name) ? $to_name[$i] : $to_name);
                                // preg_replace is because some servers may reject sending names that look like e-mail addresses. ocP tries this from recommend module.
                                if (count($to_email) == 1) {
                                    if ($_to_name == '') {
                                        fwrite($socket, 'To: ' . $to_email[$i] . "\r\n");
                                    } else {
                                        fwrite($socket, 'To: ' . $_to_name . ' <' . $to_email[$i] . '>' . "\r\n");
                                    }
                                } else {
                                    fwrite($socket, 'To: ' . $_to_name . "\r\n");
                                }
                                fwrite($socket, 'Subject: ' . $tightened_subject . "\r\n");
                                fwrite($socket, 'Date: ' . $attractive_date . "\r\n");
                                $headers = preg_replace('#^\\.#m', '..', $headers);
                                $sending_message = preg_replace('#^\\.#m', '..', $sending_message);
                                fwrite($socket, $headers . "\r\n");
                                fwrite($socket, $sending_message);
                                fwrite($socket, "\r\n.\r\n");
                                $rcv = fread($socket, 1024);
                                fwrite($socket, "QUIT\r\n");
                                $rcv = fread($socket, 1024);
                            } else {
                                $error = do_lang('MAIL_ERROR_DATA') . ' (' . $rcv . ')';
                            }
                        }
                    } else {
                        $error = do_lang('MAIL_ERROR_FROM') . ' (' . $rcv . ')';
                    }
                    if (@fwrite($socket, "RSET\r\n") === false) {
                        @fclose($socket);
                        $socket = NULL;
                    } else {
                        $rcv = fread($socket, 1024);
                    }
                }
                if (!is_null($socket)) {
                    fclose($socket);
                }
                if (is_null($error)) {
                    $worked = true;
                }
            } else {
                $error = do_lang('MAIL_ERROR_CONNECT', $host, strval($port));
            }
        }
    } else {
        $worked = false;
        foreach ($to_email as $i => $to) {
            //exit($headers.chr(10).$sending_message);
            $GLOBALS['SUPPRESS_ERROR_DEATH'] = true;
            $additional = '';
            if (get_option('enveloper_override') == '1') {
                $additional = '-f ' . $website_email;
            }
            $_to_name = preg_replace('#@.*$#', '', is_array($to_name) ? $to_name[$i] : $to_name);
            // preg_replace is because some servers may reject sending names that look like e-mail addresses. ocP tries this from recommend module.
            if ($_to_name == '' || strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
                $to_line = $to;
            } else {
                $to_line = '"' . $_to_name . '" <' . $to . '>';
            }
            //if (function_exists('mb_language')) mb_language('en');	Stop overridden mbstring mail function from messing and base64'ing stuff. Actually we don't need this as we make sure to pass through as headers with blank message, bypassing any filtering.
            if (str_replace(array('on', 'true', 'yes'), array('1', '1', '1'), strtolower(ini_get('safe_mode'))) == '1') {
                $worked = mail($to_line, $tightened_subject, $sending_message, $headers);
            } else {
                $worked = mail($to_line, $tightened_subject, $sending_message, $headers, $additional);
            }
            if (!$worked && isset($php_errormsg)) {
                $error = $php_errormsg;
            }
            $GLOBALS['SUPPRESS_ERROR_DEATH'] = false;
        }
    }
    if (!$worked) {
        $SENDING_MAIL = false;
        if (get_param_integer('keep_hide_mail_failure', 0) == 0) {
            require_code('site');
            attach_message(!is_null($error) ? make_string_tempcode($error) : do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address'))), 'warn');
        } else {
            return warn_screen(get_page_title('ERROR_OCCURRED'), do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address'))));
        }
    }
    $SENDING_MAIL = false;
    return NULL;
}
Beispiel #5
0
/**
 * Strip out any Comcode from this "plain text". Useful for semantic text is wanted but where Comcode is used as "the next best thing" we have.
 *
 * @param  string			Plain-text/Comcode
 * @return string			Purified plain-text
 */
function strip_comcode($text)
{
    require_code('mail');
    if (function_exists('comcode_to_clean_text')) {
        // For benefit of installer, which disables mail.php
        $text = comcode_to_clean_text($text);
    }
    global $VALID_COMCODE_TAGS;
    foreach (array_keys($VALID_COMCODE_TAGS) as $tag) {
        if ($tag == 'i') {
            $text = preg_replace('#\\[/?' . $tag . '\\]#', '', $text);
        } else {
            $text = preg_replace('#\\[/?' . $tag . '[^\\]]*\\]#', '', $text);
        }
    }
    return $text;
}