public static function actionParse() { $tolist = 'apple@beta.com, Michael Ferranti <*****@*****.**> "Jeff Reifman" <*****@*****.**>, <*****@*****.**>,jeff <*****@*****.**>'; //Yii::import('ext.Mail_RFC822'); include 'Mail/RFC822.php'; $parser = new Mail_RFC822(); // replace the backslash quotes $tolist = str_replace('\\"', '"', $tolist); // split the elements by line and by comma $to_email_array = preg_split("(\r|\n|,)", $tolist, -1, PREG_SPLIT_NO_EMPTY); $num_emails = count($to_email_array); echo $num_emails; for ($count = 0; $count < $num_emails && $count <= 500; $count++) { $toAddress = trim($to_email_array[$count]); if ($toAddress != '') { $addresses = $parser->parseAddressList('my group:' . $toAddress, 'bushsucks.com', false, true); var_dump($addresses); lb(); } //$toAddress=$addresses[0]->mailbox.'@'.$addresses[0]->host; //if ($this->utilObj->checkEmail($toAddress)) { // store it or send it or whatever you want to do //} } }
/** * アドレスの羅列から名前とメールアドレスの連想配列を取得する * * @param $str メールヘッダに含まれるメールアドレスの羅列 * @param メールアドレスの配列 */ static function get_mail_addr_array($str) { // メールアドレスリストとしてparse $mail_addr_obj_array = Mail_RFC822::parseAddressList($str); // メールアドレスを格納する配列 $mail_addr_array = array(); foreach ($mail_addr_obj_array as $mail_addr_obj) { // メールアドレス $mail_addr = $mail_addr_obj->mailbox . '@' . $mail_addr_obj->host; array_push($mail_addr_array, $mail_addr); } return $mail_addr_array; }
function valid_email($email) { $emailObjects = Mail_RFC822::parseAddressList($email); if (PEAR::isError($emailObjects)) { return false; } $emailObject = $emailObjects[0]; $email = $emailObject->mailbox . '@' . $emailObject->host; if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { return false; } else { return true; } }
function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (!isset($this) || !isset($this->mailRFC822)) { $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); return $obj->parseAddressList(); } if (isset($address)) { $this->address = $address; } if (isset($default_domain)) { $this->default_domain = $default_domain; } if (isset($nest_groups)) { $this->nestGroups = $nest_groups; } if (isset($validate)) { $this->validate = $validate; } if (isset($limit)) { $this->limit = $limit; } $this->structure = array(); $this->addresses = array(); $this->error = null; $this->index = null; $this->address = preg_replace('/\\r?\\n/', "\r\n", $this->address); $this->address = preg_replace('/\\r\\n(\\t| )+/', ' ', $this->address); while ($this->address = $this->_splitAddresses($this->address)) { } if ($this->address === false || isset($this->error)) { require_once 'PEAR.php'; return PEAR::raiseError($this->error); } foreach ($this->addresses as $address) { $valid = $this->_validateAddress($address); if ($valid === false || isset($this->error)) { require_once 'PEAR.php'; return PEAR::raiseError($this->error); } if (!$this->nestGroups) { $this->structure = array_merge($this->structure, $valid); } else { $this->structure[] = $valid; } } return $this->structure; }
function updateOrCreateEmail($part = '', $opts, $cm = false) { // DB_DataObject::debugLevel(1); $template_name = preg_replace('/\\.[a-z]+$/i', '', basename($opts['file'])); if (!file_exists($opts['file'])) { $this->jerr("file does not exist : " . $opts['file']); } if (!empty($opts['master']) && !file_exists($opts['master'])) { $this->jerr("master file does not exist : " . $opts['master']); } if (empty($cm)) { $cm = DB_dataObject::factory('core_email'); $ret = $cm->get('name', $template_name); if ($ret && empty($opts['update'])) { $this->jerr("use --update 1 to update the template.."); } } $mailtext = file_get_contents($opts['file']); if (!empty($opts['master'])) { $body = $mailtext; $mailtext = file_get_contents($opts['master']); $mailtext = str_replace('{outputBody():h}', $body, $mailtext); } require_once 'Mail/mimeDecode.php'; require_once 'Mail/RFC822.php'; $decoder = new Mail_mimeDecode($mailtext); $parts = $decoder->getSendArray(); if (is_a($parts, 'PEAR_Error')) { echo $parts->toString() . "\n"; exit; } $headers = $parts[1]; $from = new Mail_RFC822(); $from_str = $from->parseAddressList($headers['From']); $from_name = trim($from_str[0]->personal, '"'); $from_email = $from_str[0]->mailbox . '@' . $from_str[0]->host; if ($cm->id) { $cc = clone $cm; $cm->setFrom(array('bodytext' => $parts[2], 'updated_dt' => date('Y-m-d H:i:s'))); $cm->update($cc); } else { $cm->setFrom(array('from_name' => $from_name, 'from_email' => $from_email, 'subject' => $headers['Subject'], 'name' => $template_name, 'bodytext' => $parts[2], 'updated_dt' => date('Y-m-d H:i:s'), 'created_dt' => date('Y-m-d H:i:s'))); $cm->insert(); } return $cm; }
function register(&$data) { $session = Session::singletone(); if (empty($data['user_login'])) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Musisz podaæ login."); } if (empty($data['user_pass1']) || empty($data['user_pass2'])) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Has³o nie mo¿e byæ puste."); } if (empty($data['user_email'])) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Musisz podaæ email."); } $addr = Mail_RFC822::parseAddressList($data['user_email'], ""); if (empty($addr)) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Podany adres email jest nieprawid³owy."); } if ($data['user_pass1'] != $data['user_pass2']) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Podane has³a ró¿ni± siê"); } $user_login = trim($data['user_login']); $user_pass1 = $data['user_pass1']; $user_pass2 = $data['user_pass2']; $user_email = trim($data['user_email']); $this->_dbo = DB_DataObject::Factory('phph_users'); if (PEAR::isError($this->_dbo)) { throw new Exception2(_INTERNAL_ERROR, $this->_dbo->getMessage()); } $r = $this->_dbo->get('user_login', $user_login); if (PEAR::isError($r)) { throw new Exception2(_INTERNAL_ERROR, $r->getMessage()); } if ($r != 0) { throw new Exception2("Nie mo¿na zarejestrowaæ konta", "Podany login jest ju¿ zajêty."); } $this->_dbo->user_login = $user_login; $this->_dbo->user_pass = md5($user_pass1); $this->_dbo->user_email = $user_email; $this->_dbo->user_registered = time(); $this->_dbo->user_activation = md5(uniqid($user_login)); $r = $this->_dbo->insert(); if (PEAR::isError($r)) { throw new Exception2(_INTERNAL_ERROR, $r->getMessage()); } return $r; }
function valid_email($email) { $emailObjects = Mail_RFC822::parseAddressList($email); if (PEAR::isError($emailObjects)) { return false; } // Get the mailbox and host parts of the email object $mailbox = $emailObjects[0]->mailbox; $host = $emailObjects[0]->host; // Make sure the mailbox and host parts aren't too long if (strlen($mailbox) > 64) { return false; } if (strlen($host) > 255) { return false; } // Validate the mailbox $atom = '[[:alnum:]_!#$%&\'*+\\/=?^`{|}~-]+'; $dotatom = '(\\.' . $atom . ')*'; $address = '(^' . $atom . $dotatom . '$)'; $char = '([^\\\\"])'; $esc = '(\\\\[\\\\"])'; $text = '(' . $char . '|' . $esc . ')+'; $quoted = '(^"' . $text . '"$)'; $localPart = '/' . $address . '|' . $quoted . '/'; $localMatch = preg_match($localPart, $mailbox); if ($localMatch === false || $localMatch != 1) { return false; } // Validate the host $hostname = '([[:alnum:]]([-[:alnum:]]{0,62}[[:alnum:]])?)'; $hostnames = '(' . $hostname . '(\\.' . $hostname . ')*)'; $top = '\\.[[:alnum:]]{2,6}'; $domainPart = '/^' . $hostnames . $top . '$/'; $domainMatch = preg_match($domainPart, $host); if ($domainMatch === false || $domainMatch != 1) { return false; } return true; }
function getCcAddressList() { return $this->struct->headers['cc'] ? Mail_RFC822::parseAddressList($this->struct->headers['cc']) : null; }
} //exit(); //get all the destined addresses from to,cc,bcc into the array $var_toaddress //do check for duplicates and insert all valid addresses to $var_toaddress array $var_toaddress = array(); for ($j = 0; $j < 3; $j++) { $structure = ""; switch ($j) { case 0: $structure = Mail_RFC822::parseAddressList($mimedecoder->_mailheader->_headerto, 'example.com', true); break; case 1: $structure = Mail_RFC822::parseAddressList($mimedecoder->_mailheader->_headercc, 'example.com', true); break; case 2: $structure = Mail_RFC822::parseAddressList($mimedecoder->_mailheader->_headerbcc, 'example.com', true); break; } $cnt = count($structure); for ($i = 0; $i < $cnt; $i++) { $var_temp = $structure[$i]->mailbox . "@" . strtolower($structure[$i]->host); if ($structure[$i]->mailbox != "" && !isset($var_toaddress[$var_temp])) { $var_toaddress[$var_temp] = $structure[$i]->mailbox; } } } //print_r($var_toaddress); /* *Case-sensitivity for isset - it is case sensitive *so same email addresses with different case may create two tickets *se we convert all domain names to lower case here
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { debugLog("IMAP-SendMail: " . $rfc822 . "for: {$forward} reply: {$reply} parent: {$parent}"); $mobj = new Mail_mimeDecode($rfc822); $message = $mobj->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\n", 'charset' => 'utf-8')); $toaddr = $ccaddr = $bccaddr = ""; if (isset($message->headers["to"])) { $toaddr = $this->parseAddr(Mail_RFC822::parseAddressList($message->headers["to"])); } if (isset($message->headers["cc"])) { $ccaddr = $this->parseAddr(Mail_RFC822::parseAddressList($message->headers["cc"])); } if (isset($message->headers["bcc"])) { $bccaddr = $this->parseAddr(Mail_RFC822::parseAddressList($message->headers["bcc"])); } // save some headers when forwarding mails (content type & transfer-encoding) $headers = ""; $forward_h_ct = ""; $forward_h_cte = ""; $use_orgbody = false; // clean up the transmitted headers // remove default headers because we are using imap_mail $changedfrom = false; $returnPathSet = false; $body_base64 = false; $org_charset = ""; foreach ($message->headers as $k => $v) { if ($k == "subject" || $k == "to" || $k == "cc" || $k == "bcc") { continue; } if ($k == "content-type") { // save the original content-type header for the body part when forwarding if ($forward) { $forward_h_ct = $v; continue; } // set charset always to utf-8 $org_charset = $v; $v = preg_replace("/charset=([A-Za-z0-9-\"']+)/", "charset=\"utf-8\"", $v); } if ($k == "content-transfer-encoding") { // if the content was base64 encoded, encode the body again when sending if (trim($v) == "base64") { $body_base64 = true; } // save the original encoding header for the body part when forwarding if ($forward) { $forward_h_cte = $v; continue; } } // if the message is a multipart message, then we should use the sent body if (!$forward && $k == "content-type" && preg_match("/multipart/i", $v)) { $use_orgbody = true; } // check if "from"-header is set if ($k == "from" && !trim($v) && IMAP_DEFAULTFROM) { $changedfrom = true; if (IMAP_DEFAULTFROM == 'username') { $v = $this->_username; } else { if (IMAP_DEFAULTFROM == 'domain') { $v = $this->_domain; } else { $v = $this->_username . IMAP_DEFAULTFROM; } } } // check if "Return-Path"-header is set if ($k == "return-path") { $returnPathSet = true; if (!trim($v) && IMAP_DEFAULTFROM) { if (IMAP_DEFAULTFROM == 'username') { $v = $this->_username; } else { if (IMAP_DEFAULTFROM == 'domain') { $v = $this->_domain; } else { $v = $this->_username . IMAP_DEFAULTFROM; } } } } // all other headers stay if ($headers) { $headers .= "\n"; } $headers .= ucfirst($k) . ": " . $v; } // set "From" header if not set on the device if (IMAP_DEFAULTFROM && !$changedfrom) { if (IMAP_DEFAULTFROM == 'username') { $v = $this->_username; } else { if (IMAP_DEFAULTFROM == 'domain') { $v = $this->_domain; } else { $v = $this->_username . IMAP_DEFAULTFROM; } } if ($headers) { $headers .= "\n"; } $headers .= 'From: ' . $v; } // set "Return-Path" header if not set on the device if (IMAP_DEFAULTFROM && !$returnPathSet) { if (IMAP_DEFAULTFROM == 'username') { $v = $this->_username; } else { if (IMAP_DEFAULTFROM == 'domain') { $v = $this->_domain; } else { $v = $this->_username . IMAP_DEFAULTFROM; } } if ($headers) { $headers .= "\n"; } $headers .= 'Return-Path: ' . $v; } // if this is a multipart message with a boundary, we must use the original body if ($use_orgbody) { list(, $body) = $mobj->_splitBodyHeader($rfc822); } else { $body = $this->getBody($message); } // reply if (isset($reply) && isset($parent) && $reply && $parent) { $this->imap_reopenFolder($parent); // receive entire mail (header + body) to decode body correctly $origmail = @imap_fetchheader($this->_mbox, $reply, FT_PREFETCHTEXT | FT_UID) . @imap_body($this->_mbox, $reply, FT_PEEK | FT_UID); $mobj2 = new Mail_mimeDecode($origmail); // receive only body $body .= $this->getBody($mobj2->decode(array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $origmail, 'crlf' => "\n", 'charset' => 'utf-8'))); // unset mimedecoder & origmail - free memory unset($mobj2); unset($origmail); } // encode the body to base64 if it was sent originally in base64 by the pda // the encoded body is included in the forward if ($body_base64) { $body = base64_encode($body); } // forward if (isset($forward) && isset($parent) && $forward && $parent) { $this->imap_reopenFolder($parent); // receive entire mail (header + body) $origmail = @imap_fetchheader($this->_mbox, $forward, FT_PREFETCHTEXT | FT_UID) . @imap_body($this->_mbox, $forward, FT_PEEK | FT_UID); // build a new mime message, forward entire old mail as file list($aheader, $body) = $this->mail_attach("forwarded_message.eml", strlen($origmail), $origmail, $body, $forward_h_ct, $forward_h_cte); // unset origmail - free memory unset($origmail); // add boundary headers $headers .= "\n" . $aheader; } //advanced debugging //debugLog("IMAP-SendMail: parsed message: ". print_r($message,1)); //debugLog("IMAP-SendMail: headers: $headers"); //debugLog("IMAP-SendMail: subject: {$message->headers["subject"]}"); //debugLog("IMAP-SendMail: body: $body"); $send = @imap_mail($toaddr, $message->headers["subject"], $body, $headers, $ccaddr, $bccaddr); // email sent? if (!$send) { debugLog("The email could not be sent. Last-IMAP-error: " . imap_last_error()); } // add message to the sent folder // build complete headers $cheaders = "To: " . $toaddr . "\n"; $cheaders .= "Subject: " . $message->headers["subject"] . "\n"; $cheaders .= "Cc: " . $ccaddr . "\n"; $cheaders .= $headers; $asf = false; if ($this->_sentID) { $asf = $this->addSentMessage($this->_sentID, $cheaders, $body); } else { if (IMAP_SENTFOLDER) { $asf = $this->addSentMessage(IMAP_SENTFOLDER, $cheaders, $body); debugLog("IMAP-SendMail: Outgoing mail saved in configured 'Sent' folder '" . IMAP_SENTFOLDER . "': " . ($asf ? "success" : "failed")); } else { debugLog("IMAP-SendMail: No Sent mailbox set"); if ($this->addSentMessage("INBOX.Sent", $cheaders, $body)) { debugLog("IMAP-SendMail: Outgoing mail saved in 'INBOX.Sent'"); $asf = true; } else { if ($this->addSentMessage("Sent", $cheaders, $body)) { debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent'"); $asf = true; } else { if ($this->addSentMessage("Sent Items", $cheaders, $body)) { debugLog("IMAP-SendMail: Outgoing mail saved in 'Sent Items'"); $asf = true; } } } } } // unset mimedecoder - free memory unset($mobj); return $send && $asf; }
/** * Implements Mail_mail::send() function using php's built-in mail() * command. * * @param mixed $recipients Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. This may contain recipients not * specified in the headers, for Bcc:, resending * messages, etc. * * @param array $headers The array of headers to send with the mail, in an * associative array, where the array key is the * header name (ie, 'Subject'), and the array value * is the header value (ie, 'test'). The header * produced from those values would be 'Subject: * test'. * * @param string $body The full text of the message body, including any * Mime parts, etc. * * @return mixed Returns true on success, or a PEAR_Error * containing a descriptive error message on * failure. * @access public */ function send($recipients, $headers, $body) { // if we're passed an array of recipients, implode it. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // get the Subject out of the headers array so that we can // pass it as a seperate argument to mail(). $subject = ''; if (isset($headers['Subject'])) { $subject = $headers['Subject']; unset($headers['Subject']); } // flatten the headers out. list(, $text_headers) = Mail::prepareHeaders($headers); include_once 'Mail/RFC822.php'; $addresses = Mail_RFC822::parseAddressList($headers['From'], 'localhost', false); $from = $addresses[0]->mailbox . '@' . $addresses[0]->host; return mail($recipients, $subject, $body, $text_headers, "-f" . $from . " " . $this->_params); }
/** * Take a set of recipients and parse them, returning an array of * bare addresses (forward paths) that can be passed to sendmail * or an smtp server with the rcpt to: command. * * @param mixed Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. * * @return mixed An array of forward paths (bare addresses) or a PEAR_Error * object if the address list could not be parsed. * @access private */ function parseRecipients($recipients) { // if we're passed an array, assume addresses are valid and // implode them before parsing. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // Parse recipients, leaving out all personal info. This is // for smtp recipients, etc. All relevant personal information // should already be in the headers. $parser = new Mail_RFC822(); $addresses = $parser->parseAddressList($recipients, 'localhost', false); // If parseAddressList() returned a PEAR_Error object, just return it. //if (is_a($addresses, 'PEAR_Error')) { if ($addresses === false) { return $addresses; } $recipients = array(); if (is_array($addresses)) { foreach ($addresses as $ob) { $recipients[] = $ob->mailbox . '@' . $ob->host; } } // Remove duplicated $recipients = array_unique($recipients); return $recipients; }
function plugin_forumml_show_message($p, $hp, $msg, $id_parent, $purgeCache) { $body = $msg['body']; $request = HTTPRequest::instance(); // Is "ready to display" body already in cache or not $bodyIsCached = false; if (!empty($msg['cached_html']) && !$purgeCache) { $bodyIsCached = true; } if (PEAR::isError($from_info = Mail_RFC822::parseAddressList($msg['sender'], $GLOBALS['sys_default_domain'])) || !isset($from_info[0]) || !$from_info[0]->personal) { $from_info = $hp->purify($msg['sender'], CODENDI_PURIFIER_CONVERT_HTML); } else { $from_info = '<abbr title="' . $hp->purify($from_info[0]->mailbox . '@' . $from_info[0]->host, CODENDI_PURIFIER_CONVERT_HTML) . '">' . $hp->purify($from_info[0]->personal, CODENDI_PURIFIER_CONVERT_HTML) . '</abbr>'; } echo '<div class="plugin_forumml_message">'; // specific thread echo '<div class="plugin_forumml_message_header boxitemalt" id="plugin_forumml_message_' . $msg['id_message'] . '">'; echo '<div class="plugin_forumml_message_header_subject">' . $hp->purify($msg['subject'], CODENDI_PURIFIER_CONVERT_HTML) . '</div>'; echo '<a href="#' . $msg['id_message'] . '" title="message #' . $msg['id_message'] . '">'; echo '<img src="' . $p->getThemePath() . '/images/ic/comment.png" id="' . $msg['id_message'] . '" style="vertical-align:middle" alt="#' . $msg['id_message'] . '" />'; echo '</a>'; echo ' <span class="plugin_forumml_message_header_from">' . $from_info . '</span>'; echo ' <span class="plugin_forumml_message_header_date">' . $GLOBALS['Language']->getText('plugin_forumml', 'show_message_date', array($msg['date'])) . '</span>'; echo ' <a href="#" id="plugin_forumml_toogle_msg_' . $msg['id_message'] . '" class="plugin_forumml_toggle_font">' . $GLOBALS['Language']->getText('plugin_forumml', 'toggle_font') . '</a>'; // get CC $cc = trim($msg['cc']); if ($cc) { if (PEAR::isError($cc_info = Mail_RFC822::parseAddressList($cc, $GLOBALS['sys_default_domain']))) { $ccs = $hp->purify($cc, CODENDI_PURIFIER_CONVERT_HTML); } else { $ccs = array(); foreach ($cc_info as $c) { if (!$c->personal) { $ccs[] = $hp->purify($c->mailbox . '@' . $c->host, CODENDI_PURIFIER_CONVERT_HTML); } else { $ccs[] = '<abbr title="' . $hp->purify($c->mailbox . '@' . $c->host, CODENDI_PURIFIER_CONVERT_HTML) . '">' . $hp->purify($c->personal, CODENDI_PURIFIER_CONVERT_HTML) . '</abbr>'; } } $ccs = implode(', ', $ccs); } print '<div class="plugin_forumml_message_header_cc">' . $GLOBALS['Language']->getText('plugin_forumml', 'show_message_cc') . ' ' . $ccs . '</div>'; } // Message content if (strpos($msg['content_type'], 'multipart/') !== false) { $content_type = $msg['msg_type']; } else { $content_type = $msg['content_type']; } $is_html = strpos($content_type, "text/html") !== false; // get attached files if (count($msg['attachments'])) { print '<div class="plugin_forumml_message_header_attachments">'; $first = true; foreach ($msg['attachments'] as $attachment) { // Special case, this is an HTML email if (preg_match('/.html$/i', $attachment['file_name'])) { // By default, the first html attachment replaces the default body (text) if ($first) { if (!$bodyIsCached && is_file($attachment['file_path'])) { $body = file_get_contents($attachment['file_path']); // Make sure that the body is utf8 if (!mb_detect_encoding($body, 'UTF-8', true)) { $body = mb_convert_encoding($body, 'UTF-8'); } $is_html = true; } continue; } else { $flink = $attachment['file_name']; } } else { $flink = $attachment['file_name']; } if (!$first) { echo ', '; } echo "<img src='" . $p->getThemePath() . "/images/ic/attach.png'/> <a href='upload.php?group_id=" . $request->get('group_id') . "&list=" . $request->get('list') . "&id=" . $attachment['id_attachment'] . "&topic=" . $id_parent . "'>" . $flink . "</a>"; $first = false; } echo '</div>'; } echo '</div>'; print '<div id="plugin_forumml_message_content_' . $msg['id_message'] . '" class="plugin_forumml_message_content_std">'; $body = str_replace("\r\n", "\n", $body); // If there is no cached html of if user requested to regenerate the cache, do it, otherwise use cached HTML. if (!$bodyIsCached) { // Purify message body, according to the content-type if ($is_html) { // Update attachment links $body = plugin_forumml_replace_attachment($msg['id_message'], $request->get('group_id'), $request->get('list'), $id_parent, $body); // Use CODENDI_PURIFIER_FULL for html mails $msg['cached_html'] = $hp->purify($body, CODENDI_PURIFIER_FULL, $request->get('group_id')); } else { // CODENDI_PURIFIER_FORUMML level : no basic html markups, no forms, no javascript, // Allowed: url + automagic links + <blockquote> $purified_body = $hp->purify($body, CODENDI_PURIFIER_CONVERT_HTML, $request->get('group_id')); $purified_body = str_replace('>', '>', $purified_body); $tab_body = ''; $level = 0; $current_level = 0; $search_for_quotes = false; $maxi = strlen($purified_body); for ($i = 0; $i < $maxi; ++$i) { if ($search_for_quotes) { if ($purified_body[$i] == ">") { ++$current_level; if ($level < $current_level) { $tab_body .= '<blockquote class="grep">'; ++$level; } } else { $search_for_quotes = false; if ($level > $current_level) { $tab_body .= '</blockquote>'; --$level; } if ($purified_body[$i] == "\n" && $i < $maxi - 1) { $search_for_quotes = true; $current_level = 0; } $tab_body .= $purified_body[$i]; } } else { if ($purified_body[$i] == "\n" && $i < $maxi - 1) { $search_for_quotes = true; $current_level = 0; } $tab_body .= $purified_body[$i]; } } $purified_body = str_replace('>', '>', $purified_body); $msg['cached_html'] = nl2br($tab_body); } db_query('UPDATE plugin_forumml_message SET cached_html="' . db_es($msg['cached_html']) . '" WHERE id_message=' . $msg['id_message']); } echo $msg['cached_html']; echo '</div>'; // Reply echo '<div class="plugin_forumml_message_footer">'; // If you click on 'Reply', load reply form $vMess = new Valid_UInt('id_mess'); $vMess->required(); if ($request->valid($vMess) && $request->get('id_mess') == $msg['id_message']) { $vReply = new Valid_WhiteList('reply', array(0, 1)); $vReply->required(); if ($request->valid($vReply) && $request->get('reply') == 1) { if ($is_html) { $body = $hp->purify($body, CODENDI_PURIFIER_STRIP_HTML); } else { $body = $hp->purify($body, CODENDI_PURIFIER_CONVERT_HTML); } plugin_forumml_reply($hp, $msg['subject'], $msg['id_message'], $id_parent, $body, $msg['sender']); } } else { print "<a href='message.php?group_id=" . $request->get('group_id') . "&topic=" . $id_parent . "&id_mess=" . $msg['id_message'] . "&reply=1&list=" . $request->get('list') . "#reply-" . $msg['id_message'] . "'>\n <img src='" . $p->getThemePath() . "/images/ic/comment_add.png'/>\n " . $GLOBALS['Language']->getText('plugin_forumml', 'reply') . "\n </a>"; } echo '</div>'; echo '</div>'; }
/** * Sends the mail. * * @param array $recipients Array of receipients to send the mail to * @param string $type How to send the mail ('mail' or 'sendmail' or 'smtp') * @return mixed */ public function send($recipients, $type = 'mail') { if (!defined('CRLF')) { $this->setCRLF(($type == 'mail' or $type == 'sendmail') ? "\n" : "\r\n"); } $this->build(); switch ($type) { case 'mail': $subject = ''; if (!empty($this->headers['Subject'])) { $subject = $this->encodeHeader($this->headers['Subject'], $this->build_params['head_charset']); unset($this->headers['Subject']); } // Get flat representation of headers foreach ($this->headers as $name => $value) { $headers[] = $name . ': ' . $this->encodeHeader($value, $this->build_params['head_charset']); } $to = $this->encodeHeader(implode(', ', $recipients), $this->build_params['head_charset']); if (!empty($this->return_path)) { $result = mail($to, $subject, $this->output, implode(CRLF, $headers), '-f' . $this->return_path); } else { $result = mail($to, $subject, $this->output, implode(CRLF, $headers)); } // Reset the subject in case mail is resent if ($subject !== '') { $this->headers['Subject'] = $subject; } // Return return $result; break; case 'sendmail': // Get flat representation of headers foreach ($this->headers as $name => $value) { $headers[] = $name . ': ' . $this->encodeHeader($value, $this->build_params['head_charset']); } // Encode To: $headers[] = 'To: ' . $this->encodeHeader(implode(', ', $recipients), $this->build_params['head_charset']); // Get return path arg for sendmail command if necessary $returnPath = ''; if (!empty($this->return_path)) { $returnPath = '-f' . $this->return_path; } $pipe = popen($this->sendmail_path . " " . $returnPath, 'w'); $bytes = fputs($pipe, implode(CRLF, $headers) . CRLF . CRLF . $this->output); $r = pclose($pipe); return $r; break; case 'smtp': require_once dirname(__FILE__) . '/smtp.php'; require_once dirname(__FILE__) . '/RFC822.php'; $smtp =& smtp::connect($this->smtp_params); // Parse recipients argument for internet addresses foreach ($recipients as $recipient) { $addresses = Mail_RFC822::parseAddressList($recipient, $this->smtp_params['helo'], null, false); foreach ($addresses as $address) { $smtp_recipients[] = sprintf('%s@%s', $address->mailbox, $address->host); } } unset($addresses); // These are reused unset($address); // These are reused // Get flat representation of headers, parsing // Cc and Bcc as we go foreach ($this->headers as $name => $value) { if ($name == 'Cc' or $name == 'Bcc') { $addresses = Mail_RFC822::parseAddressList($value, $this->smtp_params['helo'], null, false); foreach ($addresses as $address) { $smtp_recipients[] = sprintf('%s@%s', $address->mailbox, $address->host); } } if ($name == 'Bcc') { continue; } $headers[] = $name . ': ' . $this->encodeHeader($value, $this->build_params['head_charset']); } // Add To header based on $recipients argument $headers[] = 'To: ' . $this->encodeHeader(implode(', ', $recipients), $this->build_params['head_charset']); // Add headers to send_params $send_params['headers'] = $headers; $send_params['recipients'] = array_values(array_unique($smtp_recipients)); $send_params['body'] = $this->output; // Setup return path if (isset($this->return_path)) { $send_params['from'] = $this->return_path; } elseif (!empty($this->headers['From'])) { $from = Mail_RFC822::parseAddressList($this->headers['From']); $send_params['from'] = sprintf('%s@%s', $from[0]->mailbox, $from[0]->host); } else { $send_params['from'] = 'postmaster@' . $this->smtp_params['helo']; } // Send it if (!$smtp->send($send_params)) { $this->errors = $smtp->getErrors(); return false; } return true; break; } }
/** * Starts the whole process. The address must either be set here * or when creating the object. One or the other. * * @access public * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. * * @return array A structured array of addresses. */ function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (!isset($this->mailRFC822)) { $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); return $obj->parseAddressList(); } if (isset($address)) { $this->address = $address; } if (isset($default_domain)) { $this->default_domain = $default_domain; } if (isset($nest_groups)) { $this->nestGroups = $nest_groups; } if (isset($validate)) { $this->validate = $validate; } if (isset($limit)) { $this->limit = $limit; } $this->structure = array(); $this->addresses = array(); $this->error = null; $this->index = null; while ($this->address = $this->_splitAddresses($this->address)) { continue; } if ($this->address === false || isset($this->error)) { return $this->raiseError($this->error); } // Reset timer since large amounts of addresses can take a long time to // get here set_time_limit(30); // Loop through all the addresses for ($i = 0; $i < count($this->addresses); $i++) { if (($return = $this->_validateAddress($this->addresses[$i])) === false || isset($this->error)) { return $this->raiseError($this->error); } if (!$this->nestGroups) { $this->structure = array_merge($this->structure, $return); } else { $this->structure[] = $return; } } return $this->structure; }
/** * Take a set of recipients and parse them, returning an array of * bare addresses (forward paths) that can be passed to sendmail * or an smtp server with the rcpt to: command. * * @param mixed Either a comma-seperated list of recipients * (RFC822 compliant), or an array of recipients, * each RFC822 valid. * * @return array An array of forward paths (bare addresses). * @access private */ function parseRecipients($recipients) { include_once 'Mail/RFC822.php'; // if we're passed an array, assume addresses are valid and // implode them before parsing. if (is_array($recipients)) { $recipients = implode(', ', $recipients); } // Parse recipients, leaving out all personal info. This is // for smtp recipients, etc. All relevant personal information // should already be in the headers. $addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false); $recipients = array(); if (is_array($addresses)) { foreach ($addresses as $ob) { $recipients[] = $ob->mailbox . '@' . $ob->host; } } return $recipients; }
/** * Returns the actual SyncXXX object type. * * @param string $folderid id of the parent folder * @param string $id id of the message * @param ContentParameters $contentparameters parameters of the requested message (truncation, mimesupport etc) * * @access public * @return object/false false if the message could not be retrieved */ public function GetMessage($folderid, $id, $contentparameters) { $truncsize = Utils::GetTruncSize($contentparameters->GetTruncation()); $mimesupport = $contentparameters->GetMimeSupport(); $bodypreference = $contentparameters->GetBodyPreference(); /* fmbiete's contribution r1528, ZP-320 */ ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage('%s','%s')", $folderid, $id)); $folderImapid = $this->getImapIdFromFolderId($folderid); // Get flags, etc $stat = $this->StatMessage($folderid, $id); if ($stat) { $this->imap_reopenFolder($folderImapid); $mail = @imap_fetchheader($this->mbox, $id, FT_UID) . @imap_body($this->mbox, $id, FT_PEEK | FT_UID); $mobj = new Mail_mimeDecode($mail); $message = $mobj->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8')); /* BEGIN fmbiete's contribution r1528, ZP-320 */ $output = new SyncMail(); //Select body type preference $bpReturnType = SYNC_BODYPREFERENCE_PLAIN; if ($bodypreference !== false) { $bpReturnType = Utils::GetBodyPreferenceBestMatch($bodypreference); // changed by mku ZP-330 } ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage - getBodyPreferenceBestMatch: %d", $bpReturnType)); //Get body data $this->getBodyRecursive($message, "plain", $plainBody); $this->getBodyRecursive($message, "html", $htmlBody); if ($plainBody == "") { $plainBody = Utils::ConvertHtmlToText($htmlBody); } $htmlBody = str_replace("\n", "\r\n", str_replace("\r", "", $htmlBody)); $plainBody = str_replace("\n", "\r\n", str_replace("\r", "", $plainBody)); if (Request::GetProtocolVersion() >= 12.0) { $output->asbody = new SyncBaseBody(); switch ($bpReturnType) { case SYNC_BODYPREFERENCE_PLAIN: $output->asbody->data = $plainBody; break; case SYNC_BODYPREFERENCE_HTML: if ($htmlBody == "") { $output->asbody->data = $plainBody; $bpReturnType = SYNC_BODYPREFERENCE_PLAIN; } else { $output->asbody->data = $htmlBody; } break; case SYNC_BODYPREFERENCE_MIME: //We don't need to create a new MIME mail, we already have one!! $output->asbody->data = $mail; break; case SYNC_BODYPREFERENCE_RTF: ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->GetMessage RTF Format NOT CHECKED"); $output->asbody->data = base64_encode($plainBody); break; } // truncate body, if requested if (strlen($output->asbody->data) > $truncsize) { $output->asbody->data = Utils::Utf8_truncate($output->asbody->data, $truncsize); $output->asbody->truncated = 1; } $output->asbody->type = $bpReturnType; $output->nativebodytype = $bpReturnType; $output->asbody->estimatedDataSize = strlen($output->asbody->data); $bpo = $contentparameters->BodyPreference($output->asbody->type); if (Request::GetProtocolVersion() >= 14.0 && $bpo->GetPreview()) { $output->asbody->preview = Utils::Utf8_truncate(Utils::ConvertHtmlToText($plainBody), $bpo->GetPreview()); } else { $output->asbody->truncated = 0; } } else { // ASV_2.5 $output->bodytruncated = 0; /* BEGIN fmbiete's contribution r1528, ZP-320 */ if ($bpReturnType == SYNC_BODYPREFERENCE_MIME) { if (strlen($mail) > $truncsize) { $output->mimedata = Utils::Utf8_truncate($mail, $truncsize); $output->mimetruncated = 1; } else { $output->mimetruncated = 0; $output->mimedata = $mail; } $output->mimesize = strlen($output->mimedata); } else { // truncate body, if requested if (strlen($plainBody) > $truncsize) { $output->body = Utils::Utf8_truncate($plainBody, $truncsize); $output->bodytruncated = 1; } else { $output->body = $plainBody; $output->bodytruncated = 0; } $output->bodysize = strlen($output->body); } /* END fmbiete's contribution r1528, ZP-320 */ } $output->datereceived = isset($message->headers["date"]) ? $this->cleanupDate($message->headers["date"]) : null; $output->messageclass = "IPM.Note"; $output->subject = isset($message->headers["subject"]) ? $message->headers["subject"] : ""; $output->read = $stat["flags"]; $output->from = isset($message->headers["from"]) ? $message->headers["from"] : null; /* BEGIN fmbiete's contribution r1528, ZP-320 */ if (isset($message->headers["thread-topic"])) { $output->threadtopic = $message->headers["thread-topic"]; } // Language Code Page ID: http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx $output->internetcpid = INTERNET_CPID_UTF8; if (Request::GetProtocolVersion() >= 12.0) { $output->contentclass = "urn:content-classes:message"; } /* END fmbiete's contribution r1528, ZP-320 */ $Mail_RFC822 = new Mail_RFC822(); $toaddr = $ccaddr = $replytoaddr = array(); if (isset($message->headers["to"])) { $toaddr = $Mail_RFC822->parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = $Mail_RFC822->parseAddressList($message->headers["cc"]); } if (isset($message->headers["reply_to"])) { $replytoaddr = $Mail_RFC822->parseAddressList($message->headers["reply_to"]); } $output->to = array(); $output->cc = array(); $output->reply_to = array(); foreach (array("to" => $toaddr, "cc" => $ccaddr, "reply_to" => $replytoaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $address = $addr->mailbox . "@" . $addr->host; $name = $addr->personal; if (!isset($output->displayto) && $name != "") { $output->displayto = $name; } if ($name == "" || $name == $address) { $fulladdr = w2u($address); } else { if (substr($name, 0, 1) != '"' && substr($name, -1) != '"') { $fulladdr = "\"" . w2u($name) . "\" <" . w2u($address) . ">"; } else { $fulladdr = w2u($name) . " <" . w2u($address) . ">"; } } array_push($output->{$type}, $fulladdr); } } // convert mime-importance to AS-importance if (isset($message->headers["x-priority"])) { $mimeImportance = preg_replace("/\\D+/", "", $message->headers["x-priority"]); //MAIL 1 - most important, 3 - normal, 5 - lowest //AS 0 - low, 1 - normal, 2 - important if ($mimeImportance > 3) { $output->importance = 0; } if ($mimeImportance == 3) { $output->importance = 1; } if ($mimeImportance < 3) { $output->importance = 2; } } else { /* fmbiete's contribution r1528, ZP-320 */ $output->importance = 1; } // Attachments are not needed for MIME messages if ($bpReturnType != SYNC_BODYPREFERENCE_MIME && isset($message->parts)) { $mparts = $message->parts; for ($i = 0; $i < count($mparts); $i++) { $part = $mparts[$i]; //recursively add parts if ($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative" || $part->ctype_secondary == "related")) { foreach ($part->parts as $spart) { $mparts[] = $spart; } continue; } //add part as attachment if it's disposition indicates so or if it is not a text part if (isset($part->disposition) && ($part->disposition == "attachment" || $part->disposition == "inline") || isset($part->ctype_primary) && $part->ctype_primary != "text") { if (isset($part->d_parameters['filename'])) { $attname = $part->d_parameters['filename']; } else { if (isset($part->ctype_parameters['name'])) { $attname = $part->ctype_parameters['name']; } else { if (isset($part->headers['content-description'])) { $attname = $part->headers['content-description']; } else { $attname = "unknown attachment"; } } } /* BEGIN fmbiete's contribution r1528, ZP-320 */ if (Request::GetProtocolVersion() >= 12.0) { if (!isset($output->asattachments) || !is_array($output->asattachments)) { $output->asattachments = array(); } $attachment = new SyncBaseAttachment(); $attachment->estimatedDataSize = isset($part->d_parameters['size']) ? $part->d_parameters['size'] : isset($part->body) ? strlen($part->body) : 0; $attachment->displayname = $attname; $attachment->filereference = $folderid . ":" . $id . ":" . $i; $attachment->method = 1; //Normal attachment $attachment->contentid = isset($part->headers['content-id']) ? str_replace("<", "", str_replace(">", "", $part->headers['content-id'])) : ""; if (isset($part->disposition) && $part->disposition == "inline") { $attachment->isinline = 1; } else { $attachment->isinline = 0; } array_push($output->asattachments, $attachment); } else { //ASV_2.5 if (!isset($output->attachments) || !is_array($output->attachments)) { $output->attachments = array(); } $attachment = new SyncAttachment(); $attachment->attsize = isset($part->d_parameters['size']) ? $part->d_parameters['size'] : isset($part->body) ? strlen($part->body) : 0; $attachment->displayname = $attname; $attachment->attname = $folderid . ":" . $id . ":" . $i; $attachment->attmethod = 1; $attachment->attoid = isset($part->headers['content-id']) ? str_replace("<", "", str_replace(">", "", $part->headers['content-id'])) : ""; array_push($output->attachments, $attachment); } /* END fmbiete's contribution r1528, ZP-320 */ } } } // unset mimedecoder & mail unset($mobj); unset($mail); return $output; } return false; }
/** * Processes a response to a meeting request. * * @param string $requestid id of the object containing the request * @param string $folderid id of the parent folder of $requestid * @param string $response * * @access public * @return string id of the created/updated calendar obj * @throws StatusException */ public function MeetingResponse($requestid, $folderid, $response) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->MeetingResponse('%s','%s','%s')", $requestid, $folderid, $response)); $folderImapid = $this->getImapIdFromFolderId($folderid); $this->imap_reopen_folder($folderImapid); $mail = @imap_fetchheader($this->mbox, $requestid, FT_UID) . @imap_body($this->mbox, $requestid, FT_PEEK | FT_UID); if (empty($mail)) { throw new StatusException(sprintf("BackendIMAP->MeetingResponse(): Error, message not found, maybe was moved"), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT); } $mobj = new Mail_mimeDecode($mail); unset($mail); $message = $mobj->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'rfc_822bodies' => true, 'charset' => 'utf-8')); unset($mobj); $Mail_RFC822 = new Mail_RFC822(); $from_header = $this->getDefaultFromValue(); $fromaddr = $this->parseAddr($Mail_RFC822->parseAddressList($from_header)); $to_header = ""; if (isset($message->headers["from"])) { $to_header = $message->headers["from"]; } else { if (isset($message->headers["return-path"])) { $to_header = $message->headers["return-path"]; } else { throw new StatusException(sprintf("BackendIMAP->MeetingResponse(): Error, no reply address"), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT); } } $toaddr = $this->parseAddr($Mail_RFC822->parseAddressList($to_header)); if (isset($message->headers["subject"])) { $subject_header = $message->headers["subject"]; } else { $subject_header = ""; } $body_part = null; if (isset($message->parts)) { $mparts = $message->parts; for ($i = 0; $i < count($mparts); $i++) { $part = $mparts[$i]; //recursively add parts if (isset($part->ctype_primary) && $part->ctype_primary == "multipart" && (isset($part->ctype_secondary) && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative" || $part->ctype_secondary == "related"))) { foreach ($part->parts as $spart) { $mparts[] = $spart; } continue; } if (is_calendar($part)) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->MeetingResponse - text/calendar part found, trying to reply")); $body_part = $this->replyMeetingCalendar($part, $response); } } unset($mparts); } unset($message); if ($body_part === null) { throw new StatusException(sprintf("BackendIMAP->MeetingResponse(): Error, no calendar part modified"), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT); } ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->MeetingResponse - Creating response message")); $mail = new Mail_mimepart(); $headers = array("MIME-version" => "1.0", "From" => $mail->encodeHeader("from", $from_header, "UTF-8"), "To" => $mail->encodeHeader("to", $to_header, "UTF-8"), "Date" => gmdate("D, d M Y H:i:s", time()) . " GMT", "Subject" => $mail->encodeHeader("subject", $subject_header, "UTF-8"), "Content-class" => "urn:content-classes:calendarmessage", "Content-transfer-encoding" => "8BIT"); unset($mail); $mail = new Mail_mimepart($body_part, array("content_type" => "text/calendar; method=REPLY; charset=UTF-8", "headers" => $headers)); $encoded_mail = $mail->encode(); unset($mail); ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->MeetingResponse - Response message")); foreach ($encoded_mail["headers"] as $k => $v) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("%s: %s", $k, $v)); } ZLog::Write(LOGLEVEL_DEBUG, sprintf("%s", $encoded_mail["body"])); $send = $this->sendMessage($fromaddr, $toaddr, $encoded_mail["headers"], $encoded_mail["body"]); if ($send) { $this->saveSentMessage($encoded_mail["headers"], $encoded_mail["body"]); } unset($encoded_mail); return $send; }
function parseAddressList($address) { if (!$address) { return array(); } // Delivered-To may appear more than once in the email headers if (is_array($address)) { $address = implode(', ', $address); } $parsed = Mail_RFC822::parseAddressList($address, null, null, false); if (PEAR::isError($parsed)) { return array(); } // Decode name and mailbox foreach ($parsed as $p) { $p->personal = Format::mimedecode($p->personal, $this->charset); // Some mail clients may send ISO-8859-1 strings without proper encoding. // Also, handle the more sane case where the mailbox is properly encoded // against RFC2047 $p->mailbox = Format::mimedecode($p->mailbox, $this->charset); } return $parsed; }
/** * Returns the actual SyncXXX object type. * * @param string $folderid id of the parent folder * @param string $id id of the message * @param ContentParameters $contentparameters parameters of the requested message (truncation, mimesupport etc) * * @access public * @return object/false false if the message could not be retrieved */ public function GetMessage($folderid, $id, $contentparameters) { $truncsize = Utils::GetTruncSize($contentparameters->GetTruncation()); $mimesupport = $contentparameters->GetMimeSupport(); $bodypreference = $contentparameters->GetBodyPreference(); /* fmbiete's contribution r1528, ZP-320 */ ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage('%s', '%s', '%s')", $folderid, $id, implode(",", $bodypreference))); $folderImapid = $this->getImapIdFromFolderId($folderid); $is_sent_folder = strcasecmp($folderImapid, $this->create_name_folder(IMAP_FOLDER_SENT)) == 0; // Get flags, etc $stat = $this->StatMessage($folderid, $id); if ($stat) { $this->imap_reopen_folder($folderImapid); $mail_headers = @imap_fetchheader($this->mbox, $id, FT_UID); $mail = $mail_headers . @imap_body($this->mbox, $id, FT_PEEK | FT_UID); if (empty($mail)) { throw new StatusException(sprintf("BackendIMAP->GetMessage(): Error, message not found, maybe was moved"), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT); } $mobj = new Mail_mimeDecode($mail); $message = $mobj->decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'rfc_822bodies' => true, 'charset' => 'utf-8')); $is_multipart = is_multipart($message); $is_smime = is_smime($message); $is_encrypted = $is_smime ? is_encrypted($message) : false; ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): Message is multipart: %d, smime: %d, smime encrypted: %d", $is_multipart, $is_smime, $is_encrypted)); //Select body type preference $bpReturnType = SYNC_BODYPREFERENCE_PLAIN; if ($bodypreference !== false) { $bpReturnType = Utils::GetBodyPreferenceBestMatch($bodypreference); // changed by mku ZP-330 } ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): getBodyPreferenceBestMatch: %d", $bpReturnType)); // Prefered format is MIME -OR- message is SMIME -OR- the device supports MIME (iPhone) and doesn't really understand HTML if ($bpReturnType == SYNC_BODYPREFERENCE_MIME || $is_smime || in_array(SYNC_BODYPREFERENCE_MIME, $bodypreference)) { $bpReturnType = SYNC_BODYPREFERENCE_MIME; } // We need the text body even though MIME is used, for the preview $textBody = ""; Mail_mimeDecode::getBodyRecursive($message, "html", $textBody, true); if (strlen($textBody) > 0) { if ($bpReturnType != SYNC_BODYPREFERENCE_MIME) { $bpReturnType = SYNC_BODYPREFERENCE_HTML; } } else { Mail_mimeDecode::getBodyRecursive($message, "plain", $textBody, true); if ($bpReturnType != SYNC_BODYPREFERENCE_MIME) { $bpReturnType = SYNC_BODYPREFERENCE_PLAIN; } } ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): after thinking a bit we will use: %d", $bpReturnType)); $output = new SyncMail(); if (Request::GetProtocolVersion() >= 12.0) { $output->asbody = new SyncBaseBody(); switch ($bpReturnType) { case SYNC_BODYPREFERENCE_PLAIN: $output->asbody->data = $textBody; break; case SYNC_BODYPREFERENCE_HTML: $output->asbody->data = $textBody; break; case SYNC_BODYPREFERENCE_MIME: if ($is_smime) { if ($is_encrypted) { // #190, KD 2015-06-04 - If message body is encrypted only send the headers, as data should only be in the attachment $output->asbody->data = $mail_headers; } else { $output->asbody->data = $mail; } } else { $output->asbody->data = build_mime_message($message); } break; case SYNC_BODYPREFERENCE_RTF: ZLog::Write(LOGLEVEL_DEBUG, "BackendIMAP->GetMessage(): RTF Format NOT CHECKED"); $output->asbody->data = base64_encode($textBody); break; } // truncate body, if requested. // MIME should not be truncated, but encrypted messages are truncated always to the headers size if ($bpReturnType == SYNC_BODYPREFERENCE_MIME) { if ($is_encrypted) { $output->asbody->truncated = 1; } else { $output->asbody->truncated = 0; } } else { if (strlen($output->asbody->data) > $truncsize) { $output->asbody->data = Utils::Utf8_truncate($output->asbody->data, $truncsize); $output->asbody->truncated = 1; } else { $output->asbody->truncated = 0; } } $output->asbody->type = $bpReturnType; if ($bpReturnType == SYNC_BODYPREFERENCE_MIME) { // NativeBodyType can be only (1 => PLAIN, 2 => HTML, 3 => RTF). MIME uses 1 $output->nativebodytype = SYNC_BODYPREFERENCE_PLAIN; } else { $output->nativebodytype = $bpReturnType; } $output->asbody->estimatedDataSize = strlen($output->asbody->data); $bpo = $contentparameters->BodyPreference($output->asbody->type); if (Request::GetProtocolVersion() >= 14.0 && $bpo->GetPreview()) { // Preview must be always plaintext $previewText = ""; Mail_mimeDecode::getBodyRecursive($message, "plain", $previewText, true); if (strlen($previewText) == 0) { Mail_mimeDecode::getBodyRecursive($message, "html", $previewText, true); $previewText = Utils::ConvertHtmlToText($previewText); } $output->asbody->preview = Utils::Utf8_truncate($previewText, $bpo->GetPreview()); } } else { // ASV_2.5 //DEPRECATED : very old devices, and incomplete code $output->bodytruncated = 0; /* BEGIN fmbiete's contribution r1528, ZP-320 */ if ($bpReturnType == SYNC_BODYPREFERENCE_MIME) { // truncate body, if requested, but never truncate MIME messages $output->mimetruncated = 0; $output->mimedata = $mail; $output->mimesize = strlen($output->mimedata); } else { // truncate body, if requested if (strlen($textBody) > $truncsize) { $output->body = Utils::Utf8_truncate($textBody, $truncsize); $output->bodytruncated = 1; } else { $output->body = $textBody; $output->bodytruncated = 0; } $output->bodysize = strlen($output->body); } /* END fmbiete's contribution r1528, ZP-320 */ } unset($textBody); unset($mail_headers); $output->datereceived = isset($message->headers["date"]) ? $this->cleanupDate($message->headers["date"]) : null; if ($is_smime) { // #190, KD 2015-06-04 - Add Encrypted (and possibly signed) to the classifications emitted if ($is_encrypted) { $output->messageclass = "IPM.Note.SMIME"; } else { $output->messageclass = "IPM.Note.SMIME.MultipartSigned"; } } else { $output->messageclass = "IPM.Note"; } $output->subject = isset($message->headers["subject"]) ? $message->headers["subject"] : ""; $output->read = $stat["flags"]; $output->from = isset($message->headers["from"]) ? $message->headers["from"] : null; /* BEGIN fmbiete's contribution r1528, ZP-320 */ if (isset($message->headers["thread-topic"])) { $output->threadtopic = $message->headers["thread-topic"]; /* //FIXME: Conversation support, get conversationid and conversationindex good values if (Request::GetProtocolVersion() >= 14.0) { // since the conversationid must be unique for a thread we could use the threadtopic in base64 minus the == $output->conversationid = strtoupper(str_replace("=", "", base64_encode($output->threadtopic))); if (isset($message->headers["thread-index"])) $output->conversationindex = strtoupper($message->headers["thread-index"]); } */ } else { $output->threadtopic = $output->subject; } // Language Code Page ID: http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx $output->internetcpid = INTERNET_CPID_UTF8; if (Request::GetProtocolVersion() >= 12.0) { $output->contentclass = "urn:content-classes:message"; $output->flag = new SyncMailFlags(); if (isset($stat["star"]) && $stat["star"]) { //flagstatus 0: clear, 1: complete, 2: active $output->flag->flagstatus = SYNC_FLAGSTATUS_ACTIVE; //flagtype: for follow up $output->flag->flagtype = "FollowUp"; } else { $output->flag->flagstatus = SYNC_FLAGSTATUS_CLEAR; } } /* END fmbiete's contribution r1528, ZP-320 */ $Mail_RFC822 = new Mail_RFC822(); $toaddr = $ccaddr = $replytoaddr = array(); if (isset($message->headers["to"])) { $toaddr = $Mail_RFC822->parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = $Mail_RFC822->parseAddressList($message->headers["cc"]); } if (isset($message->headers["reply-to"])) { $replytoaddr = $Mail_RFC822->parseAddressList($message->headers["reply-to"]); } $output->to = array(); $output->cc = array(); $output->reply_to = array(); foreach (array("to" => $toaddr, "cc" => $ccaddr, "reply_to" => $replytoaddr) as $type => $addrlist) { if ($addrlist === false) { //If we couldn't parse the addresslist we put the raw header (decoded) if ($type == "reply_to") { array_push($output->{$type}, $message->headers["reply-to"]); } else { array_push($output->{$type}, $message->headers[$type]); } } else { foreach ($addrlist as $addr) { // If the address was a group we have "groupname" and "addresses" atributes if (isset($addr->addresses)) { if (count($addr->addresses) == 0) { // readd the empty group delimiter array_push($output->{$type}, sprintf("%s:;", $addr->groupname)); if (!isset($output->displayto) && strlen($addr->groupname) > 0) { $output->displayto = $addr->groupname; } } else { foreach ($addr->addresses as $addr_group) { $name = $this->add_address_to_list($output->{$type}, $addr_group); if (!isset($output->displayto) && strlen($name) > 0) { $output->displayto = $name; } } } } else { // Not a group $name = $this->add_address_to_list($output->{$type}, $addr); if (!isset($output->displayto) && strlen($name) > 0) { $output->displayto = $name; } } } } } // convert mime-importance to AS-importance if (isset($message->headers["x-priority"])) { $mimeImportance = preg_replace("/\\D+/", "", $message->headers["x-priority"]); //MAIL 1 - most important, 3 - normal, 5 - lowest //AS 0 - low, 1 - normal, 2 - important if ($mimeImportance > 3) { $output->importance = 0; } elseif ($mimeImportance == 3) { $output->importance = 1; } elseif ($mimeImportance < 3) { $output->importance = 2; } } else { /* fmbiete's contribution r1528, ZP-320 */ $output->importance = 1; } // Attachments are also needed for MIME messages if (isset($message->parts)) { $mparts = $message->parts; for ($i = 0; $i < count($mparts); $i++) { $part = $mparts[$i]; //recursively add subparts to later processing if (isset($part->ctype_primary) && $part->ctype_primary == "multipart" && (isset($part->ctype_secondary) && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative" || $part->ctype_secondary == "related"))) { if (isset($part->parts)) { foreach ($part->parts as $spart) { $mparts[] = $spart; } } // Go to the for again continue; } if (is_calendar($part)) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): text/calendar part found, trying to convert")); $output->meetingrequest = new SyncMeetingRequest(); parse_meeting_calendar($part, $output, $is_sent_folder); } else { //add part as attachment if it's disposition indicates so or if it is not a text part if (isset($part->disposition) && ($part->disposition == "attachment" || $part->disposition == "inline") || isset($part->ctype_primary) && $part->ctype_primary != "text") { if (isset($part->d_parameters['filename'])) { $attname = $part->d_parameters['filename']; } else { if (isset($part->ctype_parameters['name'])) { $attname = $part->ctype_parameters['name']; } else { if (isset($part->headers['content-description'])) { $attname = $part->headers['content-description']; } else { $attname = "unknown attachment"; } } } /* BEGIN fmbiete's contribution r1528, ZP-320 */ if (Request::GetProtocolVersion() >= 12.0) { if (!isset($output->asattachments) || !is_array($output->asattachments)) { $output->asattachments = array(); } $attachment = new SyncBaseAttachment(); $attachment->estimatedDataSize = isset($part->d_parameters['size']) ? $part->d_parameters['size'] : isset($part->body) ? strlen($part->body) : 0; $attachment->displayname = $attname; $attachment->filereference = $folderid . ":" . $id . ":" . $i; $attachment->method = 1; //Normal attachment $attachment->contentid = isset($part->headers['content-id']) ? str_replace("<", "", str_replace(">", "", $part->headers['content-id'])) : ""; if (isset($part->disposition) && $part->disposition == "inline") { $attachment->isinline = 1; // #209 - KD 2015-06-16 If we got a filename use it, otherwise guess if (!isset($part->filename)) { // We try to fix the name for the inline file. // FIXME: This is a dirty hack as the used in the Zarafa backend, if you have a better method let me know! if (isset($part->ctype_primary) && isset($part->ctype_secondary)) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): Guessing extension for inline attachment [primary_type %s secondary_type %s]", $part->ctype_primary, $part->ctype_secondary)); if (isset(BackendIMAP::$mimeTypes[$part->ctype_primary . '/' . $part->ctype_secondary])) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): primary_type %s secondary_type %s", $part->ctype_primary, $part->ctype_secondary)); $attachment->displayname = "inline_" . $i . "." . BackendIMAP::$mimeTypes[$part->ctype_primary . '/' . $part->ctype_secondary]; } else { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): no extension found in '%s'!!", SYSTEM_MIME_TYPES_MAPPING)); } } else { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendIMAP->GetMessage(): no primary_type or secondary_type")); } } } else { $attachment->isinline = 0; } array_push($output->asattachments, $attachment); } else { //ASV_2.5 if (!isset($output->attachments) || !is_array($output->attachments)) { $output->attachments = array(); } $attachment = new SyncAttachment(); $attachment->attsize = isset($part->d_parameters['size']) ? $part->d_parameters['size'] : isset($part->body) ? strlen($part->body) : 0; $attachment->displayname = $attname; $attachment->attname = $folderid . ":" . $id . ":" . $i; $attachment->attmethod = 1; $attachment->attoid = isset($part->headers['content-id']) ? str_replace("<", "", str_replace(">", "", $part->headers['content-id'])) : ""; array_push($output->attachments, $attachment); } /* END fmbiete's contribution r1528, ZP-320 */ } } } } unset($message); unset($mobj); unset($mail); return $output; } return false; }
$dbh = $sth = $record = null; return $from; } function encoding_from($from) { $items = explode("<", $from); $name = trim($items[0]); return "=?UTF-8?B?" . base64_encode($name) . "?= <" . $items[1]; } $from = get_from_sql('fmbiete', 'zpush.org'); printf("%s\n", $from); $from = "Francisco Miguel Biete Bañón <*****@*****.**>"; $encoded_from = encoding_from($from); printf("%s\n", $encoded_from); function parseAddr($ad) { $addr_string = ""; if (isset($ad) && is_array($ad)) { foreach ($ad as $addr) { if ($addr_string) { $addr_string .= ","; } $addr_string .= $addr->mailbox . "@" . $addr->host; } } return $addr_string; } include_once 'include/z_RFC822.php'; $Mail_RFC822 = new Mail_RFC822(); $fromaddr = parseAddr($Mail_RFC822->parseAddressList($encoded_from)); printf("%s\n", $fromaddr);
/** * Starts the whole process. The address must either be set here * or when creating the object. One or the other. * * @access public * @param string $address The address(es) to validate. * @param string $default_domain Default domain/host etc. * @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing. * @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance. * * @return array A structured array of addresses. */ function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null) { if (!isset($this) || !isset($this->mailRFC822)) { $obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit); return $obj->parseAddressList(); } if (isset($address)) { $this->address = $address; } if (isset($default_domain)) { $this->default_domain = $default_domain; } if (isset($nest_groups)) { $this->nestGroups = $nest_groups; } if (isset($validate)) { $this->validate = $validate; } if (isset($limit)) { $this->limit = $limit; } $this->structure = array(); $this->addresses = array(); $this->error = null; $this->index = null; // Unfold any long lines in $this->address. $this->address = preg_replace('/\\r?\\n/', "\r\n", $this->address); $this->address = preg_replace('/\\r\\n(\\t| )+/', ' ', $this->address); while ($this->address = $this->_splitAddresses($this->address)) { } if ($this->address === false || isset($this->error)) { //require_once 'PEAR.php'; return $this->raiseError($this->error); } // Validate each address individually. If we encounter an invalid // address, stop iterating and return an error immediately. foreach ($this->addresses as $address) { $valid = $this->_validateAddress($address); if ($valid === false || isset($this->error)) { //require_once 'PEAR.php'; return $this->raiseError($this->error); } if (!$this->nestGroups) { $this->structure = array_merge($this->structure, $valid); } else { $this->structure[] = $valid; } } return $this->structure; }
/** * explode recipient string * allowed seperators are ',' ';' ' ' * * Returns an array with recipient objects * * @access private * * @return array with recipient objects. array[i]->mailbox gets the mailbox * of the recipient. array[i]->host gets the host of the recipients. Returns * a PEAR_Error object, if exploding failed. Use is_a() to test, if the return * value is a PEAR_Error, then use $rcp->message to retrieve the error message. */ function explodeRecipients($a_recipients, $use_pear = true) { $a_recipients = trim($a_recipients); // WHITESPACE IS NOT ALLOWED AS SEPERATOR #$a_recipients = preg_replace("/ /",",",$a_recipients); $a_recipients = preg_replace("/;/", ",", $a_recipients); if (ilMail::_usePearMail() && $use_pear == true) { if (strlen(trim($a_recipients)) > 0) { require_once './Services/PEAR/lib/Mail/RFC822.php'; $parser = new Mail_RFC822(); return $parser->parseAddressList($a_recipients, "ilias", false, true); } else { return array(); } } else { foreach (explode(',', $a_recipients) as $tmp_rec) { if ($tmp_rec) { $rcps[] = trim($tmp_rec); } } return is_array($rcps) ? $rcps : array(); } }
function register(&$data, $auto_activate = false) { $session = Session::singletone(); $db = Database::singletone()->db(); if (empty($data['user_login'])) { throw new Exception("Nie można zarejestrować konta. Musisz podać login."); } if (empty($data['user_pass1']) || empty($data['user_pass2'])) { throw new Exception("Nie można zarejestrować konta. Hasło nie może być puste."); } if (empty($data['user_email'])) { throw new Exception("Nie można zarejestrować konta. Musisz podać email."); } $addr = Mail_RFC822::parseAddressList($data['user_email'], ""); if (empty($addr)) { throw new Exception("Nie można zarejestrować konta. Podany adres email jest nieprawidłowy."); } if ($data['user_pass1'] != $data['user_pass2']) { throw new Exception("Nie można zarejestrować konta. Podane hasła różnią się"); } $user_login = trim($data['user_login']); $user_pass1 = $data['user_pass1']; $user_pass2 = $data['user_pass2']; $user_email = trim($data['user_email']); $user_title = Config::get('default_user_title'); $user_level = Config::get('default_user_level', 0); $sth = $db->prepare("SELECT COUNT(*) AS cnt FROM phph_users WHERE user_login = :user_login"); $sth->bindParam(":user_login", $user_login); $sth->execute(); $cnt = $sth->fetchColumn(0); $sth = null; if ($cnt != 0) { throw new Exception("Nie można zarejestrować konta. Podany login jest już zajęty."); } $sth = $db->prepare("INSERT INTO phph_users (user_login, user_pass, user_email, user_registered, user_activation, user_title, user_level, user_activated) VALUES " . "(:user_login, :user_pass, :user_email, :user_registered, :user_activation, :user_title, :user_level, :user_activated)"); $sth->bindParam(":user_login", $user_login); $sth->bindValue(":user_pass", md5($user_pass1)); $sth->bindParam(":user_email", $user_email); $sth->bindParam(":user_title", $user_title); $sth->bindParam(":user_level", $user_level); $sth->bindValue(":user_registered", time()); $sth->bindValue(":user_activation", md5(uniqid($user_login))); if ($auto_activate) { $sth->bindValue(":user_activated", time()); } else { $sth->bindValue(":user_activated", 0); } $sth->execute(); $sth = null; $this->_uid = $db->lastInsertId(); $this->updateDBData(); return $this->_uid; }
/** * Returns the mailbox address of a role. * * Example 1: Mailbox address for an ILIAS reserved role name * ---------------------------------------------------------- * The il_crs_member_345 role of the course object "English Course 1" is * returned as one of the following mailbox addresses: * * a) Course Member <#member@[English Course 1]> * b) Course Member <#il_crs_member_345@[English Course 1]> * c) Course Member <#il_crs_member_345> * * Address a) is returned, if the title of the object is unique, and * if there is only one local role with the substring "member" defined for * the object. * * Address b) is returned, if the title of the object is unique, but * there is more than one local role with the substring "member" in its title. * * Address c) is returned, if the title of the course object is not unique. * * * Example 2: Mailbox address for a manually defined role name * ----------------------------------------------------------- * The "Admin" role of the category object "Courses" is * returned as one of the following mailbox addresses: * * a) Course Administrator <#Admin@Courses> * b) Course Administrator <#Admin> * c) Course Adminstrator <#il_role_34211> * * Address a) is returned, if the title of the object is unique, and * if there is only one local role with the substring "Admin" defined for * the course object. * * Address b) is returned, if the title of the object is not unique, but * the role title is unique. * * Address c) is returned, if neither the role title nor the title of the * course object is unique. * * * Example 3: Mailbox address for a manually defined role title that can * contains special characters in the local-part of a * mailbox address * -------------------------------------------------------------------- * The "Author Courses" role of the category object "Courses" is * returned as one of the following mailbox addresses: * * a) "#Author Courses"@Courses * b) Author Courses <#il_role_34234> * * Address a) is returned, if the title of the role is unique. * * Address b) is returned, if neither the role title nor the title of the * course object is unique, or if the role title contains a quote or a * backslash. * * * @param int a role id * @param boolean is_localize whether mailbox addresses should be localized * @return String mailbox address or null, if role does not exist. * @todo refactor rolf */ function getRoleMailboxAddress($a_role_id, $is_localize = true) { global $log, $lng, $ilDB; include_once "Services/Mail/classes/class.ilMail.php"; if (ilMail::_usePearMail()) { // Retrieve the role title and the object title. $query = "SELECT rdat.title role_title,odat.title object_title, " . " oref.ref_id object_ref " . "FROM object_data rdat " . "JOIN rbac_fa fa ON fa.rol_id = rdat.obj_id " . "JOIN tree rtree ON rtree.child = fa.parent " . "JOIN object_reference oref ON oref.ref_id = rtree.parent " . "JOIN object_data odat ON odat.obj_id = oref.obj_id " . "WHERE rdat.obj_id = " . $this->ilDB->quote($a_role_id, 'integer') . " " . "AND fa.assign = 'y' "; $r = $ilDB->query($query); if (!($row = $ilDB->fetchObject($r))) { //$log->write('class.ilRbacReview->getMailboxAddress('.$a_role_id.'): error role does not exist'); return null; // role does not exist } $object_title = $row->object_title; $object_ref = $row->object_ref; $role_title = $row->role_title; // In a perfect world, we could use the object_title in the // domain part of the mailbox address, and the role title // with prefix '#' in the local part of the mailbox address. $domain = $object_title; $local_part = $role_title; // Determine if the object title is unique $q = "SELECT COUNT(DISTINCT dat.obj_id) count " . "FROM object_data dat " . "JOIN object_reference ref ON ref.obj_id = dat.obj_id " . "JOIN tree ON tree.child = ref.ref_id " . "WHERE title = " . $this->ilDB->quote($object_title, 'text') . " " . "AND tree.tree = 1 "; $r = $this->ilDB->query($q); $row = $r->fetchRow(DB_FETCHMODE_OBJECT); // If the object title is not unique, we get rid of the domain. if ($row->count > 1) { $domain = null; } // If the domain contains illegal characters, we get rid of it. //if (domain != null && preg_match('/[\[\]\\]|[\x00-\x1f]/',$domain)) // Fix for Mantis Bug: 7429 sending mail fails because of brakets // Fix for Mantis Bug: 9978 sending mail fails because of semicolon if ($domain != null && preg_match('/[\\[\\]\\]|[\\x00-\\x1f]|[\\x28-\\x29]|[;]/', $domain)) { $domain = null; } // If the domain contains special characters, we put square // brackets around it. if ($domain != null && (preg_match('/[()<>@,;:\\".\\[\\]]/', $domain) || preg_match('/[^\\x21-\\x8f]/', $domain))) { $domain = '[' . $domain . ']'; } // If the role title is one of the ILIAS reserved role titles, // we can use a shorthand version of it for the local part // of the mailbox address. if (strpos($role_title, 'il_') === 0 && $domain != null) { $unambiguous_role_title = $role_title; $pos = strpos($role_title, '_', 3) + 1; $local_part = substr($role_title, $pos, strrpos($role_title, '_') - $pos); } else { $unambiguous_role_title = 'il_role_' . $a_role_id; } // Determine if the local part is unique. If we don't have a // domain, the local part must be unique within the whole repositry. // If we do have a domain, the local part must be unique for that // domain. if ($domain == null) { $q = "SELECT COUNT(DISTINCT dat.obj_id) count " . "FROM object_data dat " . "JOIN object_reference ref ON ref.obj_id = dat.obj_id " . "JOIN tree ON tree.child = ref.ref_id " . "WHERE title = " . $this->ilDB->quote($local_part, 'text') . " " . "AND tree.tree = 1 "; } else { $q = "SELECT COUNT(rd.obj_id) count " . "FROM object_data rd " . "JOIN rbac_fa fa ON rd.obj_id = fa.rol_id " . "JOIN tree t ON t.child = fa.parent " . "WHERE fa.assign = 'y' " . "AND t.parent = " . $this->ilDB->quote($object_ref, 'integer') . " " . "AND rd.title LIKE " . $this->ilDB->quote('%' . preg_replace('/([_%])/', '\\\\$1', $local_part) . '%', 'text') . " "; } $r = $this->ilDB->query($q); $row = $r->fetchRow(DB_FETCHMODE_OBJECT); // if the local_part is not unique, we use the unambiguous role title // instead for the local part of the mailbox address if ($row->count > 1) { $local_part = $unambiguous_role_title; } $use_phrase = true; // If the local part contains illegal characters, we use // the unambiguous role title instead. if (preg_match('/[\\"\\x00-\\x1f]/', $local_part)) { $local_part = $unambiguous_role_title; } else { if (!preg_match('/^[\\x00-\\x7E]+$/i', $local_part)) { // 2013-12-05: According to #12283, we do not accept umlauts in the local part $local_part = $unambiguous_role_title; $use_phrase = false; } } // Add a "#" prefix to the local part $local_part = '#' . $local_part; // Put quotes around the role title, if needed if (preg_match('/[()<>@,;:.\\[\\]\\x20]/', $local_part)) { $local_part = '"' . $local_part . '"'; } $mailbox = $domain == null ? $local_part : $local_part . '@' . $domain; if ($is_localize) { if (substr($role_title, 0, 3) == 'il_') { $phrase = $lng->txt(substr($role_title, 0, strrpos($role_title, '_'))); } else { $phrase = $role_title; } if ($use_phrase) { // make phrase RFC 822 conformant: // - strip excessive whitespace // - strip special characters $phrase = preg_replace('/\\s\\s+/', ' ', $phrase); $phrase = preg_replace('/[()<>@,;:\\".\\[\\]]/', '', $phrase); $mailbox = $phrase . ' <' . $mailbox . '>'; } } require_once './Services/PEAR/lib/Mail/RFC822.php'; $obj = new Mail_RFC822($mailbox, 'ilias'); if (@$obj->parseAddressList() instanceof PEAR_Error) { $q = "SELECT title " . "FROM object_data " . "WHERE obj_id = " . $this->ilDB->quote($a_role_id, 'integer'); $r = $this->ilDB->query($q); if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT)) { return '#' . $row->title; } else { return null; } } return $mailbox; } else { $q = "SELECT title " . "FROM object_data " . "WHERE obj_id = " . $this->ilDB->quote($a_role_id, 'integer'); $r = $this->ilDB->query($q); if ($row = $r->fetchRow(DB_FETCHMODE_OBJECT)) { return '#' . $row->title; } else { return null; } } }
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { $mimeParams = array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\r\n", 'charset' => 'utf-8'); $mimeObject = new Mail_mimeDecode($mimeParams['input'], $mimeParams['crlf']); $message = $mimeObject->decode($mimeParams); // Open the outbox and create the message there $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID)); if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) { debugLog("Outbox not found to create message"); return false; } $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]); if (!$outbox) { debugLog("Unable to open outbox"); return false; } $mapimessage = mapi_folder_createmessage($outbox); mapi_setprops($mapimessage, array(PR_SUBJECT => u2w($mimeObject->_decodeHeader($message->headers["subject"])), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time())); if (isset($message->headers["x-priority"])) { switch ($message->headers["x-priority"]) { case 1: case 2: $priority = PRIO_URGENT; $importance = IMPORTANCE_HIGH; break; case 4: case 5: $priority = PRIO_NONURGENT; $importance = IMPORTANCE_LOW; break; case 3: default: $priority = PRIO_NORMAL; $importance = IMPORTANCE_NORMAL; break; } mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority)); } $addresses = array(); $toaddr = $ccaddr = $bccaddr = array(); if (isset($message->headers["to"])) { $toaddr = Mail_RFC822::parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = Mail_RFC822::parseAddressList($message->headers["cc"]); } if (isset($message->headers["bcc"])) { $bccaddr = Mail_RFC822::parseAddressList($message->headers["bcc"]); } // Add recipients $recips = array(); if (isset($toaddr)) { foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $mapirecip[PR_ADDRTYPE] = "SMTP"; $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host; if (isset($addr->personal) && strlen($addr->personal) > 0) { $mapirecip[PR_DISPLAY_NAME] = u2w($mimeObject->_decodeHeader($addr->personal)); } else { $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS]; } $mapirecip[PR_RECIPIENT_TYPE] = $type; $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]); array_push($recips, $mapirecip); } } } mapi_message_modifyrecipients($mapimessage, 0, $recips); // Loop through subparts. We currently only support real single-level // multiparts and partly multipart/related/mixed for attachments. // The PDA currently only does this because you are adding // an attachment and the type will be multipart/mixed or multipart/alternative. $body = ""; if ($message->ctype_primary == "multipart" && ($message->ctype_secondary == "mixed" || $message->ctype_secondary == "alternative")) { foreach ($message->parts as $part) { if ($part->ctype_primary == "text" && $part->ctype_secondary == "plain" && isset($part->body)) { // discard any other kind of text, like html $body .= u2w($part->body); // assume only one text body } elseif ($part->ctype_primary == "ms-tnef" || $part->ctype_secondary == "ms-tnef") { $zptnef = new ZPush_tnef($this->_defaultstore); $mapiprops = array(); $zptnef->extractProps($part->body, $mapiprops); if (is_array($mapiprops) && !empty($mapiprops)) { //check if it is a recurring item $tnefrecurr = GetPropIDFromString($this->_defaultstore, "PT_BOOLEAN:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x5"); if (isset($mapiprops[$tnefrecurr])) { $this->_handleRecurringItem($mapimessage, $mapiprops); } mapi_setprops($mapimessage, $mapiprops); } else { debugLog("TNEF: Mapi props array was empty"); } } elseif ($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "related")) { if (is_array($part->parts)) { foreach ($part->parts as $part2) { if (isset($part2->disposition) && ($part2->disposition == "inline" || $part2->disposition == "attachment")) { $this->_storeAttachment($mapimessage, $part2); } } } } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "calendar") { $zpical = new ZPush_ical($this->_defaultstore); $mapiprops = array(); $zpical->extractProps($part->body, $mapiprops); if (is_array($mapiprops) && !empty($mapiprops)) { mapi_setprops($mapimessage, $mapiprops); } else { debugLog("ICAL: Mapi props array was empty"); } } else { $this->_storeAttachment($mapimessage, $part); } } } else { $body = u2w($message->body); } if ($forward) { $orig = $forward; } if ($reply) { $orig = $reply; } if (isset($orig) && $orig) { // Append the original text body for reply/forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); if ($fwmessage) { //update icon when forwarding or replying message if ($forward) { mapi_setprops($fwmessage, array(PR_ICON_INDEX => 262)); } elseif ($reply) { mapi_setprops($fwmessage, array(PR_ICON_INDEX => 261)); } mapi_savechanges($fwmessage); $stream = mapi_openproperty($fwmessage, PR_BODY, IID_IStream, 0, 0); $fwbody = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $fwbody .= $data; } if (strlen($body) > 0) { if ($forward) { // During a forward, we have to add the forward header ourselves. This is because // normally the forwarded message is added as an attachment. However, we don't want this // because it would be rather complicated to copy over the entire original message due // to the lack of IMessage::CopyTo .. $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME)); $body .= "\r\n\r\n"; $body .= "-----Original Message-----\r\n"; if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) { $body .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) { $body .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) { $body .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n"; } if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) { $body .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n"; } if (isset($fwmessageprops[PR_SUBJECT])) { $body .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n"; } $body .= "\r\n"; } $body .= $fwbody; } } else { debugLog("Unable to open item with id {$orig} for forward/reply"); } } if ($forward) { // Add attachments from the original message in a forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); $attachtable = mapi_message_getattachmenttable($fwmessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($mapimessage); // Copy all attachments from old to new attachment $attachprops = mapi_getprops($attach); mapi_setprops($newattach, $attachprops); if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) { // Data is in a stream $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE); while (1) { $data = mapi_stream_read($srcstream, 4096); if (strlen($data) == 0) { break; } mapi_stream_write($dststream, $data); } mapi_stream_commit($dststream); } mapi_savechanges($newattach); } } } mapi_setprops($mapimessage, array(PR_BODY => $body)); mapi_savechanges($mapimessage); mapi_message_submitmessage($mapimessage); return true; }
function parseAddressList($address) { return Mail_RFC822::parseAddressList($address, null, null, false); }
function SendMail($rfc822, $forward = false, $reply = false, $parent = false) { if (WBXML_DEBUG == true) { debugLog("SendMail: forward: {$forward} reply: {$reply} parent: {$parent}\n" . $rfc822); } $mimeParams = array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8'); $mimeObject = new Mail_mimeDecode($rfc822); $message = $mimeObject->decode($mimeParams); // Open the outbox and create the message there $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID)); if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) { debugLog("Outbox not found to create message"); return false; } $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]); if (!$outbox) { debugLog("Unable to open outbox"); return false; } $mapimessage = mapi_folder_createmessage($outbox); mapi_setprops($mapimessage, array(PR_SUBJECT => u2wi(isset($message->headers["subject"]) ? $message->headers["subject"] : ""), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time())); if (isset($message->headers["x-priority"])) { switch ($message->headers["x-priority"]) { case 1: case 2: $priority = PRIO_URGENT; $importance = IMPORTANCE_HIGH; break; case 4: case 5: $priority = PRIO_NONURGENT; $importance = IMPORTANCE_LOW; break; case 3: default: $priority = PRIO_NORMAL; $importance = IMPORTANCE_NORMAL; break; } mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority)); } $addresses = array(); $toaddr = $ccaddr = $bccaddr = array(); $Mail_RFC822 = new Mail_RFC822(); if (isset($message->headers["to"])) { $toaddr = $Mail_RFC822->parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = $Mail_RFC822->parseAddressList($message->headers["cc"]); } if (isset($message->headers["bcc"])) { $bccaddr = $Mail_RFC822->parseAddressList($message->headers["bcc"]); } // Add recipients $recips = array(); if (isset($toaddr)) { foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $mapirecip[PR_ADDRTYPE] = "SMTP"; $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host; if (isset($addr->personal) && strlen($addr->personal) > 0) { $mapirecip[PR_DISPLAY_NAME] = u2wi($addr->personal); } else { $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS]; } $mapirecip[PR_RECIPIENT_TYPE] = $type; $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]); array_push($recips, $mapirecip); } } } mapi_message_modifyrecipients($mapimessage, 0, $recips); // Loop through message subparts. $body = ""; $body_html = ""; if ($message->ctype_primary == "multipart" && ($message->ctype_secondary == "mixed" || $message->ctype_secondary == "alternative")) { $mparts = $message->parts; for ($i = 0; $i < count($mparts); $i++) { $part = $mparts[$i]; // palm pre & iPhone send forwarded messages in another subpart which are also parsed if ($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative" || $part->ctype_secondary == "related")) { foreach ($part->parts as $spart) { $mparts[] = $spart; } continue; } // standard body if ($part->ctype_primary == "text" && $part->ctype_secondary == "plain" && isset($part->body) && (!isset($part->disposition) || $part->disposition != "attachment")) { $body .= u2wi($part->body); // assume only one text body } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "html") { $body_html .= u2wi($part->body); } elseif ($part->ctype_primary == "ms-tnef" || $part->ctype_secondary == "ms-tnef") { $zptnef = new ZPush_tnef($this->_defaultstore); $mapiprops = array(); $zptnef->extractProps($part->body, $mapiprops); if (is_array($mapiprops) && !empty($mapiprops)) { //check if it is a recurring item $tnefrecurr = GetPropIDFromString($this->_defaultstore, "PT_BOOLEAN:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x5"); if (isset($mapiprops[$tnefrecurr])) { $this->_handleRecurringItem($mapimessage, $mapiprops); } mapi_setprops($mapimessage, $mapiprops); } else { debugLog("TNEF: Mapi props array was empty"); } } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "calendar") { $zpical = new ZPush_ical($this->_defaultstore); $mapiprops = array(); $zpical->extractProps($part->body, $mapiprops); // iPhone sends a second ICS which we ignore if we can if (!isset($mapiprops[PR_MESSAGE_CLASS]) && strlen(trim($body)) == 0) { debugLog("Secondary iPhone response is being ignored!! Mail dropped!"); return true; } if (!checkMapiExtVersion("6.30") && is_array($mapiprops) && !empty($mapiprops)) { mapi_setprops($mapimessage, $mapiprops); } else { // store ics as attachment //see icalTimezoneFix function in compat.php for more information $part->body = icalTimezoneFix($part->body); $this->_storeAttachment($mapimessage, $part); debugLog("Sending ICS file as attachment"); } } else { $this->_storeAttachment($mapimessage, $part); } } } else { if ($message->ctype_primary == "text" && $message->ctype_secondary == "html") { $body_html .= u2wi($message->body); } else { $body = u2wi($message->body); } } // some devices only transmit a html body if (strlen($body) == 0 && strlen($body_html) > 0) { debugLog("only html body sent, transformed into plain text"); $body = strip_tags($body_html); } if ($forward) { $orig = $forward; } if ($reply) { $orig = $reply; } if (isset($orig) && $orig) { // Append the original text body for reply/forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); if ($fwmessage) { //update icon when forwarding or replying message if ($forward) { mapi_setprops($fwmessage, array(PR_ICON_INDEX => 262)); } elseif ($reply) { mapi_setprops($fwmessage, array(PR_ICON_INDEX => 261)); } mapi_savechanges($fwmessage); $stream = mapi_openproperty($fwmessage, PR_BODY, IID_IStream, 0, 0); $fwbody = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $fwbody .= $data; } $stream = mapi_openproperty($fwmessage, PR_HTML, IID_IStream, 0, 0); $fwbody_html = ""; while (1) { $data = mapi_stream_read($stream, 1024); if (strlen($data) == 0) { break; } $fwbody_html .= $data; } if ($forward) { // During a forward, we have to add the forward header ourselves. This is because // normally the forwarded message is added as an attachment. However, we don't want this // because it would be rather complicated to copy over the entire original message due // to the lack of IMessage::CopyTo .. $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME)); $fwheader = "\r\n\r\n"; $fwheader .= "-----Original Message-----\r\n"; if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) { $fwheader .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) { $fwheader .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n"; } if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) { $fwheader .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n"; } if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) { $fwheader .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n"; } if (isset($fwmessageprops[PR_SUBJECT])) { $fwheader .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n"; } $fwheader .= "\r\n"; // add fwheader to body and body_html $body .= $fwheader; if (strlen($body_html) > 0) { $body_html .= str_ireplace("\r\n", "<br>", $fwheader); } } if (strlen($body) > 0) { $body .= $fwbody; } if (strlen($body_html) > 0) { $body_html .= $fwbody_html; } } else { debugLog("Unable to open item with id {$orig} for forward/reply"); } } if ($forward) { // Add attachments from the original message in a forward $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig)); $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid); $attachtable = mapi_message_getattachmenttable($fwmessage); $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM)); foreach ($rows as $row) { if (isset($row[PR_ATTACH_NUM])) { $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]); $newattach = mapi_message_createattach($mapimessage); // Copy all attachments from old to new attachment $attachprops = mapi_getprops($attach); mapi_setprops($newattach, $attachprops); if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) { // Data is in a stream $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN); $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE); while (1) { $data = mapi_stream_read($srcstream, 4096); if (strlen($data) == 0) { break; } mapi_stream_write($dststream, $data); } mapi_stream_commit($dststream); } mapi_savechanges($newattach); } } } //set PR_INTERNET_CPID to 65001 (utf-8) if store supports it and to 1252 otherwise $internetcpid = 1252; if (defined('STORE_SUPPORTS_UNICODE') && STORE_SUPPORTS_UNICODE == true) { $internetcpid = 65001; } mapi_setprops($mapimessage, array(PR_BODY => $body, PR_INTERNET_CPID => $internetcpid)); if (strlen($body_html) > 0) { mapi_setprops($mapimessage, array(PR_HTML => $body_html)); } mapi_savechanges($mapimessage); mapi_message_submitmessage($mapimessage); return true; }
/** * Returns the actual SyncXXX object type. * * @param string $folderid id of the parent folder * @param string $id id of the message * @param ContentParameters $contentparameters parameters of the requested message (truncation, mimesupport etc) * * @access public * @return object/false false if the message could not be retrieved */ public function GetMessage($folderid, $id, $truncsize, $mimesupport = 0) { if ($folderid != 'root') { return false; } $fn = $this->findMessage($id); // Get flags, etc $stat = $this->StatMessage($folderid, $id); // Parse e-mail $rfc822 = file_get_contents($this->getPath() . "/" . $fn); $message = Mail_mimeDecode::decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\n", 'charset' => 'utf-8')); $output = new SyncMail(); $output->body = str_replace("\n", "\r\n", $this->getBody($message)); $output->bodysize = strlen($output->body); $output->bodytruncated = 0; // We don't implement truncation in this backend $output->datereceived = $this->parseReceivedDate($message->headers["received"][0]); $output->messageclass = "IPM.Note"; $output->subject = $message->headers["subject"]; $output->read = $stat["flags"]; $output->from = $message->headers["from"]; $Mail_RFC822 = new Mail_RFC822(); $toaddr = $ccaddr = $replytoaddr = array(); if (isset($message->headers["to"])) { $toaddr = $Mail_RFC822->parseAddressList($message->headers["to"]); } if (isset($message->headers["cc"])) { $ccaddr = $Mail_RFC822->parseAddressList($message->headers["cc"]); } if (isset($message->headers["reply_to"])) { $replytoaddr = $Mail_RFC822->parseAddressList($message->headers["reply_to"]); } $output->to = array(); $output->cc = array(); $output->reply_to = array(); foreach (array("to" => $toaddr, "cc" => $ccaddr, "reply_to" => $replytoaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $address = $addr->mailbox . "@" . $addr->host; $name = $addr->personal; if (!isset($output->displayto) && $name != "") { $output->displayto = $name; } if ($name == "" || $name == $address) { $fulladdr = w2u($address); } else { if (substr($name, 0, 1) != '"' && substr($name, -1) != '"') { $fulladdr = "\"" . w2u($name) . "\" <" . w2u($address) . ">"; } else { $fulladdr = w2u($name) . " <" . w2u($address) . ">"; } } array_push($output->{$type}, $fulladdr); } } // convert mime-importance to AS-importance if (isset($message->headers["x-priority"])) { $mimeImportance = preg_replace("/\\D+/", "", $message->headers["x-priority"]); if ($mimeImportance > 3) { $output->importance = 0; } if ($mimeImportance == 3) { $output->importance = 1; } if ($mimeImportance < 3) { $output->importance = 2; } } // Attachments are only searched in the top-level part $n = 0; if (isset($message->parts)) { foreach ($message->parts as $part) { if ($part->ctype_primary == "application") { $attachment = new SyncAttachment(); $attachment->attsize = strlen($part->body); if (isset($part->d_parameters['filename'])) { $attname = $part->d_parameters['filename']; } else { if (isset($part->ctype_parameters['name'])) { $attname = $part->ctype_parameters['name']; } else { if (isset($part->headers['content-description'])) { $attname = $part->headers['content-description']; } else { $attname = "unknown attachment"; } } } $attachment->displayname = $attname; $attachment->attname = $id . ":" . $n; $attachment->attmethod = 1; $attachment->attoid = isset($part->headers['content-id']) ? $part->headers['content-id'] : ""; array_push($output->attachments, $attachment); } $n++; } } return $output; }
/** * Adds the recipients to an email message from a RFC822 message headers. * * @param MIMEMessageHeader $headers * @param MAPIMessage $mapimessage */ private function addRecipients($headers, &$mapimessage) { $toaddr = $ccaddr = $bccaddr = array(); $Mail_RFC822 = new Mail_RFC822(); if (isset($headers["to"])) { $toaddr = $Mail_RFC822->parseAddressList($headers["to"]); } if (isset($headers["cc"])) { $ccaddr = $Mail_RFC822->parseAddressList($headers["cc"]); } if (isset($headers["bcc"])) { $bccaddr = $Mail_RFC822->parseAddressList($headers["bcc"]); } if (empty($toaddr)) { throw new StatusException(sprintf("ZarafaBackend->SendMail(): 'To' address in RFC822 message not found or unparsable. To header: '%s'", isset($headers["to"]) ? $headers["to"] : ''), SYNC_COMMONSTATUS_MESSHASNORECIP); } // Add recipients $recips = array(); foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) { foreach ($addrlist as $addr) { $mapirecip[PR_ADDRTYPE] = "SMTP"; $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host; if (isset($addr->personal) && strlen($addr->personal) > 0) { $mapirecip[PR_DISPLAY_NAME] = u2wi($addr->personal); } else { $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS]; } $mapirecip[PR_RECIPIENT_TYPE] = $type; $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]); array_push($recips, $mapirecip); } } mapi_message_modifyrecipients($mapimessage, 0, $recips); }