Beispiel #1
0
 /**
  * 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'));
 }
Beispiel #2
0
 /**
  * @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'));
 }
Beispiel #3
0
 /**
  * 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);
 }
Beispiel #4
0
    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']);
    }
Beispiel #5
0
 /**
  * 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');
 }
Beispiel #6
0
 /**
  * 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'));
 }
Beispiel #7
0
 /**
  * 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());
 }
Beispiel #8
0
 /**
  * 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';
 }
Beispiel #9
0
 /**
  * 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']);
 }
Beispiel #10
0
 /**
  * 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();
 }
Beispiel #11
0
 /**
  * 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();
 }
Beispiel #12
0
 /**
  * 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);
     }
 }
Beispiel #13
0
 /**
  */
 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;
 }
Beispiel #14
0
 /**
  * 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'));
 }
Beispiel #15
0
 /**
  */
 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;
 }
Beispiel #16
0
 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;
 }
Beispiel #17
0
 /**
  */
 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;
     }
 }
Beispiel #18
0
 /**
  * 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;
 }
Beispiel #19
0
 /**
  * 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;
 }
Beispiel #20
0
 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!');
 }
Beispiel #21
0
 /**
  * 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);
 }
Beispiel #22
0
 /**
  * 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;
 }
Beispiel #23
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)
 {
     $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)));
 }
Beispiel #24
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))));
 }
Beispiel #25
0
 /**
  * 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;
 }
Beispiel #26
0
 /**
  * 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);
 }
Beispiel #27
0
 /**
  * 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);
 }
Beispiel #28
0
 /**
  * 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);
 }
Beispiel #29
0
 /**
  * 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.") . '&nbsp;' . 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;
 }
Beispiel #30
0
 /**
  * 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());
 }