/** * Constructor. * * @param string $from The email address of the original sender. * @param Horde_Mime_Headers $h The headers object for the message. */ public function __construct($from, Horde_Mime_Headers $h) { global $prefs; $addressList = $nameList = array(); /* First we'll get a comma separated list of email addresses * and a comma separated list of personal names out of $from * (there just might be more than one of each). */ $addr_list = IMP::parseAddressList($from); foreach ($addr_list as $addr) { if (!is_null($addr->mailbox)) { $addressList[] = $addr->bare_address; } if (!is_null($addr->personal)) { $nameList[] = $addr->personal; } elseif (!is_null($addr->mailbox)) { $nameList[] = $addr->mailbox; } } /* Define the macros. */ if (is_array($message_id = $h->getValue('message-id'))) { $message_id = reset($message_id); } if (!($subject = $h->getValue('subject'))) { $subject = _("[No Subject]"); } $udate = strtotime($h->getValue('date')); $match = array('/%n/' => "\n", '/%%/' => '%', '/%f/' => $from, '/%a/' => implode(', ', $addressList), '/%p/' => implode(', ', $nameList), '/%r/' => $h->getValue('date'), '/%d/' => strftime("%a, %d %b %Y", $udate), '/%x/' => strftime("%x", $udate), '/%c/' => strftime("%c", $udate), '/%m/' => $message_id, '/%s/' => $subject); $this->_text = preg_replace(array_keys($match), array_values($match), $prefs->getValue('attrib_text')); }
/** * @param Horde_Mime_Headers $data */ public function match($data) { if (!($ctype = $data->getValue('content-type', Horde_Mime_Headers::VALUE_BASE))) { return false; } @(list($primary, $sub) = explode('/', $ctype, 2)); return $primary == 'multipart' && !in_array($sub, array('alternative', 'encrypt', 'related', 'signed')); }
/** * Constructor. * * @param string|Horde_Mail_Rfc822_Object $from The email address of the * original sender. * @param Horde_Mime_Headers $h The headers object for * the message. * @param string $attrib Use this for the * attribution config * instead of the default * prefs version. */ public function __construct($from, Horde_Mime_Headers $h, $attrib = null) { global $prefs; $this->_text = preg_replace_callback('/\\%./', function ($matches) use($from, $h) { switch ($matches[0]) { case '%n': /* New line. */ return "\n"; case '%%': /* Percent character. */ return '%'; case '%f': /* Name and email address of original sender. */ if ($from) { $from = new Horde_Mail_Rfc822_Address($from); return $from->writeAddress(array('noquote' => true)); } return _("Unknown Sender"); case '%a': /* Senders email address(es). */ /* Senders email address(es). */ case '%p': /* Senders name(s). */ $out = array(); foreach (IMP::parseAddressList($from) as $addr) { if ($matches[0] == '%a') { if (!is_null($addr->mailbox)) { $out[] = $addr->bare_address; } } else { $out[] = $addr->label; } } return count($out) ? implode(', ', $out) : _("Unknown Sender"); case '%r': /* RFC 822 date and time. */ return $h->getValue('date'); case '%d': /* Date as ddd, dd mmm yyyy. */ return strftime("%a, %d %b %Y", strtotime($h->getValue('date'))); case '%c': /* Date and time in locale's default. */ /* Date and time in locale's default. */ case '%x': /* Date in locale's default. */ return strftime($matches[0], strtotime($h->getValue('date'))); case '%m': /* Message-ID. */ return is_array($message_id = $h->getValue('message-id')) ? reset($message_id) : $message_id; case '%s': /* Message subject. */ return strlen($subject = $h->getValue('subject')) ? $subject : _("[No Subject]"); default: return ''; } }, is_null($attrib) ? $prefs->getValue('attrib_text') : $attrib); }
public function testGenerate() { $h = new Horde_Mime_Headers(); $ob = new Horde_Mime_Mdn($h); try { $ob->generate(true, true, 'deleted', 'foo', null); $this->fail('Expected Exception'); } catch (RuntimeException $e) { } $date = 'Tue, 18 Nov 2014 20:14:17 -0700'; $mdn_addr = 'Aäb <*****@*****.**>'; $h->addHeader('Date', $date); $h->addHeader('Subject', 'Test'); $h->addHeader('To', '"BAR" <*****@*****.**>'); $ob->addMdnRequestHeaders($mdn_addr); $mailer = new Horde_Mail_Transport_Mock(); $ob->generate(true, true, 'displayed', 'test.example.com', $mailer, array('from_addr' => '*****@*****.**'), array('error'), array('error' => 'Foo')); $sent = str_replace("\r\n", "\n", $mailer->sentMessages[0]); $this->assertEquals('auto-replied', $sent['headers']['Auto-Submitted']); $this->assertEquals('*****@*****.**', $sent['headers']['From']); $this->assertEquals($mdn_addr, Horde_Mime::decode($sent['headers']['To'])); $this->assertEquals('Disposition Notification', $sent['headers']['Subject']); $this->assertStringMatchesFormat('This message is in MIME format. --=%s Content-Type: text/plain; format=flowed; DelSp=Yes The message sent on Tue, 18 Nov 2014 20:14:17 -0700 to BAR <*****@*****.**> with subject "Test" has been displayed. This is no guarantee that the message has been read or understood. --=%s Content-Type: message/disposition-notification Reporting-UA: test.example.com; Horde Application Framework 5 Final-Recipient: rfc822;bar@example.com Disposition: manual-action/MDN-sent-manually; displayed/error Error: Foo --=%s Content-Type: message/rfc822 Date: Tue, 18 Nov 2014 20:14:17 -0700 Subject: Test To: BAR <*****@*****.**> Disposition-Notification-To: =?utf-8?b?QcOkYg==?= <*****@*****.**> --=%s ', $sent['body']); }
/** * Sends a message to an email address supposed to be added to the * identity. * * A message is send to this address containing a time-sensitive link to * confirm that the address really belongs to that user. * * @param integer $id The identity's ID. * @param string $old_addr The old From: address. * * @throws Horde_Mime_Exception */ public function verifyIdentity($id, $old_addr) { global $injector, $notification, $registry; $hash = strval(new Horde_Support_Randomid()); $pref = $this->_confirmEmail(); $pref[$hash] = $this->get($id); $pref[$hash][self::EXPIRE] = time() + self::EXPIRE_SECS; $this->_confirmEmail($pref); $new_addr = $this->getValue($this->_prefnames['from_addr'], $id); $confirm = Horde::url($registry->getServiceLink('emailconfirm')->add('h', $hash)->setRaw(true), true); $message = sprintf(Horde_Core_Translation::t("You have requested to add the email address \"%s\" to the list of your personal email addresses.\n\nGo to the following link to confirm that this is really your address:\n%s\n\nIf you don't know what this message means, you can delete it."), $new_addr, $confirm); $msg_headers = new Horde_Mime_Headers(); $msg_headers->addHeaderOb(Horde_Mime_Headers_MessageId::create()); $msg_headers->addHeaderOb(Horde_Mime_Headers_UserAgent::create()); $msg_headers->addHeaderOb(Horde_Mime_Headers_Date::create()); $msg_headers->addHeader('To', $new_addr); $msg_headers->addHeader('From', $old_addr); $msg_headers->addHeader('Subject', Horde_Core_Translation::t("Confirm new email address")); $body = new Horde_Mime_Part(); $body->setType('text/plain'); $body->setContents(Horde_String::wrap($message, 76)); $body->setCharset('UTF-8'); $body->send($new_addr, $msg_headers, $injector->getInstance('Horde_Mail')); $notification->push(sprintf(Horde_Core_Translation::t("A message has been sent to \"%s\" to verify that this is really your address. The new email address is activated as soon as you confirm this message."), $new_addr), 'horde.message'); }
/** * Return the rendered information about the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _renderInfo() { global $registry; if ($registry->getView() == $registry::VIEW_MINIMAL) { return array(); } $status = array(); $mime_id = $this->_mimepart->getMimeId(); $headers = Horde_Mime_Headers::parseHeaders($this->getConfigParam('imp_contents')->getBodyPart($mime_id, array('length' => 0, 'mimeheaders' => true, 'stream' => true))->data); if (($duration = $headers->getValue('content-duration')) !== null) { $text = array(); if ($minutes = floor($duration / 60)) { $text[] = sprintf(ngettext(_("%d minute"), _("%d minutes"), $minutes), $minutes); } if ($seconds = $duration % 60) { $text[] = sprintf(ngettext(_("%d second"), _("%d seconds"), $seconds), $seconds); } $status[] = sprintf(_("This video file is reported to be %s in length."), implode(' ', $text)); } if ($this->_thumbnailBinary()) { $status[] = _("This is a thumbnail of a video attachment."); $status[] = $this->getConfigParam('imp_contents')->linkViewJS($this->_mimepart, 'view_attach', '<img src="' . $this->getConfigParam('imp_contents')->urlView($this->_mimepart, 'view_attach', array('params' => array('imp_video_view' => 'view_thumbnail'))) . '" />', null, null, null); } if (empty($status)) { return array(); } $s = new IMP_Mime_Status($status); $s->icon('mime/video.png'); return array($this->_mimepart->getMimeId() => array('data' => '', 'status' => $s, 'type' => 'text/html; charset=UTF-8')); }
/** * Cont'r * * @param array $params Parameters: * - factory: (Horde_ActiveSync_Interface_ImapFactory) Factory object * DEFAULT: none - REQUIRED */ public function __construct(array $params = array()) { $this->_imap = $params['factory']; Horde_Mime_Part::$defaultCharset = 'UTF-8'; Horde_Mime_Headers::$defaultCharset = 'UTF-8'; $this->_procid = getmypid(); $this->_logger = new Horde_Log_Logger(new Horde_Log_Handler_Null()); }
/** * Determines the priority of the message based on the headers. * * @param Horde_Mime_Headers $header The headers object. * * @return string 'high', 'low', or 'normal'. */ public function getPriority($header) { if (($xpriority = $header->getValue('x-priority')) && preg_match('/\\s*(\\d+)\\s*/', $xpriority, $matches)) { if (in_array($matches[1], array(1, 2))) { return 'high'; } elseif (in_array($matches[1], array(4, 5))) { return 'low'; } } elseif (($importance = $header->getValue('importance')) && preg_match('/:\\s*(\\w+)\\s*/', $importance, $matches)) { if (strcasecmp($matches[1], 'high') === 0) { return 'high'; } elseif (strcasecmp($matches[1], 'low') === 0) { return 'low'; } } return 'normal'; }
/** * See Bug #13456 Wnen we add the Message-Id/User-Agent headers, make sure * we don't cause the subject header to not be MIME encoded. */ public function testMIMEEncodingWhenStandardHeadersAreAdded() { $fixture = file_get_contents(__DIR__ . '/fixtures/mime_encoding.eml'); $rfc822 = new Horde_ActiveSync_Rfc822($fixture, true); $hdrs = Horde_Mime_Headers::parseHeaders($rfc822->getString()); $hdr_array = $hdrs->toArray(array('charset' => 'UTF-8')); $this->assertEquals('=?utf-8?b?w4PDhMOjw6s=?=', $hdr_array['Subject']); }
/** * Get the raw email data sent by this object. * * @param boolean $stream If true, return a stream resource, otherwise * a string is returned. * * @return stream|string The raw email data. * @since 2.4.0 */ public function getRaw($stream = true) { if ($stream) { $hdr = new Horde_Stream(); $hdr->add($this->_headers->toString(), true); return Horde_Stream_Wrapper_Combine::getStream(array($hdr->stream, $this->getBasePart()->toString(array('stream' => true, 'encode' => Horde_Mime_Part::ENCODE_7BIT | Horde_Mime_Part::ENCODE_8BIT | Horde_Mime_Part::ENCODE_BINARY)))); } return $this->_headers->toString() . $this->getBasePart()->toString(); }
/** * Get the raw email data sent by this object. * * @param boolean $stream If true, return a stream resource, otherwise * a string is returned. * * @return stream|string The raw email data. * @since 2.4.0 */ public function getRaw($stream = true) { if ($stream) { $hdr = new Horde_Stream(); $hdr->add($this->_headers->toString(), true); return Horde_Stream_Wrapper_Combine::getStream(array($hdr->stream, $this->getBasePart()->toString(array('stream' => true)))); } return $this->_headers->toString() . $this->_getBasePart->toString(); }
/** * TODO */ public function loadFixtures($dir) { $this->_fixtures = array(); $dh = opendir($dir); while (($dent = readdir($dh)) !== false) { if (!in_array($dent, array('.', '..'))) { $this->_fixtures[$dent] = Horde_Mime_Headers::parseHeaders(file_get_contents($dir . '/' . $dent)); } } closedir($dh); $i = 0; foreach (array_keys($this->_fixtures) as $key) { $this->_folders['INBOX'][] = array('uid' => ++$i, 'fixture' => $key, 'deleted' => false); } }
/** */ public function __isset($name) { switch ($name) { case 'reply_to': $name = 'reply-to'; // Fall-through // Fall-through case 'sender': if ($this->_data->getValue($name) !== null) { return true; } $name = 'from'; break; } return $this->_data->getValue($name) !== null; }
/** * Return the rendered information about the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _renderInfo() { $mime_id = $this->_mimepart->getMimeId(); $headers = Horde_Mime_Headers::parseHeaders($this->getConfigParam('imp_contents')->getBodyPart($mime_id, array('length' => 0, 'mimeheaders' => true, 'stream' => true))->data); if (($duration = $headers->getValue('content-duration')) === null) { return array(); } $text = array(); if ($minutes = floor($duration / 60)) { $text[] = sprintf(ngettext(_("%d minute"), _("%d minutes"), $minutes), $minutes); } if ($seconds = $duration % 60) { $text[] = sprintf(ngettext(_("%d second"), _("%d seconds"), $seconds), $seconds); } $status = new IMP_Mime_Status(sprintf(_("This audio file is reported to be %s in length."), implode(' ', $text))); $status->icon('mime/audio.png'); return array($this->_mimepart->getMimeId() => array('data' => '', 'status' => $status, 'type' => 'text/html; charset=UTF-8')); }
/** */ public function report(IMP_Contents $contents, $action) { global $injector, $registry; $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create(); switch ($this->_format) { case 'redirect': /* Send the message. */ try { $imp_compose->redirectMessage($contents->getIndicesOb()); $imp_compose->sendRedirectMessage($this->_email, false); return true; } catch (IMP_Compose_Exception $e) { $e->log(); } break; case 'digest': default: try { $from_line = $injector->getInstance('IMP_Identity')->getFromLine(); } catch (Horde_Exception $e) { $from_line = null; } /* Build the MIME structure. */ $mime = new Horde_Mime_Part(); $mime->setType('multipart/digest'); $rfc822 = new Horde_Mime_Part(); $rfc822->setType('message/rfc822'); $rfc822->setContents($contents->fullMessageText(array('stream' => true))); $mime->addPart($rfc822); $spam_headers = new Horde_Mime_Headers(); $spam_headers->addMessageIdHeader(); $spam_headers->addHeader('Date', date('r')); $spam_headers->addHeader('To', $this->_email); if (!is_null($from_line)) { $spam_headers->addHeader('From', $from_line); } $spam_headers->addHeader('Subject', sprintf(_("%s report from %s"), $action == IMP_Spam::SPAM ? 'spam' : 'innocent', $registry->getAuth())); /* Send the message. */ try { $recip_list = $imp_compose->recipientList(array('to' => $this->_email)); $imp_compose->sendMessage($recip_list['list'], $spam_headers, $mime, 'UTF-8'); $rfc822->clearContents(); return true; } catch (IMP_Compose_Exception $e) { $e->log(); $rfc822->clearContents(); } break; } return false; }
public function userConfirmationNeededProvider() { $out = array(); $h = new Horde_Mime_Headers(); $out[] = array(clone $h, true); $h->addHeader('Return-Path', '*****@*****.**'); $out[] = array(clone $h, false); $h->addHeader('Return-Path', '*****@*****.**'); $out[] = array(clone $h, true); $h->replaceHeader('Return-Path', '*****@*****.**'); $h->addHeader(Horde_Mime_Mdn::MDN_HEADER, '*****@*****.**'); $out[] = array(clone $h, true); $h->replaceHeader(Horde_Mime_Mdn::MDN_HEADER, '*****@*****.**'); $out[] = array(clone $h, false); return $out; }
/** */ public function __set($name, $value) { if (!strlen($value)) { return; } $name = $this->_normalizeProperty($name); switch ($name) { case 'bcc': case 'cc': case 'date': case 'from': case 'in-reply-to': case 'message-id': case 'reply-to': case 'sender': case 'subject': case 'to': switch ($name) { case 'from': if ($this->reply_to->match($value)) { unset($this->_data['reply-to']); } if ($this->sender->match($value)) { unset($this->_data['sender']); } break; case 'reply-to': case 'sender': if ($this->from->match($value)) { unset($this->_data[$name]); return; } break; } $this->_data->addHeader($name, $value); break; } }
/** * Retrieve locally cached message data. * * @param string $type Either 'hdr', 'hdrob', 'msg', 'size', 'stat', * or 'uidl'. * @param integer $index The message index. * @param mixed $data Additional information needed. * * @return mixed The cached data. 'msg' returns a stream resource. All * other types return strings. * * @throws Horde_Imap_Client_Exception */ protected function _pop3Cache($type, $index = null, $data = null) { if (isset($this->_temp['pop3cache'][$index][$type])) { if ($type == 'msg') { rewind($this->_temp['pop3cache'][$index][$type]); } return $this->_temp['pop3cache'][$index][$type]; } switch ($type) { case 'hdr': $data = null; if ($this->queryCapability('TOP')) { try { $resp = $this->_sendLine('TOP ' . $index . ' 0'); $ptr = $this->_getMultiline(); rewind($ptr); $data = stream_get_contents($ptr); fclose($ptr); } catch (Horde_Imap_Client_Exception $e) { } } if (is_null($data)) { $data = Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $index)), 'header', 0); } break; case 'hdrob': $data = Horde_Mime_Headers::parseHeaders($this->_pop3Cache('hdr', $index)); break; case 'msg': $resp = $this->_sendLine('RETR ' . $index); $data = $this->_getMultiline(); rewind($data); break; case 'size': case 'uidl': $data = array(); try { $this->_sendLine($type == 'size' ? 'LIST' : 'UIDL'); foreach ($this->_getMultiline(true) as $val) { $resp_data = explode(' ', $val, 2); $data[$resp_data[0]] = $resp_data[1]; } } catch (Horde_Imap_Client_Exception $e) { } break; case 'stat': $resp = $this->_sendLine('STAT'); $resp_data = explode(' ', $resp['line'], 2); $data = array('msgs' => $resp_data[0], 'size' => $resp_data[1]); break; } $this->_temp['pop3cache'][$index][$type] = $data; return $data; }
/** * Builds a Horde_Mime_Headers object from header text. * This function can be called statically: * $headers = Horde_Mime_Headers::parseHeaders(). * * @param string $text A text string containing the headers. * * @return Horde_Mime_Headers A new Horde_Mime_Headers object. */ public static function parseHeaders($text) { $currheader = $currtext = null; $mime = self::mimeParamFields(); $to_process = array(); foreach (explode("\n", $text) as $val) { $val = rtrim($val); if (empty($val)) { break; } if ($val[0] == ' ' || $val[0] == "\t") { $currtext .= ' ' . ltrim($val); } else { if (!is_null($currheader)) { $to_process[] = array($currheader, $currtext); } $pos = strpos($val, ':'); $currheader = substr($val, 0, $pos); $currtext = ltrim(substr($val, $pos + 1)); } } if (!is_null($currheader)) { $to_process[] = array($currheader, $currtext); } $headers = new Horde_Mime_Headers(); reset($to_process); while (list(, $val) = each($to_process)) { /* Ignore empty headers. */ if (!strlen($val[1])) { continue; } if (in_array(Horde_String::lower($val[0]), $mime)) { $res = Horde_Mime::decodeParam($val[0], $val[1]); $headers->addHeader($val[0], $res['val'], array('params' => $res['params'], 'sanity_check' => true)); } else { $headers->addHeader($val[0], $val[1], array('sanity_check' => true)); } } return $headers; }
private function _getMailHeaders() { if (isset($GLOBALS['injector']->getInstance('IMP_Mail')->sentMessages[0])) { $headers = Horde_Mime_Headers::parseHeaders($GLOBALS['injector']->getInstance('IMP_Mail')->sentMessages[0]['header_text']); if (!$headers instanceof Horde_Mime_Headers) { $this->fail('Failed parsing message headers!'); return new Horde_Mime_Headers(); } return $headers; } $this->fail('No message has been sent!'); }
/** * Add a MDN (read receipt) request header. * * @param mixed $to The address(es) the receipt should be mailed to. */ public function addMdnRequestHeaders($to) { /* This is the RFC 3798 way of requesting a receipt. */ $this->_headers->addHeader(self::MDN_HEADER, $to); }
/** * Get an IMAP message and retrieve the Kolab Format object. * * @param int $id The message to retrieve. * @param string $mime_type The mime type of the part to retrieve. * @param boolean $parse_headers Should the heades be Mime parsed? * @param array $formats The list of possible format parts. * * @return array|PEAR_Error An array that list the Kolab XML * object text, the mime ID of the part * with the XML object, the Mime parsed * message and the Mime parsed headers if * requested. */ function parseMessage($id, $mime_type, $parse_headers = true, $formats = array('XML')) { $raw_headers = $this->_driver->getMessageHeader($this->_path, $id); if (is_a($raw_headers, 'PEAR_Error')) { return PEAR::raiseError(sprintf(Horde_Kolab_Storage_Translation::t("Failed retrieving the message with ID %s. Original error: %s."), $id, $raw_headers->getMessage())); } $body = $this->_driver->getMessageBody($this->_path, $id); if (is_a($body, 'PEAR_Error')) { return PEAR::raiseError(sprintf(Horde_Kolab_Storage_Translation::t("Failed retrieving the message with ID %s. Original error: %s."), $id, $body->getMessage())); } //@todo: not setting "forcemime" means the subparts get checked too. Seems incorrect. $mime_message = Horde_Mime_Part::parseMessage($raw_headers . "\r" . $body, array('forcemime' => true)); $parts = $mime_message->contentTypeMap(); $mime_headers = false; $xml = false; // Read in a Kolab event object, if one exists $part_ids['XML'] = array_search($mime_type, $parts); if ($part_ids['XML'] !== false) { if ($parse_headers) { $mime_headers = Horde_Mime_Headers::parseHeaders($raw_headers); $mime_headers->setEOL("\r\n"); } $part = $mime_message->getPart($part_ids['XML']); //@todo: Check what happened to this call //$part->transferDecodeContents(); $xml = $part->getContents(); } $alternate_formats = array_diff(array('XML'), $formats); if (!empty($alternate_formats)) { foreach ($alternate_formats as $type) { $part_ids[$type] = false; } foreach ($mime_message->getParts() as $part) { $params = $part->getDispositionParameters(); foreach ($alternate_formats as $type) { if (isset($params['x-kolab-format']) && $params['x-kolab-format'] == $type) { $part_ids[$type] = $part->getMimeId(); } } } } $result = array($xml, $part_ids, $mime_message, $mime_headers); return $result; }
/** * Retrieves a complete message. * * @param string $folder The folder to fetch the messages from. * @param array $uid The message UID. * * @return array The message encapsuled as an array that contains a * Horde_Mime_Headers and a Horde_Mime_Part object. */ public function fetchComplete($folder, $uid) { $msg = $this->getBackend()->handlePartBody($this->encodePath($folder), $uid, true, '', null, false); if ($this->getBackend()->errornum != 0) { throw new Horde_Kolab_Storage_Exception(sprintf(Horde_Kolab_Storage_Translation::t("Failed fetching message %s in folder %s.") . ' ' . Horde_Kolab_Storage_Translation::t("Error: %s"), $uid, $folder, $this->getBackend()->error)); } return array(Horde_Mime_Headers::parseHeaders($msg), Horde_Mime_Part::parseMessage(Horde_Mime_Part::getRawPartText($msg, 'body', 0))); }
/** * Retrieves a complete message. * * @param string $folder The folder to fetch the messages from. * @param array $uid The message UID. * * @return array The message encapsuled as an array that contains a * Horde_Mime_Headers and a Horde_Mime_Part object. */ public function fetchComplete($folder, $uid) { $this->select($folder); return array(Horde_Mime_Headers::parseHeaders(Horde_Kolab_Storage_Exception_Pear::catchError($this->getBackend()->getRawHeaders($uid, '', true))), Horde_Mime_Part::parseMessage(Horde_Kolab_Storage_Exception_Pear::catchError($this->getBackend()->getBody($uid, true)))); }
/** * Retrieve locally cached message data. * * @param string $type Either 'hdr', 'hdrob', 'msg', 'size', 'stat', * 'top', or 'uidl'. * @param integer $index The message index. * @param mixed $data Additional information needed. * * @return mixed The cached data. 'msg' returns a stream resource. All * other types return strings. * * @throws Horde_Imap_Client_Exception */ protected function _pop3Cache($type, $index = self::MBOX_CACHE, $data = null) { if (isset($this->_temp['pop3cache'][$index][$type])) { if ($type == 'msg') { rewind($this->_temp['pop3cache'][$index][$type]); } return $this->_temp['pop3cache'][$index][$type]; } switch ($type) { case 'hdr': case 'top': $data = null; if ($type == 'top' || $this->_capability('TOP')) { try { $res = $this->_sendLine('TOP ' . $index . ' 0', array('multiline' => 'stream')); rewind($res['data']); $data = stream_get_contents($res['data']); fclose($res['data']); } catch (Horde_Imap_Client_Exception $e) { $this->_temp['no_top'] = true; if ($type == 'top') { return null; } } } if (is_null($data)) { $data = Horde_Mime_Part::getRawPartText(stream_get_contents($this->_pop3Cache('msg', $index)), 'header', 0); } break; case 'hdrob': $data = Horde_Mime_Headers::parseHeaders($this->_pop3Cache('hdr', $index)); break; case 'msg': $res = $this->_sendLine('RETR ' . $index, array('multiline' => 'stream')); $data = $res['data']; rewind($data); break; case 'size': case 'uidl': $data = array(); try { $res = $this->_sendLine($type == 'size' ? 'LIST' : 'UIDL', array('multiline' => 'array')); foreach ($res['data'] as $val) { $resp_data = explode(' ', $val, 2); $data[$resp_data[0]] = $resp_data[1]; } } catch (Horde_Imap_Client_Exception $e) { if ($type == 'uidl') { $this->_temp['no_uidl'] = true; } } break; case 'stat': $resp = $this->_sendLine('STAT'); $resp_data = explode(' ', $resp['resp'], 2); $data = array('msgs' => $resp_data[0], 'size' => $resp_data[1]); break; } $this->_temp['pop3cache'][$index][$type] = $data; return $data; }
/** * Return the response as a MIME message. * * @param Horde_Itip_Response_Type $type The response type. * @param Horde_Itip_Response_Options $options The options for the response. * * @return array A list of two object: The mime headers and the mime * message. */ public function getMessage(Horde_Itip_Response_Type $type, Horde_Itip_Response_Options $options) { $message = new Horde_Mime_Part(); $message->setType('text/calendar'); $options->prepareIcsMimePart($message); $message->setContents($this->getIcalendar($type, $options)->exportvCalendar()); $message->setEOL("\r\n"); $this->_setIcsFilename($message); $message->setContentTypeParameter('METHOD', 'REPLY'); // Build the reply headers. $from = $this->_resource->getFrom(); $reply_to = $this->_resource->getReplyTo(); $headers = new Horde_Mime_Headers(); $headers->addHeaderOb(Horde_Mime_Headers_Date::create()); $headers->addHeader('From', $from); $headers->addHeader('To', $this->_request->getOrganizer()); if (!empty($reply_to) && $reply_to != $from) { $headers->addHeader('Reply-to', $reply_to); } $headers->addHeader('Subject', $type->getSubject()); $options->prepareResponseMimeHeaders($headers); return array($headers, $message); }
/** * Return the message headers. * * @return Horde_Mime_Headers The header object. */ public function getHeaders() { if (!empty($this->_header_text)) { $hdr_text = $this->_header_text; } else { $this->_stream->rewind(); $hdr_text = $this->_stream->substring(0, $this->_hdr_pos); } return Horde_Mime_Headers::parseHeaders($hdr_text); }
/** * Retrieves the message headers. * * @param string $folder The folder to fetch the message from. * @param array $uid The message UID. * * @return Horde_Mime_Headers The message headers. */ public function fetchHeaders($folder, $uid) { $query = new Horde_Imap_Client_Fetch_Query(); $query->headerText(); try { $ret = $this->getBackend()->fetch($folder, $query, array('ids' => new Horde_Imap_Client_Ids($uid))); $msg = $ret[$uid]->getHeaderText(); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { throw new Horde_Kolab_Storage_Exception($e->details); } catch (Horde_Imap_Client_Exception $e) { throw new Horde_Kolab_Storage_Exception($e); } return Horde_Mime_Headers::parseHeaders($msg); }
/** * Variables required in form input: * - identity (TODO: ? Code uses it, but it is never set anywhere) * - imple_submit: itip_action(s) * - mime_id * - muid * * @return boolean True on success. */ protected function _handle(Horde_Variables $vars) { global $injector, $notification, $registry; $actions = (array) $vars->imple_submit; $result = false; $vCal = new Horde_Icalendar(); /* Retrieve the calendar data from the message. */ try { $contents = $injector->getInstance('IMP_Factory_Contents')->create(new IMP_Indices_Mailbox($vars)); $mime_part = $contents->getMIMEPart($vars->mime_id); if (empty($mime_part)) { throw new IMP_Exception(_("Cannot retrieve calendar data from message.")); } elseif (!$vCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) { throw new IMP_Exception(_("The calendar data is invalid")); } $components = $vCal->getComponents(); } catch (Exception $e) { $notification->push($e, 'horde.error'); $actions = array(); } foreach ($actions as $key => $action) { $pos = strpos($key, '['); $key = substr($key, $pos + 1, strlen($key) - $pos - 2); switch ($action) { case 'delete': // vEvent cancellation. if ($registry->hasMethod('calendar/delete')) { $guid = $components[$key]->getAttribute('UID'); $recurrenceId = null; try { // This is a cancellation of a recurring event instance. $recurrenceId = $components[$key]->getAttribute('RECURRENCE-ID'); $atts = $components[$key]->getAttribute('RECURRENCE-ID', true); $range = null; foreach ($atts as $att) { if (array_key_exists('RANGE', $att)) { $range = $att['RANGE']; } } } catch (Horde_Icalendar_Exception $e) { } try { $registry->call('calendar/delete', array($guid, $recurrenceId, $range)); $notification->push(_("Event successfully deleted."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error deleting the event: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'update': // vEvent reply. if ($registry->hasMethod('calendar/updateAttendee')) { try { $from = $contents->getHeader()->getOb('from'); $registry->call('calendar/updateAttendee', array($components[$key], $from[0]->bare_address)); $notification->push(_("Respondent Status Updated."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error updating the event: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'import': case 'accept-import': // vFreebusy reply. // vFreebusy publish. // vEvent request. // vEvent publish. // vTodo publish. // vJournal publish. switch ($components[$key]->getType()) { case 'vEvent': $result = $this->_handlevEvent($key, $components, $mime_part); // Must check for exceptions. foreach ($components as $k => $component) { try { if ($component->getType() == 'vEvent' && $component->getAttribute('RECURRENCE-ID')) { $uid = $component->getAttribute('UID'); if ($uid == $components[$key]->getAttribute('UID')) { $this->_handlevEvent($k, $components, $mime_part); } } } catch (Horde_Icalendar_Exception $e) { } } break; case 'vFreebusy': // Import into Kronolith. if ($registry->hasMethod('calendar/import_vfreebusy')) { try { $registry->call('calendar/import_vfreebusy', array($components[$key])); $notification->push(_("The user's free/busy information was sucessfully stored."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error importing user's free/busy information: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'vTodo': // Import into Nag. if ($registry->hasMethod('tasks/import')) { try { $guid = $registry->call('tasks/import', array($components[$key], $mime_part->getType())); $url = Horde::url($registry->link('tasks/show', array('uid' => $guid))); $notification->push(_("The task has been added to your tasklist.") . ' ' . Horde::link($url, _("View task"), null, '_blank') . Horde_Themes_Image::tag('mime/icalendar.png', array('alt' => _("View task"))) . '</a>', 'horde.success', array('content.raw')); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error importing the task: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'vJournal': default: $notification->push(_("This action is not supported."), 'horde.warning'); } if ($action == 'import') { break; } // Fall-through for 'accept-import' // Fall-through for 'accept-import' case 'accept': case 'deny': case 'tentative': // vEvent request. if (isset($components[$key]) && $components[$key]->getType() == 'vEvent') { $vEvent = $components[$key]; $resource = new Horde_Itip_Resource_Identity($injector->getInstance('IMP_Identity'), $vEvent->getAttribute('ATTENDEE'), $vars->identity); switch ($action) { case 'accept': case 'accept-import': $type = new Horde_Itip_Response_Type_Accept($resource); break; case 'deny': $type = new Horde_Itip_Response_Type_Decline($resource); break; case 'tentative': $type = new Horde_Itip_Response_Type_Tentative($resource); break; } try { // Send the reply. Horde_Itip::factory($vEvent, $resource)->sendMultiPartResponse($type, new Horde_Core_Itip_Response_Options_Horde('UTF-8', array()), $injector->getInstance('IMP_Mail')); $notification->push(_("Reply Sent."), 'horde.success'); $result = true; } catch (Horde_Itip_Exception $e) { $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'send': case 'reply': case 'reply2m': // vfreebusy request. if (isset($components[$key]) && $components[$key]->getType() == 'vFreebusy') { $vFb = $components[$key]; // Get the organizer details. try { $organizer = parse_url($vFb->getAttribute('ORGANIZER')); } catch (Horde_Icalendar_Exception $e) { break; } $organizerEmail = $organizer['path']; $organizer = $vFb->getAttribute('ORGANIZER', true); $organizerFullEmail = new Horde_Mail_Rfc822_Address($organizerEmail); if (isset($organizer['cn'])) { $organizerFullEmail->personal = $organizer['cn']; } if ($action == 'reply2m') { $startStamp = time(); $endStamp = $startStamp + 60 * 24 * 3600; } else { try { $startStamp = $vFb->getAttribute('DTSTART'); } catch (Horde_Icalendar_Exception $e) { $startStamp = time(); } try { $endStamp = $vFb->getAttribute('DTEND'); } catch (Horde_Icalendar_Exception $e) { } if (!$endStamp) { try { $duration = $vFb->getAttribute('DURATION'); $endStamp = $startStamp + $duration; } catch (Horde_Icalendar_Exception $e) { $endStamp = $startStamp + 60 * 24 * 3600; } } } $vfb_reply = $registry->call('calendar/getFreeBusy', array($startStamp, $endStamp)); // Find out who we are and update status. $identity = $injector->getInstance('IMP_Identity'); $email = $identity->getFromAddress(); // Build the reply. $msg_headers = new Horde_Mime_Headers(); $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//' . $msg_headers->getUserAgent() . '//EN'); $vCal->setAttribute('METHOD', 'REPLY'); $vCal->addComponent($vfb_reply); $message = _("Attached is a reply to a calendar request you sent."); $body = new Horde_Mime_Part(); $body->setType('text/plain'); $body->setCharset('UTF-8'); $body->setContents(Horde_String::wrap($message, 76)); $ics = new Horde_Mime_Part(); $ics->setType('text/calendar'); $ics->setCharset('UTF-8'); $ics->setContents($vCal->exportvCalendar()); $ics->setName('icalendar.ics'); $ics->setContentTypeParameter('METHOD', 'REPLY'); $mime = new Horde_Mime_Part(); $mime->addPart($body); $mime->addPart($ics); // Build the reply headers. $msg_headers->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name'])); $msg_headers->addMessageIdHeader(); $msg_headers->addHeader('Date', date('r')); $msg_headers->addHeader('From', $email); $msg_headers->addHeader('To', $organizerFullEmail); $identity->setDefault($vars->identity); $replyto = $identity->getValue('replyto_addr'); if (!empty($replyto) && !$email->match($replyto)) { $msg_headers->addHeader('Reply-To', $replyto); } $msg_headers->addHeader('Subject', _("Free/Busy Request Response")); // Send the reply. try { $mime->send($organizerEmail, $msg_headers, $injector->getInstance('IMP_Mail')); $notification->push(_("Reply Sent."), 'horde.success'); $result = true; } catch (Exception $e) { $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("Invalid Action selected for this component."), 'horde.warning'); } break; case 'nosup': // vFreebusy request. // vFreebusy request. default: $notification->push(_("This action is not supported."), 'horde.warning'); break; } } return $result; }
/** * Prepare the iCalendar MIME part of the response message. * * @param Horde_Mime_Part $ics The iCalendar MIME part of the response * message. * * @return NULL */ public function prepareResponseMimeHeaders(Horde_Mime_Headers $headers) { $headers->addHeaderOb(Horde_Mime_Headers_MessageId::create()); }