/** * Imports an event represented in the specified content type. * * @param string $content The content of the event. * @param string $contentType What format is the data in? Currently supports: * <pre> * text/calendar * text/x-vcalendar * activesync * </pre> * @param string $calendar What calendar should the event be added to? * @param boolean $hash If true, return a hash for EAS additions. * @since 4.3.0 @todo Remove for 5.0 and make * this the normal return. * * @return array The event's UID. * @throws Kronolith_Exception */ public function import($content, $contentType, $calendar = null, $hash = false) { if (!isset($calendar)) { $calendar = Kronolith::getDefaultCalendar(Horde_Perms::EDIT); } elseif (!Kronolith::hasPermission($calendar, Horde_Perms::EDIT)) { throw new Horde_Exception_PermissionDenied(); } $kronolith_driver = Kronolith::getDriver(null, $calendar); switch ($contentType) { case 'text/calendar': case 'text/x-vcalendar': $iCal = new Horde_Icalendar(); if (!$content instanceof Horde_Icalendar_Vevent) { if (!$iCal->parsevCalendar($content)) { throw new Kronolith_Exception(_("There was an error importing the iCalendar data.")); } } else { $iCal->addComponent($content); } $ical_importer = new Kronolith_Icalendar_Handler_Base($iCal, $kronolith_driver); $result = array_flip($ical_importer->process()); return current($result); case 'activesync': $event = $kronolith_driver->getEvent(); $event->fromASAppointment($content); $event->save(); // Handle attachment data after we commit changes since we // are required to have a saved event to attach files. Also, // we can only handle files if we are returning a hash since EAS // needs the information returned to attach filereferences to // the attachments. if (!$hash) { return $event->uid; } $atc_hash = $event->addEASFiles($content); return array('uid' => $event->uid, 'atchash' => $atc_hash); } throw new Kronolith_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType)); }
/** * Imports an event represented in the specified content type. * * @param string $content The content of the event. * @param string $contentType What format is the data in? Currently supports: * <pre> * text/calendar * text/x-vcalendar * activesync * </pre> * @param string $calendar What calendar should the event be added to? * * @return array The event's UID. * @throws Kronolith_Exception */ public function import($content, $contentType, $calendar = null) { if (!isset($calendar)) { $calendar = Kronolith::getDefaultCalendar(Horde_Perms::EDIT); } elseif (!Kronolith::hasPermission($calendar, Horde_Perms::EDIT)) { throw new Horde_Exception_PermissionDenied(); } $kronolith_driver = Kronolith::getDriver(null, $calendar); switch ($contentType) { case 'text/calendar': case 'text/x-vcalendar': $iCal = new Horde_Icalendar(); if (!$content instanceof Horde_Icalendar_Vevent) { if (!$iCal->parsevCalendar($content)) { throw new Kronolith_Exception(_("There was an error importing the iCalendar data.")); } } else { $iCal->addComponent($content); } $ical_importer = new Kronolith_Icalendar_Handler_Base($iCal, $kronolith_driver); $result = array_flip($ical_importer->process()); return current($result); case 'activesync': $event = $kronolith_driver->getEvent(); $event->fromASAppointment($content); $event->save(); return $event->uid; } throw new Kronolith_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType)); }
break; } } try { $event->save(); } catch (Exception $e) { $notification->push($e, 'horde.error'); $error = true; break; } if ($max_events !== true) { $num_events++; } } if (!empty($ical)) { $ical_importer = new Kronolith_Icalendar_Handler_Base($ical, $kronolith_driver); try { $ical_importer->process(); } catch (Kronolith_Exception $e) { $msg = _("Can't create a new event.") . ' ' . sprintf(_("This is what the server said: %s"), $e->getMessage()); $notification->push($msg, 'horde.error'); $error = true; } } if (!$error) { $notification->push(sprintf(_("%s file successfully imported"), $file_types[$storage->get('format')]), 'horde.success'); } if (Horde_Util::getFormData('import_ajax')) { $page_output->addInlineScript('(function(window){window.KronolithCore.loadCalendar(\'' . $type . '\', \'' . $calendar . '\');})(window.parent)'); } $next_step = $data->cleanup();
/** * Responsible for any logic needed before the event is saved. Called for * EVERY component in the iCalendar object. Returning false from this method * will cause the current component to be ignored. Returning true causes it * to be processed. * * @param Horde_Icalendar $component The iCalendar component. * * @return boolean True to continue processing, false to ignore. */ protected function _preSave($component) { // Short circuit if we know we don't pass the parent test. if (!parent::_preSave($component)) { return false; } // Ensure we start with a fresh state. $this->_existingEvent = null; $this->_oldAttendees = new Kronolith_Attendee_List(); $this->_noItips = array(); // Get the internal id of the existing copy of the event, if it exists. try { $existing_id = $this->_dav->getInternalObjectId($this->_params['object'], $this->_calendar) ?: preg_replace('/\\.ics$/', '', $this->_params['object']); } catch (Horde_Dav_Exception $e) { $existing_id = $this->_params['object']; } // Check that we don't have newer information already on the server. try { // Exception event, so we can't compare timestamps using ids. // Instead look for baseid/recurrence-id. $rid = $component->getAttribute('RECURRENCE-ID'); $uid = $component->getAttribute('UID'); if (!empty($rid) && !empty($uid)) { $search = new stdClass(); $search->baseid = $uid; $search->recurrenceid = $rid; $results = $this->_driver->search($search); foreach ($results as $days) { foreach ($days as $exception) { // Should only be one... $modified = $exception->modified ?: $exception->created; } } } } catch (Horde_Icalendar_Exception $e) { // Base event or event with no recurrence. try { $this->_existingEvent = $this->_driver->getEvent($existing_id); $this->_existingEvent->loadHistory(); $modified = $this->_existingEvent->modified ?: $this->_existingEvent->created; // Get list of existing attendees. $this->_oldAttendees = $this->_existingEvent->attendees; } catch (Horde_Exception_NotFound $e) { $this->_existingEvent = null; } } try { if (!empty($modified) && $component->getAttribute('LAST-MODIFIED') < $modified->timestamp()) { /* LAST-MODIFIED timestamp of existing entry is newer: * don't replace it. */ return false; } } catch (Horde_Icalendar_Exception $e) { } try { $organizer = $component->getAttribute('ORGANIZER'); $organizer_params = $component->getAttribute('ORGANIZER', true); if (!empty($organizer_params[0]['SCHEDULE-AGENT']) && ($organizer_params[0]['SCHEDULE-AGENT'] == 'CLIENT' || $organizer_params[0]['SCHEDULE-AGENT'] == 'NONE')) { $tmp = str_replace(array('MAILTO:', 'mailto:'), '', $organizer); $tmp = new Horde_Mail_Rfc822_Address($tmp); $this->_noItips[] = $tmp->bare_address; } } catch (Horde_Icalendar_Exception $e) { } try { $attendee = $component->getAttribute('ATTENDEE'); $params = $component->getAttribute('ATTENDEE', true); for ($i = 0; $i < count($attendee); ++$i) { if (!empty($params[$i]['SCHEDULE-AGENT']) && ($params[$i]['SCHEDULE-AGENT'] == 'CLIENT' || $params[$i]['SCHEDULE-AGENT'] == 'NONE')) { $tmp = str_replace(array('MAILTO:', 'mailto:'), '', $attendee[$i]); $tmp = new Horde_Mail_Rfc822_Address($tmp); $this->_noItips[] = $tmp->bare_address; } } } catch (Horde_Icalendar_Exception $e) { } return true; }