Пример #1
0
 /**
  * Updates the properties of this event from a Horde_Icalendar_Vevent
  * object.
  *
  * @param Horde_Icalendar_Vevent $vEvent  The iCalendar data to update
  *                                        from.
  * @param boolean $parseAttendees         Parse attendees too?
  *                                        @since Kronolith 4.2
  */
 public function fromiCalendar($vEvent, $parseAttendees = false)
 {
     // Unique ID.
     try {
         $uid = $vEvent->getAttribute('UID');
         if (!empty($uid)) {
             $this->uid = $uid;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Sequence.
     try {
         $seq = $vEvent->getAttribute('SEQUENCE');
         if (is_int($seq)) {
             $this->sequence = $seq;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Title, tags and description.
     try {
         $title = $vEvent->getAttribute('SUMMARY');
         if (!is_array($title)) {
             $this->title = $title;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Tags
     try {
         $this->_tags = $vEvent->getAttributeValues('CATEGORIES');
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Description
     try {
         $desc = $vEvent->getAttribute('DESCRIPTION');
         if (!is_array($desc)) {
             $this->description = $desc;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Remote Url
     try {
         $url = $vEvent->getAttribute('URL');
         if (!is_array($url)) {
             $this->url = $url;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Location
     try {
         $location = $vEvent->getAttribute('LOCATION');
         if (!is_array($location)) {
             $this->location = $location;
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     try {
         $geolocation = $vEvent->getAttribute('GEO');
         $this->geoLocation = array('lat' => $geolocation['latitude'], 'lon' => $geolocation['longitude']);
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Class
     try {
         $class = $vEvent->getAttribute('CLASS');
         if (!is_array($class)) {
             $class = Horde_String::upper($class);
             $this->private = $class == 'PRIVATE' || $class == 'CONFIDENTIAL';
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Status.
     try {
         $status = $vEvent->getAttribute('STATUS');
         if (!is_array($status)) {
             $status = Horde_String::upper($status);
             if ($status == 'DECLINED') {
                 $status = 'CANCELLED';
             }
             if (defined('Kronolith::STATUS_' . $status)) {
                 $this->status = constant('Kronolith::STATUS_' . $status);
             }
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // Reset allday flag in case this has changed. Will be recalculated
     // next time isAllDay() is called.
     $this->allday = false;
     // Start and end date.
     $tzid = null;
     try {
         $start = $vEvent->getAttribute('DTSTART');
         $startParams = $vEvent->getAttribute('DTSTART', true);
         // We don't support different timezones for different attributes,
         // so use the DTSTART timezone for the complete event.
         if (isset($startParams[0]['TZID'])) {
             // Horde_Date supports timezone aliases, so try that first.
             $tz = $startParams[0]['TZID'];
             try {
                 // Check if the timezone name is supported by PHP natively.
                 new DateTimeZone($tz);
                 $this->timezone = $tzid = $tz;
             } catch (Exception $e) {
             }
         }
         if (!is_array($start)) {
             // Date-Time field
             $this->start = new Horde_Date($start, $tzid);
         } else {
             // Date field
             $this->start = new Horde_Date(array('year' => (int) $start['year'], 'month' => (int) $start['month'], 'mday' => (int) $start['mday']), $tzid);
         }
     } catch (Horde_Icalendar_Exception $e) {
         throw new Kronolith_Exception($e);
     } catch (Horde_Date_Exception $e) {
         throw new Kronolith_Exception($e);
     }
     try {
         $end = $vEvent->getAttribute('DTEND');
         if (!is_array($end)) {
             // Date-Time field
             $this->end = new Horde_Date($end, $tzid);
             // All day events are transferred by many device as
             // DSTART: YYYYMMDDT000000 DTEND: YYYYMMDDT2359(59|00)
             // Convert accordingly
             if (is_object($this->start) && $this->start->hour == 0 && $this->start->min == 0 && $this->start->sec == 0 && $this->end->hour == 23 && $this->end->min == 59) {
                 $this->end = new Horde_Date(array('year' => (int) $this->end->year, 'month' => (int) $this->end->month, 'mday' => (int) $this->end->mday + 1), $tzid);
             }
         } else {
             // Date field
             $this->end = new Horde_Date(array('year' => (int) $end['year'], 'month' => (int) $end['month'], 'mday' => (int) $end['mday']), $tzid);
         }
     } catch (Horde_Icalendar_Exception $e) {
         $end = null;
     }
     if (is_null($end)) {
         try {
             $duration = $vEvent->getAttribute('DURATION');
             if (!is_array($duration)) {
                 $this->end = new Horde_Date($this->start);
                 $this->end->sec += $duration;
                 $end = 1;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
         if (is_null($end)) {
             // End date equal to start date as per RFC 2445.
             $this->end = new Horde_Date($this->start);
             if (is_array($start)) {
                 // Date field
                 $this->end->mday++;
             }
         }
     }
     // vCalendar 1.0 alarms
     try {
         $alarm = $vEvent->getAttribute('AALARM');
         if (!is_array($alarm) && intval($alarm)) {
             $this->alarm = intval(($this->start->timestamp() - $alarm) / 60);
         }
     } catch (Horde_Icalendar_Exception $e) {
     }
     // vCalendar 2.0 alarms
     foreach ($vEvent->getComponents() as $alarm) {
         if (!$alarm instanceof Horde_Icalendar_Valarm) {
             continue;
         }
         try {
             if ($alarm->getAttribute('ACTION') == 'NONE') {
                 continue;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             // @todo consider implementing different ACTION types.
             // $action = $alarm->getAttribute('ACTION');
             $trigger = $alarm->getAttribute('TRIGGER');
             $triggerParams = $alarm->getAttribute('TRIGGER', true);
         } catch (Horde_Icalendar_Exception $e) {
             continue;
         }
         if (!is_array($triggerParams)) {
             $triggerParams = array($triggerParams);
         }
         $haveTrigger = false;
         foreach ($triggerParams as $tp) {
             if (isset($tp['VALUE']) && $tp['VALUE'] == 'DATE-TIME') {
                 if (isset($tp['RELATED']) && $tp['RELATED'] == 'END') {
                     $this->alarm = intval(($this->end->timestamp() - $trigger) / 60);
                 } else {
                     $this->alarm = intval(($this->start->timestamp() - $trigger) / 60);
                 }
                 $haveTrigger = true;
                 break;
             } elseif (isset($tp['RELATED']) && $tp['RELATED'] == 'END') {
                 $this->alarm = -intval($trigger / 60);
                 $this->alarm -= $this->durMin;
                 $haveTrigger = true;
                 break;
             }
         }
         if (!$haveTrigger) {
             $this->alarm = -intval($trigger / 60);
         }
         break;
     }
     // Alarm snoozing/dismissal
     if ($this->alarm) {
         try {
             // If X-MOZ-LASTACK is set, this event is either dismissed or
             // snoozed.
             $vEvent->getAttribute('X-MOZ-LASTACK');
             try {
                 // If X-MOZ-SNOOZE-TIME is set, this event is snoozed.
                 $snooze = $vEvent->getAttribute('X-MOZ-SNOOZE-TIME');
                 $this->_snooze = intval(($snooze - time()) / 60);
             } catch (Horde_Icalendar_Exception $e) {
                 // If X-MOZ-SNOOZE-TIME is not set, this event is dismissed.
                 $this->_snooze = -1;
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
     }
     // Attendance.
     // Importing attendance may result in confusion: editing an imported
     // copy of an event can cause invitation updates to be sent from
     // people other than the original organizer. So we don't import by
     // default. However to allow updates by synchronization, this behavior
     // can be overriden.
     // X-ATTENDEE is there for historical reasons. @todo remove in
     // Kronolith 5.
     $attendee = null;
     if ($parseAttendees) {
         try {
             $attendee = $vEvent->getAttribute('ATTENDEE');
             $params = $vEvent->getAttribute('ATTENDEE', true);
         } catch (Horde_Icalendar_Exception $e) {
             try {
                 $attendee = $vEvent->getAttribute('X-ATTENDEE');
                 $params = $vEvent->getAttribute('X-ATTENDEE', true);
             } catch (Horde_Icalendar_Exception $e) {
             }
         }
     }
     if ($attendee) {
         if (!is_array($attendee)) {
             $attendee = array($attendee);
         }
         if (!is_array($params)) {
             $params = array($params);
         }
         for ($i = 0; $i < count($attendee); ++$i) {
             $attendee[$i] = str_replace(array('MAILTO:', 'mailto:'), '', $attendee[$i]);
             $tmp = new Horde_Mail_Rfc822_Address($attendee[$i]);
             $email = $tmp->bare_address;
             // Default according to rfc2445:
             $attendance = Kronolith::PART_REQUIRED;
             // vCalendar 2.0 style:
             if (!empty($params[$i]['ROLE'])) {
                 switch ($params[$i]['ROLE']) {
                     case 'OPT-PARTICIPANT':
                         $attendance = Kronolith::PART_OPTIONAL;
                         break;
                     case 'NON-PARTICIPANT':
                         $attendance = Kronolith::PART_NONE;
                         break;
                 }
             }
             // vCalendar 1.0 style;
             if (!empty($params[$i]['EXPECT'])) {
                 switch ($params[$i]['EXPECT']) {
                     case 'REQUEST':
                         $attendance = Kronolith::PART_OPTIONAL;
                         break;
                     case 'FYI':
                         $attendance = Kronolith::PART_NONE;
                         break;
                 }
             }
             $response = Kronolith::RESPONSE_NONE;
             if (empty($params[$i]['PARTSTAT']) && !empty($params[$i]['STATUS'])) {
                 $params[$i]['PARTSTAT'] = $params[$i]['STATUS'];
             }
             if (!empty($params[$i]['PARTSTAT'])) {
                 switch ($params[$i]['PARTSTAT']) {
                     case 'ACCEPTED':
                         $response = Kronolith::RESPONSE_ACCEPTED;
                         break;
                     case 'DECLINED':
                         $response = Kronolith::RESPONSE_DECLINED;
                         break;
                     case 'TENTATIVE':
                         $response = Kronolith::RESPONSE_TENTATIVE;
                         break;
                 }
             }
             $name = isset($params[$i]['CN']) ? $params[$i]['CN'] : null;
             $this->addAttendee($email, $attendance, $response, $name);
         }
     }
     $this->_handlevEventRecurrence($vEvent);
     $this->initialized = true;
 }