Exemplo n.º 1
0
 function testChildren()
 {
     $comp = new Sabre_VObject_Component('VCALENDAR');
     // Note that 'myProp' is ignored here.
     $comp->children = array(new Sabre_VObject_Component('VEVENT'), new Sabre_VObject_Component('VTODO'));
     $r = $comp->children();
     $this->assertTrue($r instanceof Sabre_VObject_ElementList);
     $this->assertEquals(2, count($r));
 }
Exemplo n.º 2
0
 /**
  * parse VEVENT part of VCALENDAR
  * 
  * @param  Sabre_VObject_Component  $_vevent  the VEVENT to parse
  * @param  Calendar_Model_Event     $_event   the Tine 2.0 event to update
  */
 protected function _convertVevent(Sabre_VObject_Component $_vevent, Calendar_Model_Event $_event)
 {
     $event = $_event;
     $newAttendees = array();
     // unset supported fields
     foreach ($this->_supportedFields as $field) {
         if ($field == 'alarms') {
             $event->{$field} = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm');
         } else {
             $event->{$field} = null;
         }
     }
     foreach ($_vevent->children() as $property) {
         switch ($property->name) {
             case 'CREATED':
             case 'DTSTAMP':
                 // do nothing
                 break;
             case 'LAST-MODIFIED':
                 $event->last_modified_time = new Tinebase_DateTime($property->value);
                 break;
             case 'ATTENDEE':
                 $newAttendees[] = $this->_getAttendee($property);
                 break;
             case 'CLASS':
                 if (in_array($property->value, array(Calendar_Model_Event::CLASS_PRIVATE, Calendar_Model_Event::CLASS_PUBLIC))) {
                     $event->class = $property->value;
                 } else {
                     $event->class = Calendar_Model_Event::CLASS_PUBLIC;
                 }
                 break;
             case 'DTEND':
                 if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') {
                     // all day event
                     $event->is_all_day_event = true;
                     $dtend = $this->_convertToTinebaseDateTime($property, TRUE);
                     // whole day events ends at 23:59:59 in Tine 2.0 but 00:00 the next day in vcalendar
                     $dtend->subSecond(1);
                 } else {
                     $event->is_all_day_event = false;
                     $dtend = $this->_convertToTinebaseDateTime($property);
                 }
                 $event->dtend = $dtend;
                 break;
             case 'DTSTART':
                 if (isset($property['VALUE']) && strtoupper($property['VALUE']) == 'DATE') {
                     // all day event
                     $event->is_all_day_event = true;
                     $dtstart = $this->_convertToTinebaseDateTime($property, TRUE);
                 } else {
                     $event->is_all_day_event = false;
                     $dtstart = $this->_convertToTinebaseDateTime($property);
                 }
                 $event->originator_tz = $dtstart->getTimezone()->getName();
                 $event->dtstart = $dtstart;
                 break;
             case 'SEQUENCE':
                 $event->seq = $property->value;
                 break;
             case 'DESCRIPTION':
             case 'LOCATION':
             case 'UID':
             case 'SUMMARY':
                 $key = strtolower($property->name);
                 $event->{$key} = $property->value;
                 break;
             case 'ORGANIZER':
                 if (preg_match('/mailto:(?P<email>.*)/i', $property->value, $matches)) {
                     // it's not possible to change the organizer by spec
                     if (empty($event->organizer)) {
                         $name = isset($property['CN']) ? $property['CN']->value : $matches['email'];
                         $contact = Calendar_Model_Attender::resolveEmailToContact(array('email' => $matches['email'], 'lastName' => $name));
                         $event->organizer = $contact->getId();
                     }
                     // Lightning attaches organizer ATTENDEE properties to ORGANIZER property and does not add an ATTENDEE for the organizer
                     if (isset($property['PARTSTAT'])) {
                         $newAttendees[] = $this->_getAttendee($property);
                     }
                 }
                 break;
             case 'RECURRENCE-ID':
                 // original start of the event
                 $event->recurid = $this->_convertToTinebaseDateTime($property);
                 // convert recurrence id to utc
                 $event->recurid->setTimezone('UTC');
                 break;
             case 'RRULE':
                 $event->rrule = $property->value;
                 // convert date format
                 $event->rrule = preg_replace_callback('/UNTIL=([\\dTZ]+)(?=;?)/', function ($matches) {
                     if (strlen($matches[1]) < 10) {
                         $dtUntil = date_create($matches[1], new DateTimeZone((string) Tinebase_Core::get(Tinebase_Core::USERTIMEZONE)));
                         $dtUntil->setTimezone(new DateTimeZone('UTC'));
                     } else {
                         $dtUntil = date_create($matches[1]);
                     }
                     return 'UNTIL=' . $dtUntil->format(Tinebase_Record_Abstract::ISO8601LONG);
                 }, $event->rrule);
                 // remove additional days from BYMONTHDAY property
                 $event->rrule = preg_replace('/(BYMONTHDAY=)([\\d]+)([,\\d]+)/', '$1$2', $event->rrule);
                 // process exceptions
                 if (isset($_vevent->EXDATE)) {
                     $exdates = new Tinebase_Record_RecordSet('Calendar_Model_Event');
                     foreach ($_vevent->EXDATE as $exdate) {
                         foreach ($exdate->getDateTimes() as $exception) {
                             if (isset($exdate['VALUE']) && strtoupper($exdate['VALUE']) == 'DATE') {
                                 $recurid = new Tinebase_DateTime($exception->format(Tinebase_Record_Abstract::ISO8601LONG), (string) Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
                             } else {
                                 $recurid = new Tinebase_DateTime($exception->format(Tinebase_Record_Abstract::ISO8601LONG), $exception->getTimezone());
                             }
                             $recurid->setTimezone(new DateTimeZone('UTC'));
                             $eventException = new Calendar_Model_Event(array('recurid' => $recurid, 'is_deleted' => true));
                             $exdates->addRecord($eventException);
                         }
                     }
                     $event->exdate = $exdates;
                 }
                 break;
             case 'TRANSP':
                 if (in_array($property->value, array(Calendar_Model_Event::TRANSP_OPAQUE, Calendar_Model_Event::TRANSP_TRANSP))) {
                     $event->transp = $property->value;
                 } else {
                     $event->transp = Calendar_Model_Event::TRANSP_TRANSP;
                 }
                 break;
             case 'UID':
                 // it's not possible to change the uid by spec
                 if (!empty($event->uid)) {
                     continue;
                 }
                 $event->uid = $property->value;
                 break;
             case 'VALARM':
                 foreach ($property as $valarm) {
                     switch (strtoupper($valarm->TRIGGER['VALUE']->value)) {
                         # TRIGGER;VALUE=DATE-TIME:20111031T130000Z
                         case 'DATE-TIME':
                             //@TODO fixme
                             $alarmTime = new Tinebase_DateTime($valarm->TRIGGER->value);
                             $alarmTime->setTimezone('UTC');
                             $alarm = new Tinebase_Model_Alarm(array('alarm_time' => $alarmTime, 'minutes_before' => 'custom', 'model' => 'Calendar_Model_Event'));
                             $event->alarms->addRecord($alarm);
                             break;
                             # TRIGGER;VALUE=DURATION:-PT1H15M
                         # TRIGGER;VALUE=DURATION:-PT1H15M
                         case 'DURATION':
                         default:
                             $alarmTime = $this->_convertToTinebaseDateTime($_vevent->DTSTART);
                             $alarmTime->setTimezone('UTC');
                             preg_match('/(?P<invert>[+-]?)(?P<spec>P.*)/', $valarm->TRIGGER->value, $matches);
                             $duration = new DateInterval($matches['spec']);
                             $duration->invert = !!($matches['invert'] === '-');
                             $alarm = new Tinebase_Model_Alarm(array('alarm_time' => $alarmTime->add($duration), 'minutes_before' => $duration->format('%d') * 60 * 24 + $duration->format('%h') * 60 + $duration->format('%i'), 'model' => 'Calendar_Model_Event'));
                             $event->alarms->addRecord($alarm);
                             break;
                     }
                 }
                 break;
             case 'CATEGORIES':
                 // @todo handle categories
                 break;
             case 'X-MOZ-LASTACK':
                 $lastAck = $this->_convertToTinebaseDateTime($property);
                 break;
             case 'X-MOZ-SNOOZE-TIME':
                 $snoozeTime = $this->_convertToTinebaseDateTime($property);
                 break;
             default:
                 break;
         }
     }
     // merge old and new attendees
     Calendar_Model_Attender::emailsToAttendee($event, $newAttendees);
     if (($ownAttendee = Calendar_Model_Attender::getOwnAttender($event->attendee)) !== null) {
         if (isset($lastAck)) {
             $ownAttendee->alarm_ack_time = $lastAck;
         }
         if (isset($snoozeTime)) {
             $ownAttendee->alarm_snooze_time = $snoozeTime;
         }
     }
     if (empty($event->seq)) {
         $event->seq = 0;
     }
     if (empty($event->class)) {
         $event->class = Calendar_Model_Event::CLASS_PUBLIC;
     }
     // convert all datetime fields to UTC
     $event->setTimezone('UTC');
 }