Copyright 2003-2016 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.
Author: Mike Cochrane (mike@graftonhall.co.nz)
Inheritance: extends Horde_Icalendar
Example #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;
 }
Example #2
0
File: Api.php Project: horde/horde
 /**
  * Updates an attendee's response status for a specified event.
  *
  * @param Horde_Icalendar_Vevent $response  A Horde_Icalendar_Vevent
  *                                          object, with a valid UID
  *                                          attribute that points to an
  *                                          existing event.  This is
  *                                          typically the vEvent portion
  *                                          of an iTip meeting-request
  *                                          response, with the attendee's
  *                                          response in an ATTENDEE
  *                                          parameter.
  * @param string $sender                    The email address of the
  *                                          person initiating the
  *                                          update. Attendees are only
  *                                          updated if this address
  *                                          matches.
  *
  * @throws Kronolith_Exception
  */
 public function updateAttendee($response, $sender = null)
 {
     try {
         $uid = $response->getAttribute('UID');
     } catch (Horde_Icalendar_Exception $e) {
         throw new Kronolith_Exception($e);
     }
     $events = Kronolith::getDriver()->getByUID($uid, null, true);
     /* First try the user's own calendars. */
     $ownerCalendars = Kronolith::listInternalCalendars(true, Horde_Perms::EDIT);
     $event = null;
     foreach ($events as $ev) {
         if (isset($ownerCalendars[$ev->calendar])) {
             $event = $ev;
             break;
         }
     }
     /* If not successful, try all calendars the user has access to. */
     if (empty($event)) {
         $editableCalendars = Kronolith::listInternalCalendars(false, Horde_Perms::EDIT);
         foreach ($events as $ev) {
             if (isset($editableCalendars[$ev->calendar])) {
                 $event = $ev;
                 break;
             }
         }
     }
     if (empty($event) || $event->private && $event->creator != $GLOBALS['registry']->getAuth()) {
         throw new Horde_Exception_PermissionDenied();
     }
     $atnames = $response->getAttribute('ATTENDEE');
     if (!is_array($atnames)) {
         $atnames = array($atnames);
     }
     $atparms = $response->getAttribute('ATTENDEE', true);
     $found = false;
     $error = _("No attendees have been updated because none of the provided email addresses have been found in the event's attendees list.");
     foreach ($atnames as $index => $attendee) {
         if ($response->getAttribute('VERSION') < 2) {
             $addr_ob = new Horde_Mail_Rfc822_Address($attendee);
             if (!$addr_ob->valid) {
                 continue;
             }
             $attendee = $addr_ob->bare_address;
             $name = $addr_ob->personal;
         } else {
             $attendee = str_ireplace('mailto:', '', $attendee);
             $name = isset($atparms[$index]['CN']) ? $atparms[$index]['CN'] : null;
         }
         if ($event->hasAttendee($attendee)) {
             if (is_null($sender) || $sender == $attendee) {
                 $event->addAttendee($attendee, Kronolith::PART_IGNORE, Kronolith::responseFromICal($atparms[$index]['PARTSTAT']), $name);
                 $found = true;
             } else {
                 $error = _("The attendee hasn't been updated because the update was not sent from the attendee.");
             }
         }
     }
     $event->save();
     if (!$found) {
         throw new Kronolith_Exception($error);
     }
 }
Example #3
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);
         }
     }
 }
Example #4
0
 /**
  * Set the organizer of the iTip event.
  *
  * @param string $organizer  The organizer of the event.
  * @param array  $parameters Additional parameters.
  *
  * @return NULL
  */
 private function setOrganizer($organizer, $parameters)
 {
     $this->_vevent->setAttribute('ORGANIZER', $organizer, $parameters);
 }
Example #5
0
 /**
  * Update just the attendess of event with details from another
  * event.
  *
  * @param Horde_Icalendar_Vevent $vevent  The vEvent with latest details
  */
 public function updateAttendeesFromvEvent($vevent)
 {
     $newAttributes = $vevent->getAllAttributes();
     foreach ($newAttributes as $newAttribute) {
         if ($newAttribute['name'] != 'ATTENDEE') {
             continue;
         }
         try {
             $this->getAttribute($newAttribute['name']);
         } catch (Horde_Icalendar_Exception $e) {
             // Already exists so just add it.
             $this->setAttribute($newAttribute['name'], $newAttribute['value'], $newAttribute['params']);
             continue;
         }
         // Already exists so locate and modify.
         $found = false;
         // Try matching the attribte name and value incase
         // only the params changed (eg attendee updating
         // status).
         foreach ($this->_attributes as $id => $attr) {
             if ($attr['name'] == $newAttribute['name'] && $attr['value'] == $newAttribute['value']) {
                 // Merge the params.
                 foreach ($newAttribute['params'] as $param_id => $param_name) {
                     $this->_attributes[$id]['params'][$param_id] = $param_name;
                 }
                 $found = true;
                 break;
             }
         }
         if (!$found) {
             // Else match the first attribute with the same
             // name (eg changing start time).
             foreach ($this->_attributes as $id => $attr) {
                 if ($attr['name'] == $newAttribute['name']) {
                     $this->_attributes[$id]['value'] = $newAttribute['value'];
                     // Merge the params.
                     foreach ($newAttribute['params'] as $param_id => $param_name) {
                         $this->_attributes[$id]['params'][$param_id] = $param_name;
                     }
                     break;
                 }
             }
         }
     }
 }