Copyright 2009-2014 Horde LLC (http://www.horde.org/) See the enclosed file COPYING for license information (LGPL). If you did not receive this file, see http://www.horde.org/licenses/lgpl21.
저자: Michael J Rubinsky (mrubinsk@horde.org)
예제 #1
0
 /**
  * Test parsing GOID value.
  */
 public function testParseGlobalObjectId()
 {
     // Outlook UID
     $fixture = 'BAAAAIIA4AB0xbcQGoLgCAfUCRDgQMnBJoXEAQAAAAAAAAAAEAAAAAvw7UtuTulOnjnjhns3jvM=';
     $uid = Horde_Mapi::getUidFromGoid($fixture);
     $this->assertEquals('040000008200E00074C5B7101A82E00800000000E040C9C12685C4010000000000000000100000000BF0ED4B6E4EE94E9E39E3867B378EF3', $uid);
     // vCal
     $fixture = 'BAAAAIIA4AB0xbcQGoLgCAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAAHZDYWwtVWlkAQAAAHs4MTQxMkQzQy0yQTI0LTRFOUQtQjIwRS0xMUY3QkJFOTI3OTl9AA==';
     $uid = Horde_Mapi::getUidFromGoid($fixture);
     $this->assertEquals('{81412D3C-2A24-4E9D-B20E-11F7BBE92799}', $uid);
 }
예제 #2
0
 /**
  * Build an MAPI TZ blob given a TZ Offset hash.
  *
  * @param array $offsets  A TZ offset hash
  *
  * @return string  A base64_encoded MAPI Timezone structure suitable
  *                 for transmitting via wbxml.
  */
 public static function getSyncTZFromOffsets(array $offsets)
 {
     if (!Horde_Mapi::isLittleEndian()) {
         $offsets['bias'] = Horde_Mapi::chbo($offsets['bias']);
         $offsets['stdbias'] = Horde_Mapi::chbo($offsets['stdbias']);
         $offsets['dstbias'] = Horde_Mapi::chbo($offsets['dstbias']);
     }
     $packed = pack('la64vvvvvvvvla64vvvvvvvvl', $offsets['bias'], '', 0, $offsets['stdmonth'], $offsets['stdday'], $offsets['stdweek'], $offsets['stdhour'], $offsets['stdminute'], $offsets['stdsecond'], $offsets['stdmillis'], $offsets['stdbias'], '', 0, $offsets['dstmonth'], $offsets['dstday'], $offsets['dstweek'], $offsets['dsthour'], $offsets['dstminute'], $offsets['dstsecond'], $offsets['dstmillis'], $offsets['dstbias']);
     return base64_encode($packed);
 }
예제 #3
0
파일: VTodo.php 프로젝트: raz0rsdge/horde
 /**
  * Allow this object to set any MAPI attributes it needs to know about,
  * ignore any it doesn't care about.
  *
  * @param integer $type  The attribute type descriptor.
  * @param integer $name  The attribute name descriptor.
  */
 public function setMapiAttribute($type, $name, $value, $ns = null)
 {
     if ($ns == Horde_Compress_Tnef::PSETID_COMMON) {
         switch ($name) {
             case Horde_Compress_Tnef::IPM_TASK_GUID:
                 // Almost positive this is wrong :(
                 $this->_guid = Horde_Mapi::getUidFromGoid(bin2hex($value));
                 break;
             case Horde_Compress_Tnef::MSG_EDITOR_FORMAT:
                 // Map this?
                 $this->_msgformat = $value;
                 break;
             case Horde_Compress_Tnef::MAPI_TAG_BODY:
                 // plaintext. Most likely set via the attBody TNEF attribute,
                 // and not by the MAPI property.
                 if (empty($this->_bodyPlain)) {
                     $this->_bodyPlain = $value;
                 }
                 break;
             case Horde_Compress_Tnef::MAPI_TAG_HTML:
                 // html
                 $this->_bodyHtml = $value;
                 break;
             case self::MAPI_TASK_COMMONSTART:
                 try {
                     $this->_start = new Horde_Date(Horde_Mapi::filetimeToUnixtime($value));
                 } catch (Horde_Date_Exception $e) {
                     throw new Horde_Compress_Exception($e);
                 }
                 $this->_start = $this->_start->timestamp();
                 break;
             case self::MAPI_TASK_COMMONEND:
                 try {
                     $this->_due = new Horde_Date(Horde_Mapi::filetimeToUnixtime($value));
                 } catch (Horde_Mapi_Exception $e) {
                     throw new Horde_Compress_Exception($e);
                 } catch (Horde_Date_Exception $e) {
                     throw new Horde_Compress_Exception($e);
                 }
                 $this->_due = $this->_due->timestamp();
                 break;
         }
     } elseif ($ns == Horde_Compress_Tnef::PSETID_TASK) {
         switch ($name) {
             case self::MAPI_TASK_OWNER:
                 // This is the OWNER, not to be confused with the ORGANIZER.
                 // I.e., this is the person the task has been assigned to.
                 // The ORGANIZER is the person who created the task and has
                 // assigned it. I.e., the person that any task updates are
                 // sent back to by the owner.
                 $this->_owner = str_replace(array('(', ')'), array('<', '>'), $value);
                 break;
             case self::MAPI_TASK_DUEDATE:
                 // Favor COMMONEND
                 if (empty($this->_due)) {
                     $this->_due = Horde_Mapi::filetimeToUnixtime($value);
                 }
                 break;
             case self::MAPI_TASK_STARTDATE:
                 if (empty($this->_start)) {
                     $this->_start = Horde_Mapi::filetimeToUnixtime($value);
                 }
                 break;
             case self::MAPI_TASK_DATECOMPLETED:
                 $this->_completed = Horde_Mapi::filetimeToUnixtime($value);
                 break;
             case self::MAPI_TASK_PERCENTCOMPLETE:
                 $value = unpack('d', $value);
                 $this->_percentComplete = $value[1] * 100;
                 break;
             case self::MAPI_TASK_STATUS:
                 switch ($value) {
                     case self::STATUS_NOT_STARTED:
                     case self::STATUS_WAIT:
                     case self::STATUS_DEFERRED:
                         $this->_percentComplete = 0;
                         $this->_status = self::TASK_STATUS_ACTION;
                         break;
                     case self::STATUS_IN_PROGRESS:
                         $this->_status = self::TASK_STATUS_IN_PROGRESS;
                         break;
                     case self::STATUS_COMPLETE:
                         $this->_status = self::TASK_STATUS_COMPLETED;
                         $this->_percentComplete = 1;
                         break;
                 }
                 break;
             case self::MAPI_TASK_UPDATES:
                 if (!empty($value)) {
                     $this->_updates = true;
                 }
                 break;
             case self::MAPI_TASK_OWNERSHIP:
                 $this->_ownership = $value;
                 break;
             case self::MAPI_TASK_STATE:
                 $this->_state = $value;
                 break;
                 // case self::MAPI_TASK_ASSIGNER:
                 //     // *sigh* This isn't set by Outlook/Exchange until AFTER the
                 //     // assignee receives the request. I.e., this is blank on the initial
                 //     // REQUEST so not a valid way to obtain the task creator.
                 //     //$this->_organizer = $value;
                 //     break;
                 // case self::MAPI_TASK_LASTUSER:
                 //     // From MS-OXOTASK 2.2.2.2.25:
                 //     // Before client sends a REQUEST, it is set to the assigner.
                 //     // Before client sends an ACCEPT, it is set to the assignee.
                 //     // Before client sneds REJECT, it is set to the assigner, not assignee.
                 //     // Unfortunately, it is only the display name, not the email!
                 //     $this->_lastUser = $value;
                 //     break;
         }
     } else {
         // pidTag?
         switch ($name) {
             case Horde_Compress_Tnef::MAPI_SENT_REP_EMAIL_ADDR:
                 $this->_organizer = $value;
                 break;
             case Horde_Compress_Tnef::MAPI_LAST_MODIFIER_NAME:
                 $this->_lastUser = $value;
         }
     }
 }
예제 #4
0
 /**
  * Parses a vEvent into the message properties.
  *
  * @param Horde_Icalendar_Vevent $vevent  The vEvent to parse.
  * @param string $method                  The method (e.g., 'REQUEST').
  *
  * @throws Horde_ActiveSync_Exception
  */
 protected function _parsevEvent($vevent, $method = 'REQUEST')
 {
     if ($method == 'REQUEST') {
         $this->responserequested = '1';
     } else {
         $this->responserequested = '0';
     }
     try {
         $organizer = parse_url($vevent->getAttribute('ORGANIZER'));
         $this->organizer = $organizer['path'];
     } catch (Horde_Icalendar_Exception $e) {
     }
     try {
         $this->globalobjid = Horde_Mapi::createGoid($vevent->getAttribute('UID'));
         $this->starttime = new Horde_Date($vevent->getAttribute('DTSTART'));
         $this->endtime = new Horde_Date($vevent->getAttribute('DTEND'));
     } catch (Horde_Exception $e) {
         throw new Horde_ActiveSync_Exception($e);
     }
     try {
         $this->dtstamp = new Horde_Date($vevent->getAttribute('DTSTAMP'));
     } catch (Horde_Exception $e) {
     }
     try {
         $this->location = Horde_String::truncate($vevent->getAttribute('LOCATION'), 255);
     } catch (Horde_Icalendar_Exception $e) {
     }
     try {
         $class = $vevent->getAttribute('CLASS');
         if (!is_array($class)) {
             $this->sensitivity = $class == 'PRIVATE' ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PRIVATE : ($class == 'CONFIDENTIAL' ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_CONFIDENTIAL : ($class == 'PERSONAL' ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PERSONAL : Horde_ActiveSync_Message_Appointment::SENSITIVITY_NORMAL));
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     try {
         $status = $vevent->getAttribute('STATUS');
         if (!is_array($status)) {
             $status = Horde_String::upper($status);
             $this->busystatus = $status == 'TENTATIVE' ? Horde_ActiveSync_Message_Appointment::BUSYSTATUS_TENTATIVE : ($status == 'CONFIRMED' ? Horde_ActiveSync_Message_Appointment::BUSYSTATUS_BUSY : Horde_ActiveSync_Message_Appointment::BUSYSTATUS_FREE);
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // vCalendar 1.0 alarms
     try {
         $alarm = $vevent->getAttribute('AALARM');
         if (!is_array($alarm) && intval($alarm)) {
             $this->reminder = intval($this->starttime->timestamp() - $alarm);
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // vCalendar 2.0 alarms
     foreach ($vevent->getComponents() as $alarm) {
         if (!$alarm instanceof Horde_Icalendar_Valarm) {
             continue;
         }
         try {
             $trigger = $alarm->getAttribute('TRIGGER');
             $triggerParams = $alarm->getAttribute('TRIGGER', true);
         } catch (Horde_Icalendar_Exception $e) {
             continue;
         }
         if (isset($triggerParams['VALUE']) && $triggerParams['VALUE'] == 'DATE-TIME') {
             if (isset($triggerParams['RELATED']) && $triggerParams['RELATED'] == 'END') {
                 $this->reminder = intval($this->endtime->timestamp() - $trigger);
             } else {
                 $this->reminder = intval($this->starttime->timestamp() - $trigger);
             }
         } else {
             $this->reminder = -intval($trigger);
         }
     }
 }
예제 #5
0
 /**
  * Parse recurrence properties.
  *
  * @param string  $value MAPI stream
  *
  * @return Horde_Date_Recurrence
  * @throws  Horde_Compress_Exception
  */
 protected function _parseRecurrence($value)
 {
     $deleted = $modified = array();
     // both are 0x3004 (version strings);
     $this->_geti($value, 16);
     $this->_geti($value, 16);
     $freq = $this->_geti($value, 16);
     $pattern = $this->_geti($value, 16);
     $calendarType = $this->_geti($value, 16);
     $firstDt = $this->_geti($value, 32);
     $period = $this->_geti($value, 32);
     // Only used for tasks, otherwise value must be zero.
     $flag = $this->_geti($value, 32);
     // TypeSpecific field
     switch ($pattern) {
         case Horde_Compress_Tnef::PATTERN_DAY:
             // Nothing here to see, move along.
             break;
         case Horde_Compress_Tnef::PATTERN_WEEK:
             // Bits: 0/unused, 1/Saturday, 2/Friday, 3/Thursday, 4/Wednesday,
             // 5/Tuesday, 6/Monday, 7/Sunday.
             $day = $this->_geti($value, 8);
             // ??
             $this->_geti($value, 24);
             break;
         case Horde_Compress_Tnef::PATTERN_MONTH:
         case Horde_Compress_Tnef::PATTERN_MONTH_END:
             // Day of month on which the recurrence falls.
             $day = $this->_geti($value, 32);
             break;
         case Horde_Compress_Tnef::PATTERN_MONTH_NTH:
             // Bits: 0/unused, 1/Saturday, 2/Friday, 3/Thursday, 4/Wednesday,
             // 5/Tuesday, 6/Monday, 7/Sunday.
             // For Nth Weekday of month
             $day = $this->_geti($value, 8);
             $this->_geti($value, 24);
             $n = $this->_geti($value, 32);
             break;
     }
     $end = $this->_geti($value, 32);
     $count = $this->_geti($value, 32);
     $fdow = $this->_geti($value, 32);
     $deletedCount = $this->_geti($value, 32);
     for ($i = 0; $i < $deletedCount; $i++) {
         $deleted[] = $this->_geti($value, 32);
     }
     $modifiedCount = $this->_geti($value, 32);
     for ($i = 0; $i < $modifiedCount; $i++) {
         $modified[] = $this->_geti($value, 32);
     }
     // What Timezone are these in?
     try {
         $startDate = new Horde_Date(Horde_Mapi::filetimeToUnixtime($this->_geti($value, 32)));
         $endDate = new Horde_Date(Horde_Mapi::filetimeToUnixtime($this->_geti($value, 32)));
     } catch (Horde_Mapi_Exception $e) {
         throw new Horde_Compress_Exception($e);
     } catch (Horde_Date_Exception $e) {
         throw new Horde_Compress_Exception($e);
     }
     $rrule = new Horde_Date_Recurrence($startDate);
     switch ($pattern) {
         case Horde_Compress_Tnef::PATTERN_DAY:
             $rrule->setRecurType(Horde_Date_Recurrence::RECUR_DAILY);
             break;
         case Horde_Compress_Tnef::PATTERN_WEEK:
             $rrule->setRecurType(Horde_Date_Recurrence::RECUR_WEEKLY);
             break;
         case Horde_Compress_Tnef::PATTERN_MONTH:
         case Horde_Compress_Tnef::PATTERN_MONTH_END:
             $rrule->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_DATE);
             break;
         case Horde_Compress_Tnef::PATTERN_MONTH_NTH:
             $rrule->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY);
             break;
         default:
             if ($freq == Horde_Compress_Tnef::RECUR_YEARLY) {
                 $rrule->setRecurType(Horde_Date_Recurrence::RECUR_YEARLY);
             }
     }
     switch ($end) {
         case Horde_Compress_Tnef::RECUR_END_N:
             $rrule->setRecurCount($count);
             break;
         case Horde_Compress_Tnef::RECUR_END_DATE:
             $rrule->setRecurEnd($endDate);
             break;
     }
     return $rrule;
 }
예제 #6
0
파일: Tnef.php 프로젝트: raz0rsdge/horde
 /**
  * Decodes TNEF attributes.
  *
  * @param  [type] &$data [description]
  * @return [type]        [description]
  */
 protected function _decodeMessageProperty(&$data)
 {
     // This contains the type AND the attribute name. We should only check
     // against the name since this is very confusing  (everything else is
     // checked against just name). Can't change until Horde 6 though since
     // the constants would have to change. Also, the type identifiers are
     // different between MAPI and TNEF. Of course...
     // $type = $this->_geti($data, 16);
     // $attribute = $this->_geti($data, 16);
     $attribute = $this->_geti($data, 32);
     $this->_logger->debug(sprintf('TNEF: Message property 0x%X found.', $attribute));
     $value = false;
     switch ($attribute) {
         case self::AMCLASS:
             // Start of a new message.
             $message_class = trim($this->_decodeAttribute($data));
             $this->_logger->debug(sprintf('TNEF: Message class: %s', $message_class));
             switch ($message_class) {
                 case self::IPM_MEETING_REQUEST:
                     $this->_currentObject = new Horde_Compress_Tnef_Icalendar($this->_logger);
                     $this->_currentObject->setMethod('REQUEST', $message_class);
                     $this->_files[] = $this->_currentObject;
                     break;
                 case self::IPM_MEETING_RESPONSE_TENT:
                 case self::IPM_MEETING_RESPONSE_NEG:
                 case self::IPM_MEETING_RESPONSE_POS:
                     $this->_currentObject = new Horde_Compress_Tnef_Icalendar($this->_logger);
                     $this->_currentObject->setMethod('REPLY', $message_class);
                     $this->_files[] = $this->_currentObject;
                     break;
                 case self::IPM_MEETING_REQUEST_CANCELLED:
                     $this->_currentObject = new Horde_Compress_Tnef_Icalendar($this->_logger);
                     $this->_currentObject->setMethod('CANCEL', $message_class);
                     $this->_files[] = $this->_currentObject;
                     break;
                 case self::IPM_TASK_REQUEST:
                     $this->_currentObject = new Horde_Compress_Tnef_VTodo($this->_logger, null, array('parent' => &$this));
                     $this->_files[] = $this->_currentObject;
                     break;
                 default:
                     $this->_logger->debug(sprintf('Unknown message class: %s', $message_class));
             }
             break;
         case self::AMAPIPROPS:
             $this->_logger->debug('TNEF: Extracting encapsulated message properties (idMsgProps)');
             $properties = $this->_decodeAttribute($data);
             $this->_extractMapiAttributes($properties);
             break;
         case self::APRIORITY:
         case self::AOWNER:
         case self::ARECIPIENTTABLE:
         case self::ABODY:
         case self::ASTATUS:
         case self::ACONVERSATIONID:
         case self::APARENTID:
         case self::AMESSAGEID:
         case self::ASUBJECT:
         case self::AORIGINALMCLASS:
             $value = $this->_decodeAttribute($data);
             break;
         case self::ADATERECEIVED:
         case self::ADATESENT:
         case self::ADATEMODIFIED:
         case self::ID_DATE_END:
             try {
                 $value = new Horde_Date(Horde_Mapi::filetimeToUnixtime($this->_decodeAttribute($data)), 'UTC');
             } catch (Horde_Mapi_Exception $e) {
                 throw new Horde_Compress_Exception($e);
             } catch (Horde_Date_Exception $e) {
                 throw new Horde_Compress_Exception($e);
             }
             break;
         case self::AFROM:
         case self::ASENTFOR:
             $msgObj = $this->_decodeAttribute($data);
             $display_name = $this->_getx($msgObj, $this->_geti($msgObj, 16));
             $email = $this->_getx($msgObj, $this->_geti($msgObj, 16));
             $value = $email;
             // @todo - Do we need to pass display name too?
             break;
         default:
             $size = $this->_geti($data, 32);
             $value = $this->_getx($data, $size);
             $this->_geti($data, 16);
             // Checksum.
     }
     if ($value && $this->_currentObject) {
         $this->_currentObject->setTnefAttribute($attribute, $value, empty($size) ? strlen($value) : $size);
     }
 }