getAttribute() публичный Метод

Get the value of an attribute.
public getAttribute ( string $name, boolean $params = false ) : mixed
$name string The name of the attribute.
$params boolean Return the parameters for this attribute instead of its value.
Результат mixed (string) The value of the attribute. (array) The parameters for the attribute or multiple values for an attribute.
Пример #1
0
 /**
  * @requires extension bcmath
  */
 public function testvTodo()
 {
     $tnef = Horde_Compress::factory('Tnef');
     $mime = Horde_Mime_Part::parseMessage(file_get_contents(__DIR__ . '/fixtures/tnef_task.eml'));
     try {
         $tnef_data = $tnef->decompress($mime->getPart(2)->getContents());
     } catch (Horde_Mapi_Exception $e) {
         $this->markTestSkipped('Horde_Mapi is not available');
     } catch (Horde_Compress_Exception $e) {
         var_dump($e);
     }
     // Test the generated iCalendar.
     $iCal = new Horde_Icalendar();
     if (!$iCal->parsevCalendar($tnef_data[0]['stream'])) {
         throw new Horde_Compress_Exception(_("There was an error importing the iCalendar data."));
     }
     $this->assertEquals($iCal->getAttribute('METHOD'), 'REQUEST');
     $components = $iCal->getComponents();
     if (count($components) == 0) {
         throw new Horde_Compress_Exception(_("No iCalendar data was found."));
     }
     $vTodo = current($components);
     $this->assertEquals($vTodo->getAttribute('SUMMARY'), 'Test Task');
     $this->assertEquals($vTodo->getAttribute('UID'), 'EDF71E6FA6FB69A79D79FE1D6DCDBBD300000000DFD9B6FB');
     $this->assertEquals($vTodo->getAttribute('ATTENDEE'), 'Michael Rubinsky <*****@*****.**>');
     $params = $vTodo->getAttribute('ATTENDEE', true);
     if (!$params) {
         throw new Horde_Compress_Exception('Could not find expected parameters.');
     }
     $this->assertEquals($params[0]['ROLE'], 'REQ-PARTICIPANT');
     $this->assertEquals($vTodo->getAttribute('ORGANIZER'), 'mailto: mike@theupstairsroom.com');
 }
Пример #2
0
 /**
  * Builds a proper AS mail message object.
  *
  * @param Horde_Imap_Client_Mailbox    $mbox  The IMAP mailbox.
  * @param Horde_Imap_Client_Data_Fetch $data  The fetch results.
  * @param array $options                      Additional Options:
  *   - truncation:  (integer) Truncate the message body to this length.
  *                  DEFAULT: No truncation.
  *   - bodyprefs: (array)  Bodyprefs, if sent from device.
  *                DEFAULT: none (No body prefs sent or enforced).
  *   - bodypartprefs: (array)  Bodypartprefs, if sent from device.
  *                DEFAULT: none (No body part prefs sent or enforced).
  *   - mimesupport: (integer)  Indicates if MIME is supported or not.
  *                  Possible values: 0 - Not supported 1 - Only S/MIME or
  *                  2 - All MIME.
  *                  DEFAULT: 0 (No MIME support)
  *   - protocolversion: (float)  The EAS protocol version to support.
  *                      DEFAULT: 2.5
  *
  * @return Horde_ActiveSync_Message_Mail  The message object suitable for
  *                                        streaming to the device.
  */
 protected function _buildMailMessage(Horde_Imap_Client_Mailbox $mbox, Horde_Imap_Client_Data_Fetch $data, $options = array())
 {
     $version = empty($options['protocolversion']) ? Horde_ActiveSync::VERSION_TWOFIVE : $options['protocolversion'];
     $imap_message = new Horde_ActiveSync_Imap_Message($this->_getImapOb(), $mbox, $data);
     $eas_message = Horde_ActiveSync::messageFactory('Mail');
     // Build To: data (POOMMAIL_TO has a max length of 32768).
     $to = $imap_message->getToAddresses();
     $eas_message->to = array_pop($to['to']);
     foreach ($to['to'] as $to_atom) {
         if (strlen($eas_message->to) + strlen($to_atom) > 32768) {
             break;
         }
         $eas_message->to .= ',' . $to_atom;
     }
     $eas_message->displayto = implode(';', $to['displayto']);
     if (empty($eas_message->displayto)) {
         $eas_message->displayto = $eas_message->to;
     }
     // Ensure we don't send broken UTF8 data to the client. It makes clients
     // angry. And we don't like angry clients.
     $hdr_charset = $imap_message->getStructure()->getHeaderCharset();
     // Fill in other header data
     try {
         $eas_message->from = $imap_message->getFromAddress();
     } catch (Horde_ActiveSync_Exception $e) {
         $this->_logger->err($e->getMessage());
     }
     try {
         $eas_message->cc = $imap_message->getCc();
     } catch (Horde_ActiveSync_Exception $e) {
         $this->_logger->err($e->getMessage());
     }
     try {
         $eas_message->reply_to = $imap_message->getReplyTo();
     } catch (Horde_ActiveSync_Exception $e) {
         $this->_logger->err($e->getMessage());
     }
     $eas_message->subject = Horde_ActiveSync_Utils::ensureUtf8($imap_message->getSubject(), $hdr_charset);
     $eas_message->threadtopic = $eas_message->subject;
     $eas_message->datereceived = $imap_message->getDate();
     $eas_message->read = $imap_message->getFlag(Horde_Imap_Client::FLAG_SEEN);
     // Default to IPM.Note - may change below depending on message content.
     $eas_message->messageclass = 'IPM.Note';
     // Codepage id. MS recommends to always set to UTF-8 when possible.
     // See http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756%28v=vs.85%29.aspx
     $eas_message->cpid = Horde_ActiveSync_Message_Mail::INTERNET_CPID_UTF8;
     // Message importance. First try X-Priority, then Importance since
     // Outlook sends the later.
     if ($priority = $imap_message->getHeaders()->getValue('X-priority')) {
         $priority = preg_replace('/\\D+/', '', $priority);
     } else {
         $priority = $imap_message->getHeaders()->getValue('Importance');
     }
     $eas_message->importance = $this->_getEASImportance($priority);
     // Get the body data.
     $mbd = $imap_message->getMessageBodyDataObject($options);
     if ($version == Horde_ActiveSync::VERSION_TWOFIVE) {
         $eas_message->body = $mbd->plain['body']->stream;
         $eas_message->bodysize = $mbd->plain['body']->length(true);
         $eas_message->bodytruncated = $mbd->plain['truncated'];
         $eas_message->attachments = $imap_message->getAttachments($version);
     } else {
         // Get the message body and determine original type.
         if ($mbd->html) {
             $eas_message->airsyncbasenativebodytype = Horde_ActiveSync::BODYPREF_TYPE_HTML;
         } else {
             $eas_message->airsyncbasenativebodytype = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
         }
         $airsync_body = Horde_ActiveSync::messageFactory('AirSyncBaseBody');
         $body_type_pref = $mbd->getBodyTypePreference();
         if ($body_type_pref == Horde_ActiveSync::BODYPREF_TYPE_MIME) {
             $this->_logger->info(sprintf('[%s] Sending MIME Message.', $this->_procid));
             // ActiveSync *REQUIRES* all data sent to be in UTF-8, so we
             // must convert the body parts to UTF-8. Unfortunately if the
             // email is signed (or encrypted for that matter) we can't
             // alter the data in anyway or the signature will not be
             // verified, so we fetch the entire message and hope for the best.
             if (!$imap_message->isSigned() && !$imap_message->isEncrypted()) {
                 $mime = new Horde_Mime_Part();
                 if ($mbd->plain) {
                     $plain_mime = new Horde_Mime_Part();
                     $plain_mime->setType('text/plain');
                     $plain_mime->setContents($mbd->plain['body']->stream, array('usestream' => true));
                     $plain_mime->setCharset('UTF-8');
                 }
                 if ($mbd->html) {
                     $html_mime = new Horde_Mime_Part();
                     $html_mime->setType('text/html');
                     $html_mime->setContents($mbd->html['body']->stream, array('usestream' => true));
                     $html_mime->setCharset('UTF-8');
                 }
                 // Sanity check the mime type
                 if (!$mbd->html && !empty($plain_mime)) {
                     $mime = $plain_mime;
                 } elseif (!$mbd->plain && !empty($html_mime)) {
                     $mime = $html_mime;
                 } elseif (!empty($plain_mime) && !empty($html_mime)) {
                     $mime->setType('multipart/alternative');
                     $mime->addPart($plain_mime);
                     $mime->addPart($html_mime);
                 }
                 $html_mime = null;
                 $plain_mime = null;
                 // If we have attachments, create a multipart/mixed wrapper.
                 if ($imap_message->hasAttachments()) {
                     $base = new Horde_Mime_Part();
                     $base->setType('multipart/mixed');
                     $base->addPart($mime);
                     $atc = $imap_message->getAttachmentsMimeParts();
                     foreach ($atc as $atc_part) {
                         $base->addPart($atc_part);
                     }
                     $eas_message->airsyncbaseattachments = $imap_message->getAttachments($version);
                 } else {
                     $base = $mime;
                 }
                 $mime = null;
                 // Populate the EAS body structure with the MIME data, but
                 // remove the Content-Type and Content-Transfer-Encoding
                 // headers since we are building this ourselves.
                 $headers = $imap_message->getHeaders();
                 $headers->removeHeader('Content-Type');
                 $headers->removeHeader('Content-Transfer-Encoding');
                 $airsync_body->data = $base->toString(array('headers' => $headers, 'stream' => true));
                 $airsync_body->estimateddatasize = $base->getBytes();
             } else {
                 // Signed/Encrypted message - can't mess with it at all.
                 $raw = new Horde_ActiveSync_Rfc822($imap_message->getFullMsg(true), false);
                 $airsync_body->estimateddatasize = $raw->getBytes();
                 $airsync_body->data = $raw->getString();
                 $eas_message->airsyncbaseattachments = $imap_message->getAttachments($version);
             }
             $airsync_body->type = Horde_ActiveSync::BODYPREF_TYPE_MIME;
             // MIME Truncation
             // @todo Remove this sanity-check hack in 3.0. This is needed
             // since truncationsize incorrectly defaulted to a
             // MIME_TRUNCATION constant and could be cached in the sync-cache.
             $ts = !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_MIME]['truncationsize']) ? $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_MIME]['truncationsize'] : false;
             $mime_truncation = !empty($ts) && $ts > 9 ? $ts : (!empty($options['truncation']) && $options['truncation'] > 9 ? $options['truncation'] : false);
             $this->_logger->info(sprintf('[%s] Checking MIMETRUNCATION: %s, ServerData: %s', $this->_procid, $mime_truncation, $airsync_body->estimateddatasize));
             if (!empty($mime_truncation) && $airsync_body->estimateddatasize > $mime_truncation) {
                 ftruncate($airsync_body->data, $mime_truncation);
                 $airsync_body->truncated = '1';
             } else {
                 $airsync_body->truncated = '0';
             }
             $eas_message->airsyncbasebody = $airsync_body;
         } elseif ($body_type_pref == Horde_ActiveSync::BODYPREF_TYPE_HTML) {
             // Sending non MIME encoded HTML message text.
             $eas_message->airsyncbasebody = $this->_buildHtmlPart($mbd, $airsync_body);
             $eas_message->airsyncbaseattachments = $imap_message->getAttachments($version);
         } elseif ($body_type_pref == Horde_ActiveSync::BODYPREF_TYPE_PLAIN) {
             // Non MIME encoded plaintext
             $this->_logger->info(sprintf('[%s] Sending PLAINTEXT Message.', $this->_procid));
             if (!empty($mbd->plain['size'])) {
                 $airsync_body->estimateddatasize = $mbd->plain['size'];
                 $airsync_body->truncated = $mbd->plain['truncated'];
                 $airsync_body->data = $mbd->plain['body']->stream;
                 $airsync_body->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
                 $eas_message->airsyncbasebody = $airsync_body;
             }
             $eas_message->airsyncbaseattachments = $imap_message->getAttachments($version);
         }
         // It's legal to have both a BODY and a BODYPART, so we must also
         // check for that.
         if ($version > Horde_ActiveSync::VERSION_FOURTEEN && !empty($options['bodypartprefs'])) {
             $body_part = Horde_ActiveSync::messageFactory('AirSyncBaseBodypart');
             $eas_message->airsyncbasebodypart = $this->_buildBodyPart($mbd, $options, $body_part);
         }
         if ($version > Horde_ActiveSync::VERSION_TWELVEONE) {
             $flags = array();
             $msgFlags = $this->_getMsgFlags();
             foreach ($imap_message->getFlags() as $flag) {
                 if (!empty($msgFlags[Horde_String::lower($flag)])) {
                     $flags[] = $msgFlags[Horde_String::lower($flag)];
                 }
             }
             $eas_message->categories = $flags;
         }
     }
     // Body Preview? Note that this is different from BodyPart's preview
     if ($version >= Horde_ActiveSync::VERSION_FOURTEEN && !empty($options['bodyprefs']['preview'])) {
         $mbd->plain['body']->rewind();
         $eas_message->airsyncbasebody->preview = $mbd->plain['body']->substring(0, $options['bodyprefs']['preview']);
     }
     $mbd = null;
     // Check for special message types.
     if ($imap_message->isEncrypted()) {
         $eas_message->messageclass = 'IPM.Note.SMIME';
     } elseif ($imap_message->isSigned()) {
         $eas_message->messageclass = 'IPM.Note.SMIME.MultipartSigned';
     }
     $part = $imap_message->getStructure();
     if ($part->getType() == 'multipart/report') {
         $ids = array_keys($imap_message->contentTypeMap());
         reset($ids);
         $part1_id = next($ids);
         $part2_id = Horde_Mime::mimeIdArithmetic($part1_id, 'next');
         $lines = explode(chr(13), $imap_message->getBodyPart($part2_id, array('decode' => true)));
         switch ($part->getContentTypeParameter('report-type')) {
             case 'delivery-status':
                 foreach ($lines as $line) {
                     if (strpos(trim($line), 'Action:') === 0) {
                         switch (trim(substr(trim($line), 7))) {
                             case 'failed':
                                 $eas_message->messageclass = 'REPORT.IPM.NOTE.NDR';
                                 break 2;
                             case 'delayed':
                                 $eas_message->messageclass = 'REPORT.IPM.NOTE.DELAYED';
                                 break 2;
                             case 'delivered':
                                 $eas_message->messageclass = 'REPORT.IPM.NOTE.DR';
                                 break 2;
                         }
                     }
                 }
                 break;
             case 'disposition-notification':
                 foreach ($lines as $line) {
                     if (strpos(trim($line), 'Disposition:') === 0) {
                         if (strpos($line, 'displayed') !== false) {
                             $eas_message->messageclass = 'REPORT.IPM.NOTE.IPNRN';
                         } elseif (strpos($line, 'deleted') !== false) {
                             $eas_message->messageclass = 'REPORT.IPM.NOTE.IPNNRN';
                         }
                         break;
                     }
                 }
         }
     }
     $part = null;
     // Check for meeting requests and POOMMAIL_FLAG data
     if ($version >= Horde_ActiveSync::VERSION_TWELVE) {
         $eas_message->contentclass = 'urn:content-classes:message';
         if ($mime_part = $imap_message->hasiCalendar()) {
             $data = Horde_ActiveSync_Utils::ensureUtf8($mime_part->getContents(), $mime_part->getCharset());
             $vCal = new Horde_Icalendar();
             if ($vCal->parsevCalendar($data, 'VCALENDAR', $mime_part->getCharset())) {
                 $classes = $vCal->getComponentClasses();
             } else {
                 $classes = array();
             }
             if (!empty($classes['horde_icalendar_vevent'])) {
                 try {
                     $method = $vCal->getAttribute('METHOD');
                     $eas_message->contentclass = 'urn:content-classes:calendarmessage';
                 } catch (Horde_Icalendar_Exception $e) {
                 }
                 switch ($method) {
                     case 'REQUEST':
                     case 'PUBLISH':
                         $eas_message->messageclass = 'IPM.Schedule.Meeting.Request';
                         $mtg = Horde_ActiveSync::messageFactory('MeetingRequest');
                         $mtg->fromvEvent($vCal);
                         $eas_message->meetingrequest = $mtg;
                         break;
                     case 'REPLY':
                         try {
                             $reply_status = $this->_getiTipStatus($vCal);
                             switch ($reply_status) {
                                 case 'ACCEPTED':
                                     $eas_message->messageclass = 'IPM.Schedule.Meeting.Resp.Pos';
                                     break;
                                 case 'DECLINED':
                                     $eas_message->messageclass = 'IPM.Schedule.Meeting.Resp.Neg';
                                     break;
                                 case 'TENTATIVE':
                                     $eas_message->messageclass = 'IPM.Schedule.Meeting.Resp.Tent';
                             }
                             $mtg = Horde_ActiveSync::messageFactory('MeetingRequest');
                             $mtg->fromvEvent($vCal);
                             $eas_message->meetingrequest = $mtg;
                         } catch (Horde_ActiveSync_Exception $e) {
                             $this->_logger->err($e->getMessage());
                         }
                 }
             }
         }
         if ($imap_message->getFlag(Horde_Imap_Client::FLAG_FLAGGED)) {
             $poommail_flag = Horde_ActiveSync::messageFactory('Flag');
             $poommail_flag->subject = $imap_message->getSubject();
             $poommail_flag->flagstatus = Horde_ActiveSync_Message_Flag::FLAG_STATUS_ACTIVE;
             $poommail_flag->flagtype = Horde_Imap_Client::FLAG_FLAGGED;
             $eas_message->flag = $poommail_flag;
         }
     }
     if ($version >= Horde_ActiveSync::VERSION_FOURTEEN) {
         $eas_message->messageid = $imap_message->getHeaders()->getValue('Message-ID');
         $eas_message->forwarded = $imap_message->getFlag(Horde_Imap_Client::FLAG_FORWARDED);
         $eas_message->answered = $imap_message->getFlag(Horde_Imap_Client::FLAG_ANSWERED);
     }
     $imap_message = null;
     return $eas_message;
 }
Пример #3
0
 /**
  * Handle parsing recurrence related fields.
  *
  * @param Horde_Icalendar $vEvent
  * @throws Kronolith_Exception
  */
 protected function _handlevEventRecurrence($vEvent)
 {
     // Recurrence.
     try {
         $rrule = $vEvent->getAttribute('RRULE');
         if (!is_array($rrule)) {
             $this->recurrence = new Horde_Date_Recurrence($this->start);
             if (strpos($rrule, '=') !== false) {
                 $this->recurrence->fromRRule20($rrule);
             } else {
                 $this->recurrence->fromRRule10($rrule);
             }
             /* Delete all existing exceptions to this event if it
              * already exists */
             if (!empty($this->uid)) {
                 $kronolith_driver = Kronolith::getDriver(null, $this->calendar);
                 $search = new StdClass();
                 $search->start = $this->recurrence->getRecurStart();
                 $search->end = $this->recurrence->getRecurEnd();
                 $search->baseid = $this->uid;
                 $results = $kronolith_driver->search($search);
                 foreach ($results as $days) {
                     foreach ($days as $exception) {
                         $kronolith_driver->deleteEvent($exception->id);
                     }
                 }
             }
             // Exceptions. EXDATE represents deleted events, just add the
             // exception, no new event is needed.
             $exdates = $vEvent->getAttributeValues('EXDATE');
             if (is_array($exdates)) {
                 foreach ($exdates as $exdate) {
                     if (is_array($exdate)) {
                         $this->recurrence->addException((int) $exdate['year'], (int) $exdate['month'], (int) $exdate['mday']);
                     }
                 }
             }
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // RECURRENCE-ID indicates that this event represents an exception
     try {
         $recurrenceid = $vEvent->getAttribute('RECURRENCE-ID');
         $kronolith_driver = Kronolith::getDriver(null, $this->calendar);
         $originaldt = new Horde_Date($recurrenceid);
         $this->exceptionoriginaldate = $originaldt;
         $this->baseid = $this->uid;
         $this->uid = null;
         try {
             $originalEvent = $kronolith_driver->getByUID($this->baseid);
             $originalEvent->recurrence->addException($originaldt->format('Y'), $originaldt->format('m'), $originaldt->format('d'));
             $originalEvent->save();
         } catch (Horde_Exception_NotFound $e) {
             throw new Kronolith_Exception(_("Unable to locate original event series."));
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
 }
Пример #4
0
 /**
  * Return a reference to a new component.
  *
  * @param string $type                The type of component to return
  * @param Horde_Icalendar $container  A container that this component
  *                                    will be associated with.
  *
  * @return object  Reference to a Horde_Icalendar_* object as specified.
  */
 public static function newComponent($type, $container)
 {
     $type = Horde_String::lower($type);
     $class = __CLASS__ . '_' . Horde_String::ucfirst($type);
     if (class_exists($class)) {
         $component = new $class();
         if ($container !== false) {
             $component->_container = $container;
             // Use version of container, not default set by component
             // constructor.
             $component->setVersion($container->getAttribute('VERSION'));
         }
     } else {
         // Should return an dummy x-unknown type class here.
         $component = false;
     }
     return $component;
 }
Пример #5
0
 /**
  * Return the rendered inline version of the Horde_Mime_Part object.
  *
  * @return array  See parent::render().
  */
 protected function _renderInline()
 {
     $GLOBALS['page_output']->growler = true;
     $data = $this->_mimepart->getContents();
     $mime_id = $this->_mimepart->getMimeId();
     // Parse the iCal file.
     $vCal = new Horde_Icalendar();
     if (!$vCal->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) {
         $status = new IMP_Mime_Status($this->_mimepart, _("The calendar data is invalid"));
         $status->action(IMP_Mime_Status::ERROR);
         return array($mime_id => array('data' => '', 'status' => $status, 'type' => 'text/html; charset=UTF-8'));
     }
     // Check if we got vcard data with the wrong vcalendar mime type.
     $imp_contents = $this->getConfigParam('imp_contents');
     $c = $vCal->getComponentClasses();
     if (count($c) == 1 && !empty($c['horde_icalendar_vcard'])) {
         return $imp_contents->renderMIMEPart($mime_id, IMP_Contents::RENDER_INLINE, array('type' => 'text/x-vcard'));
     }
     $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_ItipRequest', array('mime_id' => $mime_id, 'muid' => strval($imp_contents->getIndicesOb())));
     // Get the method type.
     try {
         $method = $vCal->getAttribute('METHOD');
     } catch (Horde_Icalendar_Exception $e) {
         $method = '';
     }
     $out = array();
     $exceptions = array();
     $components = $vCal->getComponents();
     foreach ($components as $key => $component) {
         switch ($component->getType()) {
             case 'vEvent':
                 try {
                     if ($component->getAttribute('RECURRENCE-ID')) {
                         $exceptions[] = $this->_vEvent($component, $key, $method, $components);
                     }
                 } catch (Horde_ICalendar_Exception $e) {
                     $out[] = $this->_vEvent($component, $key, $method, $components);
                 }
                 break;
             case 'vTodo':
                 $out[] = $this->_vTodo($component, $key, $method);
                 break;
             case 'vTimeZone':
                 // Ignore them.
                 break;
             case 'vFreebusy':
                 $out[] = $this->_vFreebusy($component, $key, $method);
                 break;
                 // @todo: handle stray vcards here as well.
             // @todo: handle stray vcards here as well.
             default:
                 $out[] = sprintf(_("Unhandled component of type: %s"), $component->getType());
                 break;
         }
     }
     // If we don't have any other parts, any exceptions should be shown
     // since this is likely an update to a series instance such as a
     // cancellation etc...
     if (empty($out)) {
         $out = $exceptions;
     }
     $view = $this->_getViewOb();
     $view->formid = $imple->getDomId();
     $view->out = implode('', $out);
     return array($mime_id => array('data' => $view->render('base'), 'type' => 'text/html; charset=UTF-8'));
 }
Пример #6
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));
         if (!($mime_part = $contents->getMimePart($vars->mime_id))) {
             throw new IMP_Exception(_("Cannot retrieve calendar data from message."));
         }
         if ($vars->ctype) {
             $mime_part = clone $mime_part;
             $mime_part->setType($vars->ctype);
         }
         if (!$vCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) {
             throw new IMP_Exception(_("The calendar data is invalid"));
         }
         $components = $vCal->getComponents();
         $v1 = $vCal->getAttribute('VERSION') == '1.0';
     } 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]->getAttributeSingle('UID');
                     $recurrenceId = null;
                     $range = null;
                     try {
                         // This is a cancellation of a recurring event instance.
                         $recurrenceId = $components[$key]->getAttributeSingle('RECURRENCE-ID');
                         $atts = $components[$key]->getAttribute('RECURRENCE-ID', true);
                         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.
                 // vTodo reply.
                 switch ($components[$key]->getType()) {
                     case 'vEvent':
                         if ($registry->hasMethod('calendar/updateAttendee')) {
                             try {
                                 if ($tmp = $contents->getHeader()->getHeader('from')) {
                                     $registry->call('calendar/updateAttendee', array($components[$key], $tmp->getAddressList(true)->first()->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 'vTodo':
                         if ($registry->hasMethod('tasks/updateAttendee')) {
                             try {
                                 if ($tmp = $contents->getHeader()->getHeader('from')) {
                                     $registry->call('tasks/updateAttendee', array($components[$key], $tmp->getAddressList(true)->first()->bare_address));
                                     $notification->push(_("Respondent Status Updated."), 'horde.success');
                                     $result = true;
                                 }
                             } catch (Horde_Exception $e) {
                                 $notification->push(sprintf(_("There was an error updating the task: %s"), $e->getMessage()), 'horde.error');
                             }
                         } else {
                             $notification->push(_("This action is not supported."), 'horde.warning');
                         }
                         break;
                 }
                 break;
             case 'import':
             case 'accept-import':
                 // vFreebusy reply.
                 // vFreebusy publish.
                 // vEvent request.
                 // vEvent publish.
                 // vTodo publish.
                 // vJournal publish.
                 switch ($components[$key]->getType()) {
                     case 'vEvent':
                         // If we have accepted and are importing, update the
                         // user's attendance status in the vCal so it will be
                         // reflected when it is imported.
                         if ($action == 'accept-import') {
                             try {
                                 $a = $components[$key]->getAttribute('ATTENDEE');
                                 if (!is_array($a)) {
                                     $a = array($a);
                                 }
                                 $a_params = $components[$key]->getAttribute('ATTENDEE', true);
                                 foreach ($a as $a_key => $attendee) {
                                     $attendee_email = preg_replace('/mailto:/i', '', $attendee);
                                     $identity = $injector->getInstance('IMP_Identity');
                                     if (!is_null($id = $identity->getMatchingIdentity($attendee_email))) {
                                         $components[$key]->removeAttribute('ATTENDEE');
                                         if ($v1) {
                                             $a_params[$a_key]['STATUS'] = 'ACCEPTED';
                                         } else {
                                             $a_params[$a_key]['PARTSTAT'] = 'ACCEPTED';
                                         }
                                         foreach ($a as $ai_key => $i_attendee) {
                                             $components[$key]->setAttribute('ATTENDEE', $i_attendee, $a_params[$ai_key]);
                                         }
                                         break;
                                     }
                                 }
                             } catch (Horde_Icalendar_Exception $e) {
                                 $notification->push(sprintf(_("There was an error updating attendee status: %s"), $e->getMessage()), 'horde.error');
                             }
                         }
                         // Handle the import, and check for exceptions.
                         $result = $this->_handlevEvent($key, $components, $mime_part);
                         foreach ($components as $k => $component) {
                             try {
                                 if ($component->getType() == 'vEvent' && $component->getAttribute('RECURRENCE-ID')) {
                                     $uid = $component->getAttributeSingle('UID');
                                     if ($uid == $components[$key]->getAttributeSingle('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' || $components[$key]->getType() == 'vTodo')) {
                     $vEvent = $components[$key];
                     try {
                         $resource = new Horde_Itip_Resource_Identity($injector->getInstance('IMP_Identity'), $vEvent->getAttribute('ATTENDEE'), $vars->identity);
                     } catch (Horde_Icalendar_Exception $e) {
                         throw new Horde_Itip_Exception('No ATTENDEE data, unable to reply.');
                     }
                     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 {
                         if ($vEvent->getType() == 'vEvent') {
                             // Send the reply.
                             Horde_Itip::factory($vEvent, $resource)->sendMultiPartResponse($type, new Horde_Core_Itip_Response_Options_Horde('UTF-8', array()), $injector->getInstance('IMP_Mail'));
                         } elseif ($vEvent->getType() == 'vTodo') {
                             Horde_Itip::vTodoFactory($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->getAttributeSingle('ORGANIZER'));
                     } catch (Horde_Icalendar_Exception $e) {
                         break;
                     }
                     $organizerEmail = $organizer['path'];
                     $organizer = $vFb->getAttributeSingle('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->getAttributeSingle('DTSTART');
                         } catch (Horde_Icalendar_Exception $e) {
                             $startStamp = time();
                         }
                         try {
                             $endStamp = $vFb->getAttributeSingle('DTEND');
                         } catch (Horde_Icalendar_Exception $e) {
                         }
                         if (!$endStamp) {
                             try {
                                 $duration = $vFb->getAttributeSingle('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();
                     $vCal = new Horde_Icalendar();
                     $vCal->setAttribute('PRODID', '-//The Horde Project//' . strval(Horde_Mime_Headers_UserAgent::create()) . '//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[] = $body;
                     $mime[] = $ics;
                     // Build the reply headers.
                     $msg_headers = new Horde_Mime_Headers();
                     $msg_headers->addHeaderOb(Horde_Core_Mime_Headers_Received::createHordeHop());
                     $msg_headers->addHeaderOb(Horde_Mime_Headers_MessageId::create());
                     $msg_headers->addHeaderOb(Horde_Mime_Headers_Date::create());
                     $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;
 }
Пример #7
0
 /**
  * Parses the various exception related fields. Only deal with the EXDATE
  * field here.
  *
  * @param Horde_Icalendar $vEvent  The vEvent part.
  */
 protected function _handlevEventRecurrence($vEvent)
 {
     // Recurrence.
     try {
         $rrule = $vEvent->getAttribute('RRULE');
         if (!is_array($rrule)) {
             $this->recurrence = new Horde_Date_Recurrence($this->start);
             if (strpos($rrule, '=') !== false) {
                 $this->recurrence->fromRRule20($rrule);
             } else {
                 $this->recurrence->fromRRule10($rrule);
             }
             // Exceptions. EXDATE represents deleted events, just add the
             // exception, no new event is needed.
             $exdates = $vEvent->getAttributeValues('EXDATE');
             if (is_array($exdates)) {
                 foreach ($exdates as $exdate) {
                     if (is_array($exdate)) {
                         $this->recurrence->addException((int) $exdate['year'], (int) $exdate['month'], (int) $exdate['mday']);
                     }
                 }
             }
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
 }
Пример #8
0
 /**
  * Handle parsing recurrence related fields.
  *
  * @param Horde_Icalendar $vEvent
  * @throws Kronolith_Exception
  */
 protected function _handlevEventRecurrence($vEvent)
 {
     // Recurrence.
     try {
         $rrule = $vEvent->getAttribute('RRULE');
         if (!is_array($rrule)) {
             $this->recurrence = new Horde_Date_Recurrence($this->start);
             if (strpos($rrule, '=') !== false) {
                 $this->recurrence->fromRRule20($rrule);
             } else {
                 $this->recurrence->fromRRule10($rrule);
             }
             // Exceptions. EXDATE represents deleted events, just add the
             // exception, no new event is needed.
             $exdates = $vEvent->getAttributeValues('EXDATE');
             if (is_array($exdates)) {
                 foreach ($exdates as $exdate) {
                     if (is_array($exdate)) {
                         $this->recurrence->addException((int) $exdate['year'], (int) $exdate['month'], (int) $exdate['mday']);
                     }
                 }
             }
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // RECURRENCE-ID indicates that this event represents an exception
     try {
         $this->recurrenceid = $vEvent->getAttribute('RECURRENCE-ID');
         $originaldt = new Horde_Date($this->recurrenceid);
         $this->exceptionoriginaldate = $originaldt;
         $this->baseid = $this->uid;
         $this->uid = null;
         try {
             $originalEvent = $this->getDriver()->getByUID($this->baseid);
             $originalEvent->recurrence->addException($originaldt->format('Y'), $originaldt->format('m'), $originaldt->format('d'));
             $originalEvent->save();
         } catch (Horde_Exception_NotFound $e) {
             throw new Kronolith_Exception(_("Unable to locate original event series."));
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
 }