/** * Constructor. * * @param Horde_Mime_Part $mime_part A MIME part object. Must be of * type multipart/related. */ public function __construct(Horde_Mime_Part $mime_part) { if ($mime_part->getType() != 'multipart/related') { throw new InvalidArgumentException('MIME part must be of type multipart/related'); } $ids = array_keys($mime_part->contentTypeMap()); $related_id = $mime_part->getMimeId(); $id = null; /* Build a list of parts -> CIDs. */ foreach ($ids as $val) { if (strcmp($related_id, $val) !== 0 && ($cid = $mime_part->getPart($val)->getContentId())) { $this->_cids[$val] = $cid; } } /* Look at the 'start' parameter to determine which part to start * with. If no 'start' parameter, use the first part (RFC 2387 * [3.1]). */ $start = $mime_part->getContentTypeParameter('start'); if (!empty($start)) { $id = $this->cidSearch($start); } if (empty($id)) { reset($ids); $id = next($ids); } $this->_start = $id; }
/** * Return the MIME part of the iCalendar attachment, if available. * * @return mixed The mime id of an iCalendar part, if present. Otherwise * false. */ public function hasiCalendar() { if (!$this->hasAttachments()) { return false; } foreach ($this->_base->contentTypeMap() as $id => $type) { if ($type == 'text/calendar' || $type == 'application/ics') { return $id; } } return false; }
/** * Return the MIME part of the iCalendar attachment, if available. * * @return mixed The mime part, if present, false otherwise. */ public function hasiCalendar() { if (!$this->hasAttachments()) { return false; } foreach ($this->_base->contentTypeMap() as $id => $type) { if ($type == 'text/calendar') { return $this->_base->getPart($id); } } return false; }
/** * Signs a MIME part using PGP. * * @param Horde_Mime_Part $mime_part The object to sign. * @param array $params The parameters required for signing. * ({@see _encryptSignature()}). * * @return mixed A Horde_Mime_Part object that is signed according to RFC * 3156. * @throws Horde_Crypt_Exception */ public function signMIMEPart($mime_part, $params = array()) { $params = array_merge($params, array('sigtype' => 'detach', 'type' => 'signature')); /* RFC 3156 Requirements for a PGP signed message: * + Content-Type params 'micalg' & 'protocol' are REQUIRED. * + The digitally signed message MUST be constrained to 7 bits. * + The MIME headers MUST be a part of the signed data. * + Ensure there are no trailing spaces in encoded data by forcing * text to be Q-P encoded (see, e.g., RFC 3676 [4.6]). */ /* Ensure that all text parts are Q-P encoded. */ foreach ($mime_part->contentTypeMap(false) as $key => $val) { if (strpos($val, 'text/') === 0) { $mime_part[$key]->setTransferEncoding('quoted-printable', array('send' => true)); } } /* Get the signature. */ $msg_sign = $this->encrypt($mime_part->toString(array('canonical' => true, 'headers' => true)), $params); /* Add the PGP signature. */ $pgp_sign = new Horde_Mime_Part(); $pgp_sign->setType('application/pgp-signature'); $pgp_sign->setHeaderCharset('UTF-8'); $pgp_sign->setDisposition('inline'); $pgp_sign->setDescription(Horde_Crypt_Translation::t("PGP Digital Signature")); $pgp_sign->setContents($msg_sign, array('encoding' => '7bit')); /* Get the algorithim information from the signature. Since we are * analyzing a signature packet, we need to use the special keyword * '_SIGNATURE' - see Horde_Crypt_Pgp. */ $sig_info = $this->pgpPacketSignature($msg_sign, '_SIGNATURE'); /* Setup the multipart MIME Part. */ $part = new Horde_Mime_Part(); $part->setType('multipart/signed'); $part->setContents("This message is in MIME format and has been PGP signed.\n"); $part->addPart($mime_part); $part->addPart($pgp_sign); $part->setContentTypeParameter('protocol', 'application/pgp-signature'); $part->setContentTypeParameter('micalg', $sig_info['micalg']); return $part; }
public function testIdSortingInMessageRfc822Part() { $part = new Horde_Mime_Part(); $part->setType('message/rfc822'); $part1 = new Horde_Mime_Part(); $part1->setType('multipart/alternative'); $part[] = $part1; $part2 = new Horde_Mime_Part(); $part2->setType('text/plain'); $part1[] = $part2; $part3 = new Horde_Mime_Part(); $part3->setType('text/html'); $part1[] = $part3; $part->buildMimeIds(); $this->assertEquals(array('1.0', '1', '1.1', '1.2'), array_keys($part->contentTypeMap(true))); }
/** * Try to determine the MIME part that carries an object matching based on the message headers. * * @param Horde_Mime_Part $structure A structural representation of the mime message. * @param Horde_Mime_Headers $headers The message headers. * * @return string|boolean The MIME ID of the message part carrying an object matching the message headers or false if such a part was not identified within the message. */ public static function matchMimePartToHeaderType(Horde_Mime_Part $structure, Horde_Mime_Headers $headers) { $mime_type = $headers->getValue('X-Kolab-Type'); if ($mime_type === null) { return false; } return array(array_search($mime_type, $structure->contentTypeMap()), self::getObjectTypeFromMimeType($mime_type)); }
/** * Returns the Content-Type map for the entire message, regenerating * embedded parts if needed. * * @return array See Horde_Mime_Part::contentTypeMap(). */ public function getContentTypeMap() { $this->_buildMessage(); return $this->_message->contentTypeMap(); }