getComponents() публичный Метод

Retrieve all the components.
public getComponents ( ) : array
Результат array Array of Horde_Icalendar objects.
Пример #1
0
 public function testEmptyData()
 {
     $ical = new Horde_Icalendar();
     $ical->parsevCalendar(file_get_contents(__DIR__ . '/fixtures/empty.ics'));
     $this->assertEquals(array(), $ical->getComponents());
     $ical->parsevCalendar('');
     $this->assertEquals(array(), $ical->getComponents());
 }
Пример #2
0
 /**
  * Variables required in form input:
  *   - imple_submit: vcard action. Contains import and source properties
  *   - mime_id
  *   - muid
  *
  * @return boolean  True on success.
  */
 protected function _handle(Horde_Variables $vars)
 {
     global $registry, $injector, $notification;
     $iCal = new Horde_Icalendar();
     try {
         $contents = $injector->getInstance('IMP_Factory_Contents')->create(new IMP_Indices_Mailbox($vars));
         if (!($mime_part = $contents->getMimePart($vars->mime_id))) {
             throw new IMP_Exception(_("Cannot retrieve vCard data from message."));
         } elseif (!$iCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) {
             throw new IMP_Exception(_("Error reading the contact data."));
         }
         $components = $iCal->getComponents();
     } catch (Exception $e) {
         $notification->push($e, 'horde.error');
     }
     $import = !empty($vars->imple_submit->import) ? $vars->imple_submit->import : false;
     $source = !empty($vars->imple_submit->source) ? $vars->imple_submit->source : false;
     if ($import && $source && $registry->hasMethod('contacts/import')) {
         $count = 0;
         foreach ($components as $c) {
             if ($c->getType() == 'vcard') {
                 try {
                     $registry->call('contacts/import', array($c, null, $source));
                     ++$count;
                 } catch (Horde_Exception $e) {
                     $notification->push(Horde_Core_Translation::t("There was an error importing the contact data:") . ' ' . $e->getMessage(), 'horde.error');
                 }
             }
         }
         $notification->push(sprintf(Horde_Core_Translation::ngettext("%d contact was successfully added to your address book.", "%d contacts were successfully added to your address book.", $count), $count), 'horde.success');
     }
 }
Пример #3
0
 private function _getFixture($element)
 {
     $iCal = new Horde_Icalendar();
     $iCal->parsevCalendar(file_get_contents(__DIR__ . '/../fixtures/allday.ics'));
     $components = $iCal->getComponents();
     return $components[$element];
 }
Пример #4
0
 /**
  * Process the iCalendar data.
  *
  * @return array A hash of UID => id.
  * @throws Kronolith_Exception
  */
 protected function _process()
 {
     $ids = array();
     $components = $this->_iCal->getComponents();
     if (count($components) == 0) {
         throw new Kronolith_Exception(_("No iCalendar data was found."));
     }
     foreach ($components as $component) {
         if (!$this->_preSave($component)) {
             continue;
         }
         try {
             // RECURRENCE-ID - must import after base event is
             // imported/saved so defer these until all other data is
             // processed.
             $component->getAttribute('RECURRENCE-ID');
             $this->_exceptions[] = $component;
         } catch (Horde_Icalendar_Exception $e) {
             $event = $this->_driver->getEvent();
             $event->fromiCalendar($component, true);
             // Delete existing exception events. There is no efficient way
             // to determine if any existing events have been changed/deleted
             // so we just remove them all since they will be re-added during
             // the import process.
             foreach ($event->boundExceptions() as $exception) {
                 $this->_driver->deleteEvent($exception->id);
             }
             // Save and post-process.
             $event->save();
             $this->_postSave($event);
             $ids[$event->uid] = $event->id;
         }
     }
     // Save exception events.
     foreach ($this->_exceptions as $exception) {
         $event = $this->_driver->getEvent();
         $event->fromiCalendar($exception);
         $event->save();
     }
     return $ids;
 }
Пример #5
0
 /**
  * @dataProvider timezones
  */
 public function testFile($file)
 {
     $result = '';
     $ical = new Horde_Icalendar();
     $ical->parsevCalendar(file_get_contents($file));
     foreach ($ical->getComponents() as $component) {
         if ($component->getType() != 'vEvent') {
             continue;
         }
         $date = $component->getAttribute('DTSTART');
         if (is_array($date)) {
             continue;
         }
         $result .= str_replace("\r", '', $component->getAttribute('SUMMARY')) . "\n";
         $d = new Horde_Date($date);
         $result .= $d->format('H:i') . "\n";
     }
     $this->assertStringEqualsFile(__DIR__ . '/fixtures/vTimezone/' . basename($file, 'ics') . 'txt', $result, 'Failed parsing file ' . basename($file));
 }
Пример #6
0
 /**
  * Return the full rendered version of the Horde_Mime_Part object.
  *
  * URL parameters used by this function:
  *   - c: (integer) The VCARD component that contains an image.
  *   - p: (integer) The index of image inside the component to display.
  *
  * @return array  See parent::render().
  * @throws Horde_Exception
  */
 protected function _renderInline()
 {
     $vars = $GLOBALS['injector']->getInstance('Horde_Variables');
     if (!isset($vars->p)) {
         $imp_contents = $this->getConfigParam('imp_contents');
         $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_VcardImport', array('mime_id' => $this->_mimepart->getMimeId(), 'muid' => strval($imp_contents->getIndicesOb())));
         $this->_imageUrl = $this->getConfigParam('imp_contents')->urlView($this->_mimepart, 'download_render', array('params' => array('mode' => IMP_Contents::RENDER_INLINE)));
         return parent::_renderInline();
     }
     /* Send the requested photo. */
     $data = $this->_mimepart->getContents();
     $ical = new Horde_Icalendar();
     if (!$ical->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) {
         // TODO: Error reporting
         return array();
     }
     $components = $ical->getComponents();
     if (!isset($components[$vars->c])) {
         // TODO: Error reporting
         return array();
     }
     $name = $components[$vars->c]->getAttributeDefault('FN', false);
     if ($name === false) {
         $name = $components[$vars->c]->printableName();
     }
     if (empty($name)) {
         $name = preg_replace('/\\..*?$/', '', $this->_mimepart->getName());
     }
     $photos = $components[$vars->c]->getAllAttributes('PHOTO');
     if (!isset($photos[$vars->p])) {
         // TODO: Error reporting
         return array();
     }
     $type = 'image/' . Horde_String::lower($photos[$vars->p]['params']['TYPE']);
     return array($this->_mimepart->getMimeId() => array('data' => base64_decode($photos[$vars->p]['value']), 'name' => $name . '.' . Horde_Mime_Magic::mimeToExt($type), 'type' => $type));
 }
Пример #7
0
 /**
  * Return the rendered inline version of the Horde_Mime_Part object.
  *
  * @return array  See parent::render().
  */
 protected function _renderInline()
 {
     $GLOBALS['page_output']->growler = true;
     $data = $this->_mimepart->getContents();
     $mime_id = $this->_mimepart->getMimeId();
     // Parse the iCal file.
     $vCal = new Horde_Icalendar();
     if (!$vCal->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) {
         $status = new IMP_Mime_Status($this->_mimepart, _("The calendar data is invalid"));
         $status->action(IMP_Mime_Status::ERROR);
         return array($mime_id => array('data' => '', 'status' => $status, 'type' => 'text/html; charset=UTF-8'));
     }
     // Check if we got vcard data with the wrong vcalendar mime type.
     $imp_contents = $this->getConfigParam('imp_contents');
     $c = $vCal->getComponentClasses();
     if (count($c) == 1 && !empty($c['horde_icalendar_vcard'])) {
         return $imp_contents->renderMIMEPart($mime_id, IMP_Contents::RENDER_INLINE, array('type' => 'text/x-vcard'));
     }
     $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_ItipRequest', array('mime_id' => $mime_id, 'muid' => strval($imp_contents->getIndicesOb())));
     // Get the method type.
     try {
         $method = $vCal->getAttribute('METHOD');
     } catch (Horde_Icalendar_Exception $e) {
         $method = '';
     }
     $out = array();
     $exceptions = array();
     $components = $vCal->getComponents();
     foreach ($components as $key => $component) {
         switch ($component->getType()) {
             case 'vEvent':
                 try {
                     if ($component->getAttribute('RECURRENCE-ID')) {
                         $exceptions[] = $this->_vEvent($component, $key, $method, $components);
                     }
                 } catch (Horde_ICalendar_Exception $e) {
                     $out[] = $this->_vEvent($component, $key, $method, $components);
                 }
                 break;
             case 'vTodo':
                 $out[] = $this->_vTodo($component, $key, $method);
                 break;
             case 'vTimeZone':
                 // Ignore them.
                 break;
             case 'vFreebusy':
                 $out[] = $this->_vFreebusy($component, $key, $method);
                 break;
                 // @todo: handle stray vcards here as well.
             // @todo: handle stray vcards here as well.
             default:
                 $out[] = sprintf(_("Unhandled component of type: %s"), $component->getType());
                 break;
         }
     }
     // If we don't have any other parts, any exceptions should be shown
     // since this is likely an update to a series instance such as a
     // cancellation etc...
     if (empty($out)) {
         $out = $exceptions;
     }
     $view = $this->_getViewOb();
     $view->formid = $imple->getDomId();
     $view->out = implode('', $out);
     return array($mime_id => array('data' => $view->render('base'), 'type' => 'text/html; charset=UTF-8'));
 }
Пример #8
0
 private function _getFixture($name, $item = 0)
 {
     $iCal = new Horde_Icalendar();
     $iCal->parsevCalendar(file_get_contents(__DIR__ . '/../fixtures/' . $name));
     $components = $iCal->getComponents();
     $event = new Kronolith_Event_Sql(new Kronolith_Stub_Driver());
     $event->fromiCalendar($components[$item], true);
     return $event;
 }
Пример #9
0
 /**
  * Return the attendee participation status.
  *
  * @param Horde_Icalendar $vCal  The vCalendar component.
  *
  * @param Horde_Icalendar
  * @throws Horde_ActiveSync_Exception
  */
 protected function _getiTipStatus($vCal)
 {
     foreach ($vCal->getComponents() as $component) {
         switch ($component->getType()) {
             case 'vEvent':
                 try {
                     $atparams = $component->getAttribute('ATTENDEE', true);
                 } catch (Horde_Icalendar_Exception $e) {
                     throw new Horde_ActiveSync_Exception($e);
                 }
                 if (!is_array($atparams)) {
                     throw new Horde_Icalendar_Exception('Unexpected value');
                 }
                 return $atparams[0]['PARTSTAT'];
         }
     }
 }
Пример #10
0
 */
require_once 'Horde/Cli.php';
require_once 'Horde/Icalendar.php';
// This only works on the command line.
if (!Horde_Cli::runningFromCLI()) {
    exit("Must be run from the command line\n");
}
// Load the CLI environment - make sure there's no time limit, init
// some variables, etc.
$cli = Horde_Cli::init();
if (empty($argv[1])) {
    $cli->fatal('No file specified on the command line.');
}
$input_file = $argv[1];
if (!file_exists($input_file)) {
    $cli->fatal($input_file . ' does not exist.');
}
if (!is_readable($input_file)) {
    $cli->fatal($input_file . ' is not readable.');
}
$cli->writeln($cli->blue('Parsing ' . $input_file . ' ...'));
$data = file_get_contents($input_file);
$ical = new Horde_Icalendar();
if (!$ical->parseVCalendar($data)) {
    $cli->fatal('iCalendar parsing failed.');
}
$cli->writeln($cli->green('Parsing successful, found ' . $ical->getComponentCount() . ' component(s).'));
$components = $ical->getComponents();
foreach ($components as $component) {
    var_dump($component->toHash(true));
}
Пример #11
0
 /**
  * Converts all components of a Horde_Icalendar container into a
  * Kronolith_Event list.
  *
  * @param Horde_Icalendar $ical  A Horde_Icalendar container.
  *
  * @return array  List of Kronolith_Event_Ical objects.
  * @throws Kronolith_Exception
  */
 protected function _convertEvents($ical)
 {
     $events = array();
     foreach ($ical->getComponents() as $component) {
         if ($component->getType() == 'vEvent') {
             try {
                 $events[] = new Kronolith_Event_Ical($this, $component);
             } catch (Kronolith_Exception $e) {
                 Horde::log(sprintf('Failed to parse event from remote calendar: url = "%s"', $this->calendar), 'INFO');
             }
         }
     }
     return $events;
 }
Пример #12
0
 /**
  */
 public function davPutObject($collection, $object, $data)
 {
     $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage');
     $internal = $dav->getInternalCollectionId($collection, 'tasks') ?: $collection;
     if (!Nag::hasPermission($internal, Horde_Perms::EDIT)) {
         throw new Nag_Exception("Task List does not exist or no permission to edit");
     }
     $ical = new Horde_Icalendar();
     if (!$ical->parsevCalendar($data)) {
         throw new Nag_Exception(_("There was an error importing the iCalendar data."));
     }
     $storage = $GLOBALS['injector']->getInstance('Nag_Factory_Driver')->create($internal);
     foreach ($ical->getComponents() as $content) {
         if (!$content instanceof Horde_Icalendar_Vtodo) {
             continue;
         }
         $task = new Nag_Task();
         $task->fromiCalendar($content);
         try {
             try {
                 $existing_id = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.ics$/', '', $object);
             } catch (Horde_Dav_Exception $e) {
                 $existing_id = $object;
             }
             $existing_task = Nag::getTask($internal, $existing_id);
             /* Check if our task is newer then the existing - get the
              * task's history. */
             $modified = $this->_modified($internal, $existing_task->uid);
             try {
                 if (!empty($modified) && $content->getAttribute('LAST-MODIFIED') < $modified) {
                     /* LAST-MODIFIED timestamp of existing entry is newer:
                      * don't replace it. */
                     continue;
                 }
             } catch (Horde_Icalendar_Exception $e) {
             }
             $task->owner = $existing_task->owner;
             $storage->modify($existing_task->id, $task->toHash());
         } catch (Horde_Exception_NotFound $e) {
             $hash = $task->toHash();
             $newTask = $storage->add($hash);
             $dav->addObjectMap($newTask[0], $object, $internal);
         }
     }
 }
Пример #13
0
 /**
  * Replaces the task identified by UID with the content represented in the
  * specified content type.
  *
  * If you want to replace multiple tasks with the UID specified in the
  * VCALENDAR data, you may use $this->import instead. This automatically does a
  * replace if existings UIDs are found.
  *
  *
  * @param string $uid          Identify the task to replace.
  * @param string $content      The content of the task.
  * @param string $contentType  What format is the data in? Currently supports:
  *                             - text/x-vcalendar
  *                             - text/calendar
  *
  * @return boolean  Success or failure.
  */
 public function replace($uid, $content, $contentType)
 {
     $factory = $GLOBALS['injector']->getInstance('Nag_Factory_Driver');
     $existing = $factory->create('')->getByUID($uid);
     $taskId = $existing->id;
     $owner = $existing->owner;
     if (!Nag::hasPermission($existing->tasklist, Horde_Perms::EDIT)) {
         throw new Horde_Exception_PermissionDenied();
     }
     switch ($contentType) {
         case 'text/calendar':
         case 'text/x-vcalendar':
             if (!$content instanceof Horde_Icalendar_Vtodo) {
                 $iCal = new Horde_Icalendar();
                 if (!$iCal->parsevCalendar($content)) {
                     throw new Nag_Exception(_("There was an error importing the iCalendar data."));
                 }
                 $components = $iCal->getComponents();
                 $component = null;
                 foreach ($components as $content) {
                     if ($content instanceof Horde_Icalendar_Vtodo) {
                         if ($component !== null) {
                             throw new Nag_Exception(_("Multiple iCalendar components found; only one vTodo is supported."));
                         }
                         $component = $content;
                     }
                 }
                 if ($component === null) {
                     throw new Nag_Exception(_("No iCalendar data was found."));
                 }
             }
             $task = new Nag_Task();
             $task->fromiCalendar($content);
             $task->owner = $owner;
             $factory->create($existing->tasklist)->modify($taskId, $task->toHash());
             break;
         case 'activesync':
             $task = new Nag_Task();
             $task->fromASTask($content);
             $task->owner = $owner;
             $factory->create($existing->tasklist)->modify($taskId, $task->toHash());
             break;
         default:
             throw new Nag_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
     }
     return $result;
 }
Пример #14
0
 /**
  * Import a contact represented in the specified contentType.
  *
  * @param string $content      The content of the contact.
  * @param string $contentType  What format is the data in? Currently
  *                             supports array, text/directory, text/vcard,
  *                             text/x-vcard, and activesync.
  * @param string $source       The source into which the contact will be
  *                             imported.
  *
  * @return string  The new UID.
  *
  * @throws Turba_Exception
  * @throws Turba_Exception_ObjectExists
  */
 public function import($content, $contentType = 'array', $source = null)
 {
     global $cfgSources, $injector, $prefs;
     /* Get default address book from user preferences. */
     if (empty($source) && !($source = $prefs->getValue('default_dir'))) {
         // On new installations default_dir is not set. Try default
         // addressbook if it's editable. Otherwise use first editable
         // addressbook.
         $edit_sources = Turba::getAddressBooks(Horde_Perms::EDIT);
         $default_source = Turba::getDefaultAddressbook();
         if (isset($edit_sources[$default_source])) {
             // use default addressbook
             $source = $default_source;
         } else {
             // Use first writable source
             $source = reset($edit_sources);
         }
     }
     // Check existence of and permissions on the specified source.
     if (!isset($cfgSources[$source])) {
         throw new Turba_Exception(sprintf(_("Invalid address book: %s"), $source));
     }
     $driver = $injector->getInstance('Turba_Factory_Driver')->create($source);
     if (!$driver->hasPermission(Horde_Perms::EDIT)) {
         throw new Turba_Exception(_("Permission denied"));
     }
     if (!$content instanceof Horde_Icalendar_Vcard) {
         switch ($contentType) {
             case 'activesync':
                 $content = $driver->fromASContact($content);
                 break;
             case 'array':
                 if (!isset($content['emails']) && isset($content['email'])) {
                     $content['emails'] = $content['email'];
                 }
                 break;
             case 'text/x-vcard':
             case 'text/vcard':
             case 'text/directory':
                 $iCal = new Horde_Icalendar();
                 if (!$iCal->parsevCalendar($content)) {
                     throw new Turba_Exception(_("There was an error importing the iCalendar data."));
                 }
                 switch ($iCal->getComponentCount()) {
                     case 0:
                         throw new Turba_Exception(_("No vCard data was found."));
                     case 1:
                         $content = $iCal->getComponent(0);
                         break;
                     default:
                         $ids = array();
                         foreach ($iCal->getComponents() as $c) {
                             if ($c instanceof Horde_Icalendar_Vcard) {
                                 $content = $driver->toHash($c);
                                 $result = $driver->search($content);
                                 if (count($result)) {
                                     continue;
                                 }
                                 $ids[] = $driver->add($content);
                             }
                         }
                         return $ids;
                 }
                 break;
             default:
                 throw new Turba_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
         }
     }
     if ($content instanceof Horde_Icalendar_Vcard) {
         $content = $driver->toHash($content);
     }
     // Check if the entry already exists in the data source.
     $result = $driver->search($content);
     if (count($result)) {
         throw new Turba_Exception_ObjectExists(_("Already Exists"));
     }
     // We can't use $object->setValue() here since that cannot be used
     // with composite fields.
     $hooks = $injector->getInstance('Horde_Core_Hooks');
     if ($hooks->hookExists('encode_attribute', 'turba')) {
         foreach ($content as $attribute => &$value) {
             try {
                 $value = $hooks->callHook('encode_attribute', 'turba', array($attribute, $value, null, null));
             } catch (Turba_Exception $e) {
             }
         }
     }
     $result = $driver->add($content);
     return $driver->getObject($result)->getValue('__uid');
 }
Пример #15
0
 /**
  * Processes the components of a Horde_Icalendar container into an event
  * list.
  *
  * @param array $results             Gets filled with the events in the
  *                                   given time range.
  * @param Horde_Icalendar $ical      An Horde_Icalendar container.
  * @param Horde_Date $startInterval  Start of range date.
  * @param Horde_Date $endInterval    End of range date.
  * @param boolean $showRecurrence    Return every instance of a recurring
  *                                   event? If false, will only return
  *                                   recurring events once inside the
  *                                   $startDate - $endDate range.
  * @param boolean $json              Store the results of the events'
  *                                   toJson() method?
  * @param boolean $coverDates        Whether to add the events to all days
  *                                   that they cover.
  * $param boolean $hideExceptions    Hide events that represent exceptions
  *                                   to a recurring event.
  * @param string $id                 Enforce a certain event id (not UID).
  *
  * @throws Kronolith_Exception
  */
 protected function _processComponents(&$results, $ical, $startDate, $endDate, $showRecurrence, $json, $coverDates, $hideExceptions, $id = null)
 {
     $components = $ical->getComponents();
     $events = array();
     $count = count($components);
     $exceptions = array();
     for ($i = 0; $i < $count; $i++) {
         $component = $components[$i];
         if ($component->getType() == 'vEvent') {
             $event = new Kronolith_Event_Ical($this, $component);
             $event->permission = $this->getPermission();
             // Force string so JSON encoding is consistent across drivers.
             $event->id = $id ? $id : 'ical' . $i;
             /* Catch RECURRENCE-ID attributes which mark single recurrence
              * instances. */
             try {
                 $recurrence_id = $component->getAttribute('RECURRENCE-ID');
                 if (is_int($recurrence_id) && is_string($uid = $component->getAttribute('UID')) && is_int($seq = $component->getAttribute('SEQUENCE'))) {
                     $exceptions[$uid][$seq] = $recurrence_id;
                     if ($hideExceptions) {
                         continue;
                     }
                     $event->id .= '/' . $recurrence_id;
                 }
             } catch (Horde_Icalendar_Exception $e) {
             }
             /* Ignore events out of the period. */
             $recurs = $event->recurs();
             if ($endDate && $event->start->compareDateTime($endDate) > 0 || $startDate && !$recurs && $event->end->compareDateTime($startDate) < 0) {
                 continue;
             }
             if ($recurs && $startDate) {
                 // Fixed end date? Check if end is before start period.
                 if ($event->recurrence->hasRecurEnd() && $event->recurrence->recurEnd->compareDateTime($startDate) < 0) {
                     continue;
                 } elseif ($endDate) {
                     $next = $event->recurrence->nextRecurrence($startDate);
                     if ($next == false || $next->compareDateTime($endDate) > 0) {
                         continue;
                     }
                 }
             }
             $events[] = $event;
         }
     }
     /* Loop through all explicitly defined recurrence intances and create
      * exceptions for those in the event with the matching recurrence. */
     foreach ($events as $key => $event) {
         if ($event->recurs() && isset($exceptions[$event->uid][$event->sequence])) {
             $timestamp = $exceptions[$event->uid][$event->sequence];
             $events[$key]->recurrence->addException(date('Y', $timestamp), date('m', $timestamp), date('d', $timestamp));
         }
         Kronolith::addEvents($results, $event, $startDate, $endDate, $showRecurrence, $json, $coverDates);
     }
 }
Пример #16
0
 /**
  */
 public function davPutObject($collection, $object, $data)
 {
     $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage');
     $internal = $dav->getInternalCollectionId($collection, 'contacts') ?: $collection;
     $driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver')->create($internal);
     if (!$driver->hasPermission(Horde_Perms::EDIT)) {
         throw new Turba_Exception("Address Book does not exist or no permission to edit");
     }
     $ical = new Horde_Icalendar();
     if (!$ical->parsevCalendar($data)) {
         throw new Turba_Exception(_("There was an error importing the vCard data."));
     }
     foreach ($ical->getComponents() as $content) {
         if (!$content instanceof Horde_Icalendar_Vcard) {
             continue;
         }
         $contact = $driver->toHash($content);
         try {
             try {
                 $existing_id = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.vcf$/', '', $object);
             } catch (Horde_Dav_Exception $e) {
                 $existing_id = $object;
             }
             $existing_contact = $driver->getObject($existing_id);
             /* Check if our contact is newer then the existing - get the
              * contact's history. */
             $modified = $existing_contact->lastModification();
             try {
                 if (!empty($modified) && $content->getAttribute('LAST-MODIFIED')->before($modified)) {
                     /* LAST-MODIFIED timestamp of existing entry is newer:
                      * don't replace it. */
                     continue;
                 }
             } catch (Horde_Icalendar_Exception $e) {
             }
             foreach ($contact as $attribute => $value) {
                 if ($attribute != '__key') {
                     $existing_contact->setValue($attribute, $value);
                 }
             }
             $existing_contact->store();
         } catch (Horde_Exception_NotFound $e) {
             $id = $driver->add($contact);
             $dav->addObjectMap($id, $object, $internal);
         }
     }
 }
Пример #17
0
 /**
  * Import a contact represented in the specified contentType.
  *
  * @param string $content      The content of the contact.
  * @param string $contentType  What format is the data in? Currently
  *                             supports array, text/directory, text/vcard,
  *                             text/x-vcard, and activesync.
  * @param string $source       The source into which the contact will be
  *                             imported.
  *
  * @return string  The new UID.
  *
  * @throws Turba_Exception
  * @throws Turba_Exception_ObjectExists
  */
 public function import($content, $contentType = 'array', $source = null)
 {
     global $injector;
     $source = $this->_getSource($source);
     $driver = $injector->getInstance('Turba_Factory_Driver')->create($source);
     if (!$driver->hasPermission(Horde_Perms::EDIT)) {
         throw new Turba_Exception(_("Permission denied"));
     }
     if ($content instanceof Horde_Icalendar_Vcard) {
         $content = $driver->toHash($content);
     } else {
         switch ($contentType) {
             case 'activesync':
                 $content = $driver->fromASContact($content);
                 break;
             case 'array':
                 if (!isset($content['emails']) && isset($content['email'])) {
                     $content['emails'] = $content['email'];
                 }
                 break;
             case 'text/x-vcard':
             case 'text/vcard':
             case 'text/directory':
                 $iCal = new Horde_Icalendar();
                 if (!$iCal->parsevCalendar($content)) {
                     throw new Turba_Exception(_("There was an error importing the iCalendar data."));
                 }
                 switch ($iCal->getComponentCount()) {
                     case 0:
                         throw new Turba_Exception(_("No vCard data was found."));
                     case 1:
                         $content = $iCal->getComponent(0);
                         break;
                     default:
                         $ids = array();
                         foreach ($iCal->getComponents() as $c) {
                             if ($c instanceof Horde_Icalendar_Vcard) {
                                 $content = $driver->toHash($c);
                                 $result = $driver->search($content);
                                 if (count($result)) {
                                     continue;
                                 }
                                 $ids[] = $driver->add($content);
                             }
                         }
                         return $ids;
                 }
                 break;
             default:
                 throw new Turba_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
         }
     }
     // Check if the entry already exists in the data source.
     $result = $driver->search($content);
     if (count($result)) {
         throw new Turba_Exception_ObjectExists(_("Already Exists"));
     }
     // We can't use $object->setValue() here since that cannot be used
     // with composite fields.
     return $driver->getObject($driver->add($this->_encodeContent($content)))->getValue('__uid');
 }
Пример #18
0
 /**
  */
 public function davPutObject($collection, $object, $data)
 {
     $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage');
     $internal = $dav->getInternalCollectionId($collection, 'calendar') ?: $collection;
     if (!Kronolith::hasPermission($internal, Horde_Perms::EDIT)) {
         throw new Kronolith_Exception(_("Calendar does not exist or no permission to edit"));
     }
     $ical = new Horde_Icalendar();
     if (!$ical->parsevCalendar($data)) {
         throw new Kronolith_Exception(_("There was an error importing the iCalendar data."));
     }
     $kronolith_driver = Kronolith::getDriver(null, $internal);
     foreach ($ical->getComponents() as $content) {
         if (!$content instanceof Horde_Icalendar_Vevent) {
             continue;
         }
         $event = $kronolith_driver->getEvent();
         $event->fromiCalendar($content, true);
         try {
             try {
                 $existing_id = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.ics$/', '', $object);
             } catch (Horde_Dav_Exception $e) {
                 $existing_id = $object;
             }
             $existing_event = $kronolith_driver->getEvent($existing_id);
             /* Check if our event is newer then the existing - get the
              * event's history. */
             $existing_event->loadHistory();
             $modified = $existing_event->modified ?: $existing_event->created;
             try {
                 if (!empty($modified) && $content->getAttribute('LAST-MODIFIED') < $modified->timestamp()) {
                     /* LAST-MODIFIED timestamp of existing entry is newer:
                      * don't replace it. */
                     continue;
                 }
             } catch (Horde_Icalendar_Exception $e) {
             }
             // Don't change creator/owner.
             $event->creator = $existing_event->creator;
         } catch (Horde_Exception_NotFound $e) {
             $existing_event = null;
         }
         // Save entry.
         $id = $event->save();
         if (!$existing_event) {
             $dav->addObjectMap($id, $object, $internal);
         }
         // Send iTip messages.
         // Notifications will get lost, there is no way to return messages
         // to clients.
         Kronolith::sendITipNotifications($event, new Horde_Notification_Handler(new Horde_Notification_Storage_Object()), Kronolith::ITIP_REQUEST);
     }
 }
Пример #19
0
 /**
  * Return the rendered inline version of the Horde_Mime_Part object.
  *
  * @return array  See parent::render().
  */
 protected function _renderInline()
 {
     $browser = $this->getConfigParam('browser');
     $notification = $this->getConfigParam('notification');
     $prefs = $this->getConfigParam('prefs');
     $registry = $this->getConfigParam('registry');
     $data = $this->_mimepart->getContents();
     $html = '';
     $title = Horde_Core_Translation::t("vCard");
     $iCal = new Horde_Icalendar();
     if (!$iCal->parsevCalendar($data, 'VCALENDAR', $this->_mimepart->getCharset())) {
         $notification->push(Horde_Core_Translation::t("There was an error reading the contact data."), 'horde.error');
     }
     if (Horde_Util::getFormData('import') && Horde_Util::getFormData('source') && $registry->hasMethod('contacts/import')) {
         $source = Horde_Util::getFormData('source');
         $count = 0;
         foreach ($iCal->getComponents() as $c) {
             if ($c->getType() == 'vcard') {
                 try {
                     $registry->call('contacts/import', array($c, null, $source));
                     ++$count;
                 } catch (Horde_Exception $e) {
                     $notification->push(Horde_Core_Translation::t("There was an error importing the contact data:") . ' ' . $e->getMessage(), 'horde.error');
                 }
             }
         }
         $notification->push(sprintf(Horde_Core_Translation::ngettext("%d contact was successfully added to your address book.", "%d contacts were successfully added to your address book.", $count), $count), 'horde.success');
     }
     $html .= '<table class="horde-table" style="width:100%">';
     foreach ($iCal->getComponents() as $i => $vc) {
         if ($i > 0) {
             $html .= '<tr><td colspan="2">&nbsp;</td></tr>';
         }
         $addresses = $vc->getAllAttributes('EMAIL');
         $html .= '<tr><td colspan="2" class="header">';
         if (($fullname = $vc->getAttributeDefault('FN', false)) === false) {
             $fullname = count($addresses) ? $addresses[0]['value'] : Horde_Core_Translation::t("[No Label]");
         }
         $html .= htmlspecialchars($fullname) . '</td></tr>';
         $n = $vc->printableName();
         if (!empty($n)) {
             $html .= $this->_row(Horde_Core_Translation::t("Name"), $n);
         }
         try {
             $html .= $this->_row(Horde_Core_Translation::t("Alias"), implode("\n", $vc->getAttributeValues('ALIAS')));
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             $birthdays = $vc->getAttributeValues('BDAY');
             $birthday = new Horde_Date($birthdays[0]);
             $html .= $this->_row(Horde_Core_Translation::t("Birthday"), $birthday->strftime($prefs->getValue('date_format')));
         } catch (Horde_Icalendar_Exception $e) {
         }
         $photos = $vc->getAllAttributes('PHOTO');
         foreach ($photos as $p => $photo) {
             if (isset($photo['params']['VALUE']) && Horde_String::upper($photo['params']['VALUE']) == 'URI') {
                 $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . htmlspecialchars($photo['value']) . '" />', false);
             } elseif (isset($photo['params']['ENCODING']) && Horde_String::upper($photo['params']['ENCODING']) == 'B' && isset($photo['params']['TYPE'])) {
                 if ($browser->hasFeature('datauri') === true || $browser->hasFeature('datauri') >= strlen($photo['value'])) {
                     $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . Horde_Url_Data::create($photo['params']['TYPE'], base64_decode($photo['value'])) . '" />', false);
                 } elseif ($this->_imageUrl) {
                     $html .= $this->_row(Horde_Core_Translation::t("Photo"), '<img src="' . $this->_imageUrl->add(array('c' => $i, 'p' => $p)) . '" />', false);
                 }
             }
         }
         $labels = $vc->getAllAttributes('LABEL');
         foreach ($labels as $label) {
             if (isset($label['params']['TYPE'])) {
                 if (!is_array($label['params']['TYPE'])) {
                     $label['params']['TYPE'] = array($label['params']['TYPE']);
                 }
             } else {
                 $label['params']['TYPE'] = array_keys($label['params']);
             }
             $types = array();
             foreach ($label['params']['TYPE'] as $type) {
                 switch (Horde_String::upper($type)) {
                     case 'HOME':
                         $types[] = Horde_Core_Translation::t("Home Address");
                         break;
                     case 'WORK':
                         $types[] = Horde_Core_Translation::t("Work Address");
                         break;
                     case 'DOM':
                         $types[] = Horde_Core_Translation::t("Domestic Address");
                         break;
                     case 'INTL':
                         $types[] = Horde_Core_Translation::t("International Address");
                         break;
                     case 'POSTAL':
                         $types[] = Horde_Core_Translation::t("Postal Address");
                         break;
                     case 'PARCEL':
                         $types[] = Horde_Core_Translation::t("Parcel Address");
                         break;
                     case 'PREF':
                         $types[] = Horde_Core_Translation::t("Preferred Address");
                         break;
                 }
             }
             if (!count($types)) {
                 $types = array(Horde_Core_Translation::t("Address"));
             }
             $html .= $this->_row(implode('/', $types), $label['value']);
         }
         $adrs = $vc->getAllAttributes('ADR');
         foreach ($adrs as $item) {
             if (isset($item['params']['TYPE'])) {
                 if (!is_array($item['params']['TYPE'])) {
                     $item['params']['TYPE'] = array($item['params']['TYPE']);
                 }
             } else {
                 $item['params']['TYPE'] = array_keys($item['params']);
             }
             $address = $item['values'];
             $a = array();
             $a_list = array(Horde_Icalendar_Vcard::ADR_STREET, Horde_Icalendar_Vcard::ADR_LOCALITY, Horde_Icalendar_Vcard::ADR_REGION, Horde_Icalendar_Vcard::ADR_POSTCODE, Horde_Icalendar_Vcard::ADR_COUNTRY);
             foreach ($a_list as $val) {
                 if (isset($address[$val])) {
                     $a[] = $address[$val];
                 }
             }
             $types = array();
             foreach ($item['params']['TYPE'] as $type) {
                 switch (Horde_String::upper($type)) {
                     case 'HOME':
                         $types[] = Horde_Core_Translation::t("Home Address");
                         break;
                     case 'WORK':
                         $types[] = Horde_Core_Translation::t("Work Address");
                         break;
                     case 'DOM':
                         $types[] = Horde_Core_Translation::t("Domestic Address");
                         break;
                     case 'INTL':
                         $types[] = Horde_Core_Translation::t("International Address");
                         break;
                     case 'POSTAL':
                         $types[] = Horde_Core_Translation::t("Postal Address");
                         break;
                     case 'PARCEL':
                         $types[] = Horde_Core_Translation::t("Parcel Address");
                         break;
                     case 'PREF':
                         $types[] = Horde_Core_Translation::t("Preferred Address");
                         break;
                 }
             }
             if (!count($types)) {
                 $types = array(Horde_Core_Translation::t("Address"));
             }
             $html .= $this->_row(implode('/', $types), implode("\n", $a));
         }
         $numbers = $vc->getAllAttributes('TEL');
         foreach ($numbers as $number) {
             if (isset($number['params']['TYPE'])) {
                 if (!is_array($number['params']['TYPE'])) {
                     $number['params']['TYPE'] = array($number['params']['TYPE']);
                 }
                 foreach ($number['params']['TYPE'] as $type) {
                     $number['params'][Horde_String::upper($type)] = true;
                 }
             }
             if (isset($number['params']['FAX'])) {
                 $html .= $this->_row(Horde_Core_Translation::t("Fax"), $number['value']);
             } else {
                 if (isset($number['params']['HOME'])) {
                     $html .= $this->_row(Horde_Core_Translation::t("Home Phone"), $number['value']);
                 } elseif (isset($number['params']['WORK'])) {
                     $html .= $this->_row(Horde_Core_Translation::t("Work Phone"), $number['value']);
                 } elseif (isset($number['params']['CELL'])) {
                     $html .= $this->_row(Horde_Core_Translation::t("Cell Phone"), $number['value']);
                 } else {
                     $html .= $this->_row(Horde_Core_Translation::t("Phone"), $number['value']);
                 }
             }
         }
         $emails = array();
         foreach ($addresses as $address) {
             if (isset($address['params']['TYPE'])) {
                 if (!is_array($address['params']['TYPE'])) {
                     $address['params']['TYPE'] = array($address['params']['TYPE']);
                 }
                 foreach ($address['params']['TYPE'] as $type) {
                     $address['params'][Horde_String::upper($type)] = true;
                 }
             }
             $email = '<a href="';
             if ($registry->hasMethod('mail/compose')) {
                 $email .= $registry->call('mail/compose', array(array('to' => $address['value'])));
             } else {
                 $email .= 'mailto:' . htmlspecialchars($address['value']);
             }
             $email .= '">' . htmlspecialchars($address['value']) . '</a>';
             if (isset($address['params']['PREF'])) {
                 array_unshift($emails, $email);
             } else {
                 $emails[] = $email;
             }
         }
         if (count($emails)) {
             $html .= $this->_row(Horde_Core_Translation::t("Email"), implode("\n", $emails), false);
         }
         try {
             $title = $vc->getAttributeValues('TITLE');
             $html .= $this->_row(Horde_Core_Translation::t("Title"), $title[0]);
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             $role = $vc->getAttributeValues('ROLE');
             $html .= $this->_row(Horde_Core_Translation::t("Role"), $role[0]);
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             $org = $vc->getAttributeValues('ORG');
             $html .= $this->_row(Horde_Core_Translation::t("Company"), $org[0]);
             if (isset($org[1])) {
                 $html .= $this->_row(Horde_Core_Translation::t("Department"), $org[1]);
             }
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             $notes = $vc->getAttributeValues('NOTE');
             $html .= $this->_row(Horde_Core_Translation::t("Notes"), $notes[0]);
         } catch (Horde_Icalendar_Exception $e) {
         }
         try {
             $url = $vc->getAttributeValues('URL');
             $html .= $this->_row(Horde_Core_Translation::t("URL"), '<a href="' . htmlspecialchars($url[0]) . '" target="_blank">' . htmlspecialchars($url[0]) . '</a>', false);
         } catch (Horde_Icalendar_Exception $e) {
         }
     }
     $html .= '</table>';
     if ($registry->hasMethod('contacts/import') && $registry->hasMethod('contacts/sources')) {
         $html .= '<div class="horde-form-buttons"><form action="' . Horde::selfUrl() . '" method="get" name="vcard_import" id="vcard_import">' . Horde_Util::formInput();
         foreach ($_GET as $key => $val) {
             $html .= '<input type="hidden" name="' . htmlspecialchars($key) . '" value="' . htmlspecialchars($val) . '" />';
         }
         $sources = $registry->call('contacts/sources', array(true));
         if (count($sources) > 1) {
             $html .= '<input type="submit" class="horde-default" name="import" value="' . Horde_Core_Translation::t("Add to address book:") . '" />' . ' <label for="add_source" class="hidden">' . Horde_Core_Translation::t("Address Book") . '</label>' . '<select id="add_source" name="source">';
             foreach ($sources as $key => $label) {
                 $selected = $key == $prefs->getValue('add_source') ? ' selected="selected"' : '';
                 $html .= '<option value="' . htmlspecialchars($key) . '"' . $selected . '>' . htmlspecialchars($label) . '</option>';
             }
             $html .= '</select>';
         } else {
             reset($sources);
             $html .= '<input type="submit" class="horde-default" name="import" value="' . Horde_Core_Translation::t("Add to my address book") . '" />' . '<input type="hidden" name="source" value="' . htmlspecialchars(key($sources)) . '" />';
         }
         $html .= '</form></div>';
     }
     Horde::startBuffer();
     $notification->notify(array('listeners' => 'status'));
     return $this->_renderReturn(Horde::endBuffer() . $html, 'text/html; charset=' . $this->getConfigParam('charset'));
 }
Пример #20
0
 /**
  * Retrieves the free/busy information for a given email address, if any
  * information is available.
  *
  * @param string $email  The email address to look for.
  * @param boolean $json  Whether to return the free/busy data as a simple
  *                       object suitable to be transferred as json.
  *
  * @return Horde_Icalendar_Vfreebusy|object  Free/busy component.
  * @throws Kronolith_Exception
  */
 public static function get($email, $json = false)
 {
     $default_domain = empty($GLOBALS['conf']['storage']['default_domain']) ? null : $GLOBALS['conf']['storage']['default_domain'];
     $rfc822 = new Horde_Mail_Rfc822();
     try {
         $res = $rfc822->parseAddressList($email, array('default_domain' => $default_domain));
     } catch (Horde_Mail_Exception $e) {
         throw new Kronolith_Exception($e);
     }
     if (!($tmp = $res[0])) {
         throw new Kronolith_Exception(_("No valid email address found"));
     }
     $email = $tmp->bare_address;
     /* Check if we can retrieve a VFB from the Free/Busy URL, if one is
      * set. */
     $url = self::getUrl($email);
     if ($url) {
         $url = trim($url);
         $http = $GLOBALS['injector']->getInstance('Horde_Core_Factory_HttpClient')->create(array('request.verifyPeer' => false));
         try {
             $response = $http->get($url);
         } catch (Horde_Http_Exception $e) {
             throw new Kronolith_Exception(sprintf(_("The free/busy url for %s cannot be retrieved."), $email));
         }
         if ($response->code == 200 && ($data = $response->getBody())) {
             // Detect the charset of the iCalendar data.
             $contentType = $response->getHeader('Content-Type');
             if ($contentType && strpos($contentType, ';') !== false) {
                 list(, $charset, ) = explode(';', $contentType);
                 $data = Horde_String::convertCharset($data, trim(str_replace('charset=', '', $charset)), 'UTF-8');
             }
             $vCal = new Horde_Icalendar();
             $vCal->parsevCalendar($data, 'VCALENDAR');
             $components = $vCal->getComponents();
             $vCal = new Horde_Icalendar();
             $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal);
             $vFb->setAttribute('ORGANIZER', $email);
             $found = false;
             foreach ($components as $component) {
                 if ($component instanceof Horde_Icalendar_Vfreebusy) {
                     $found = true;
                     $vFb->merge($component);
                 }
             }
             if ($found) {
                 // @todo: actually store the results in the storage, so
                 // that they can be retrieved later. We should store the
                 // plain iCalendar data though, to avoid versioning
                 // problems with serialize iCalendar objects.
                 return $json ? self::toJson($vFb) : $vFb;
             }
         }
     }
     /* Check storage driver. */
     $storage = $GLOBALS['injector']->getInstance('Kronolith_Factory_Storage')->create();
     try {
         $fb = $storage->search($email);
         return $json ? self::toJson($fb) : $fb;
     } catch (Horde_Exception_NotFound $e) {
         if ($url) {
             throw new Kronolith_Exception(sprintf(_("No free/busy information found at the free/busy url of %s."), $email));
         }
         throw new Kronolith_Exception(sprintf(_("No free/busy url found for %s."), $email));
     }
 }
Пример #21
0
 /**
  * Replaces the event identified by UID with the content represented in the
  * specified contentType.
  *
  * @param string $uid          Idenfity the event to replace.
  * @param mixed  $content      The content of the event. String or
  *                             Horde_Icalendar_Vevent
  * @param string $contentType  What format is the data in? Currently supports:
  *                             text/calendar
  *                             text/x-vcalendar
  *                             (Ignored if content is Horde_Icalendar_Vevent)
  *                             activesync (Horde_ActiveSync_Message_Appointment)
  * @param string $calendar     Ensure the event is replaced in the specified
  *                             calendar. @since 4.2.0
  *
  * @return  mixed  For EAS operations, an array of 'uid' and 'atchash'
  *                 are returned. @since 4.3.0
  * @throws Kronolith_Exception
  */
 public function replace($uid, $content, $contentType, $calendar = null)
 {
     $event = Kronolith::getDriver(null, $calendar)->getByUID($uid);
     if (!$event->hasPermission(Horde_Perms::EDIT) || $event->private && $event->creator != $GLOBALS['registry']->getAuth()) {
         throw new Horde_Exception_PermissionDenied();
     }
     if ($content instanceof Horde_Icalendar_Vevent) {
         $component = $content;
     } elseif ($content instanceof Horde_ActiveSync_Message_Appointment) {
         $event->fromASAppointment($content);
         $atc_hash = $event->addEASFiles($content);
         $event->save();
         $event->uid = $uid;
         return array('uid' => $event->uid, 'atchash' => $atc_hash);
         return;
     } else {
         switch ($contentType) {
             case 'text/calendar':
             case 'text/x-vcalendar':
                 if (!$content instanceof Horde_Icalendar_Vevent) {
                     $iCal = new Horde_Icalendar();
                     if (!$iCal->parsevCalendar($content)) {
                         throw new Kronolith_Exception(_("There was an error importing the iCalendar data."));
                     }
                     $components = $iCal->getComponents();
                     $component = null;
                     foreach ($components as $content) {
                         if ($content instanceof Horde_Icalendar_Vevent) {
                             if ($component !== null) {
                                 throw new Kronolith_Exception(_("Multiple iCalendar components found; only one vEvent is supported."));
                             }
                             $component = $content;
                         }
                     }
                     if ($component === null) {
                         throw new Kronolith_Exception(_("No iCalendar data was found."));
                     }
                 }
                 break;
             default:
                 throw new Kronolith_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
         }
     }
     try {
         $component->getAttribute('RECURRENCE-ID');
         $this->_addiCalEvent($component, Kronolith::getDriver(null, $calendar), true);
     } catch (Horde_Icalendar_Exception $e) {
         $event->fromiCalendar($component, true);
         // Ensure we keep the original UID, even when content does not
         // contain one and fromiCalendar creates a new one.
         $event->uid = $uid;
         $event->save();
     }
 }
Пример #22
0
 /**
  * @requires extension bcmath
  */
 public function testMeetingTnef()
 {
     $winmail = file_get_contents(__DIR__ . '/fixtures/winmail2.dat');
     $tnef = Horde_Compress::factory('Tnef');
     $tnef_data = $tnef->decompress($winmail);
     // Test the meta data
     $this->assertEquals($tnef_data[0]['type'], 'text');
     $this->assertEquals($tnef_data[0]['subtype'], 'calendar');
     $this->assertEquals($tnef_data[0]['name'], 'Test Meeting');
     // Test the generated iCalendar.
     $iCal = new Horde_Icalendar();
     if (!$iCal->parsevCalendar($tnef_data[0]['stream'])) {
         throw new Horde_Compress_Exception(_("There was an error importing the iCalendar data."));
     }
     $components = $iCal->getComponents();
     if (count($components) == 0) {
         throw new Horde_Compress_Exception(_("No iCalendar data was found."));
     }
     $iTip = current($components);
     $this->assertEquals($iTip->getAttribute('SUMMARY'), 'Test Meeting');
     $this->assertEquals($iTip->getAttribute('DESCRIPTION'), 'This is a test meeting.');
     $this->assertEquals($iTip->getAttribute('ORGANIZER'), 'mailto:mike@theupstairsroom.com');
     $this->assertEquals($iTip->getAttribute('UID'), 'D38D34D34D34F36D347B4D34EF87396F00000000367B4D3CD34D34D34D34EF4774D3877BF3ADDA774D35D34D34D34D34D34D34D34D34D74D34D34D34D3471CF747DB6F469FE5EE34F386FCE75F79DFC6B675FE9D');
     $this->assertEquals($iTip->getAttribute('ATTENDEE'), '*****@*****.**');
     $params = $iTip->getAttribute('ATTENDEE', true);
     if (!$params) {
         throw new Horde_Compress_Exception('Could not find expected parameters.');
     }
     $this->assertEquals($params[0]['ROLE'], 'REQ-PARTICIPANT');
     $this->assertEquals($params[0]['PARTSTAT'], 'NEEDS-ACTION');
     $this->assertEquals($params[0]['RSVP'], 'TRUE');
 }
Пример #23
0
 public function vtodo2sif($vcard)
 {
     $iCal = new Horde_Icalendar();
     if (!$iCal->parsevCalendar($vcard)) {
         return PEAR::raiseError('There was an error importing the data.');
     }
     $components = $iCal->getComponents();
     switch (count($components)) {
         case 0:
             return PEAR::raiseError('No data was found');
         case 1:
             $content = $components[0];
             break;
         default:
             return PEAR::raiseError('Multiple components found; only one is supported.');
     }
     $hash['Complete'] = 0;
     $due = false;
     $attr = $content->getAllAttributes();
     foreach ($attr as $item) {
         switch ($item['name']) {
             case 'SUMMARY':
                 $hash['Subject'] = $item['value'];
                 break;
             case 'DESCRIPTION':
                 $hash['Body'] = $item['value'];
                 break;
             case 'PRIORITY':
                 if ($item['value'] == 1) {
                     $hash['Importance'] = 2;
                 } elseif ($item['value'] == 5) {
                     $hash['Importance'] = 0;
                 } else {
                     $hash['Importance'] = 1;
                 }
                 break;
             case 'DTSTART':
                 $hash['StartDate'] = Horde_Icalendar::_exportDateTime($item['value']);
                 break;
             case 'DUE':
                 $hash['DueDate'] = Horde_Icalendar::_exportDateTime($item['value']);
                 $due = $item['value'];
                 break;
             case 'AALARM':
                 $hash['ReminderTime'] = $item['value'];
                 $hash['ReminderSet'] = 1;
                 break;
             case 'STATUS':
                 $hash['Complete'] = $item['value'] == 'COMPLETED' ? 1 : 0;
                 break;
             case 'CATEGORIES':
                 $hash['Categories'] = $item['value'];
                 break;
             case 'CLASS':
                 switch (Horde_String::upper($item['value'])) {
                     case 'PUBLIC':
                         $hash['Sensitivity'] = 0;
                         break;
                     case 'PRIVATE':
                         $hash['Sensitivity'] = 2;
                         break;
                     case 'CONFIDENTIAL':
                         $hash['Sensitivity'] = 3;
                         break;
                 }
                 break;
         }
     }
     if ($due && !isset($hash['ReminderSet'])) {
         // Parse VALARM components.
         foreach ($content->getComponents() as $component) {
             if ($component->getType() != 'vAlarm') {
                 continue;
             }
             try {
                 $trigger = $component->getAttribute('TRIGGER');
             } catch (Horde_Icalendar_Exception $e) {
                 continue;
             }
             if (is_array($trigger) || empty($trigger)) {
                 continue;
             }
             $hash['ReminderSet'] = 1;
             $hash['ReminderTime'] = Horde_Icalendar::_exportDateTime($due - $trigger);
         }
     }
     return Horde_SyncMl_Device_sync4j::array2sif($hash, '<?xml version="1.0"?><task>', '</task>');
 }
Пример #24
0
 /**
  * Replace the memo identified by UID with the content represented in
  * the specified contentType.
  *
  * @param string $uid          Idenfity the memo to replace.
  * @param string $content      The content of the memo.
  * @param string $contentType  What format is the data in? Currently supports:
  *                             text/plain
  *                             text/x-vnote
  *                             activesync
  * @throws Mnemo_Exception
  * @throws Horde_Exception_PermissionDenied
  */
 public function replace($uid, $content, $contentType)
 {
     $storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create();
     $memo = $storage->getByUID($uid);
     if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, Horde_Perms::EDIT))) {
         throw new Horde_Exception_PermissionDenied();
     }
     switch ($contentType) {
         case 'text/plain':
             $storage->modify($memo['memo_id'], $storage->getMemoDescription($content), $content, null);
             break;
         case 'text/x-vnote':
             if (!$content instanceof Horde_Icalendar_Vnote) {
                 $iCal = new Horde_Icalendar();
                 if (!$iCal->parsevCalendar($content)) {
                     throw new Mnemo_Exception(_("There was an error importing the iCalendar data."));
                 }
                 $components = $iCal->getComponents();
                 switch (count($components)) {
                     case 0:
                         throw new Mnemo_Exception(_("No iCalendar data was found."));
                     case 1:
                         $content = $components[0];
                         break;
                     default:
                         throw new Mnemo_Exception(_("Multiple iCalendar components found; only one vNote is supported."));
                 }
             }
             $note = $storage->fromiCalendar($content);
             $storage->modify($memo['memo_id'], $note['desc'], $note['body'], !empty($note['tags']) ? $note['tags'] : '');
             break;
         case 'activesync':
             $storage->modify($memo['memo_id'], $content->subject, $content->body->data, $content->categories);
             break;
         default:
             throw new Mnemo_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType));
     }
 }
Пример #25
0
 /**
  * Variables required in form input:
  *   - identity (TODO: ? Code uses it, but it is never set anywhere)
  *   - imple_submit: itip_action(s)
  *   - mime_id
  *   - muid
  *
  * @return boolean  True on success.
  */
 protected function _handle(Horde_Variables $vars)
 {
     global $injector, $notification, $registry;
     $actions = (array) $vars->imple_submit;
     $result = false;
     $vCal = new Horde_Icalendar();
     /* Retrieve the calendar data from the message. */
     try {
         $contents = $injector->getInstance('IMP_Factory_Contents')->create(new IMP_Indices_Mailbox($vars));
         $mime_part = $contents->getMIMEPart($vars->mime_id);
         if (empty($mime_part)) {
             throw new IMP_Exception(_("Cannot retrieve calendar data from message."));
         } elseif (!$vCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) {
             throw new IMP_Exception(_("The calendar data is invalid"));
         }
         $components = $vCal->getComponents();
     } catch (Exception $e) {
         $notification->push($e, 'horde.error');
         $actions = array();
     }
     foreach ($actions as $key => $action) {
         $pos = strpos($key, '[');
         $key = substr($key, $pos + 1, strlen($key) - $pos - 2);
         switch ($action) {
             case 'delete':
                 // vEvent cancellation.
                 if ($registry->hasMethod('calendar/delete')) {
                     $guid = $components[$key]->getAttribute('UID');
                     $recurrenceId = null;
                     try {
                         // This is a cancellation of a recurring event instance.
                         $recurrenceId = $components[$key]->getAttribute('RECURRENCE-ID');
                         $atts = $components[$key]->getAttribute('RECURRENCE-ID', true);
                         $range = null;
                         foreach ($atts as $att) {
                             if (array_key_exists('RANGE', $att)) {
                                 $range = $att['RANGE'];
                             }
                         }
                     } catch (Horde_Icalendar_Exception $e) {
                     }
                     try {
                         $registry->call('calendar/delete', array($guid, $recurrenceId, $range));
                         $notification->push(_("Event successfully deleted."), 'horde.success');
                         $result = true;
                     } catch (Horde_Exception $e) {
                         $notification->push(sprintf(_("There was an error deleting the event: %s"), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'update':
                 // vEvent reply.
                 if ($registry->hasMethod('calendar/updateAttendee')) {
                     try {
                         $from = $contents->getHeader()->getOb('from');
                         $registry->call('calendar/updateAttendee', array($components[$key], $from[0]->bare_address));
                         $notification->push(_("Respondent Status Updated."), 'horde.success');
                         $result = true;
                     } catch (Horde_Exception $e) {
                         $notification->push(sprintf(_("There was an error updating the event: %s"), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'import':
             case 'accept-import':
                 // vFreebusy reply.
                 // vFreebusy publish.
                 // vEvent request.
                 // vEvent publish.
                 // vTodo publish.
                 // vJournal publish.
                 switch ($components[$key]->getType()) {
                     case 'vEvent':
                         $result = $this->_handlevEvent($key, $components, $mime_part);
                         // Must check for exceptions.
                         foreach ($components as $k => $component) {
                             try {
                                 if ($component->getType() == 'vEvent' && $component->getAttribute('RECURRENCE-ID')) {
                                     $uid = $component->getAttribute('UID');
                                     if ($uid == $components[$key]->getAttribute('UID')) {
                                         $this->_handlevEvent($k, $components, $mime_part);
                                     }
                                 }
                             } catch (Horde_Icalendar_Exception $e) {
                             }
                         }
                         break;
                     case 'vFreebusy':
                         // Import into Kronolith.
                         if ($registry->hasMethod('calendar/import_vfreebusy')) {
                             try {
                                 $registry->call('calendar/import_vfreebusy', array($components[$key]));
                                 $notification->push(_("The user's free/busy information was sucessfully stored."), 'horde.success');
                                 $result = true;
                             } catch (Horde_Exception $e) {
                                 $notification->push(sprintf(_("There was an error importing user's free/busy information: %s"), $e->getMessage()), 'horde.error');
                             }
                         } else {
                             $notification->push(_("This action is not supported."), 'horde.warning');
                         }
                         break;
                     case 'vTodo':
                         // Import into Nag.
                         if ($registry->hasMethod('tasks/import')) {
                             try {
                                 $guid = $registry->call('tasks/import', array($components[$key], $mime_part->getType()));
                                 $url = Horde::url($registry->link('tasks/show', array('uid' => $guid)));
                                 $notification->push(_("The task has been added to your tasklist.") . '&nbsp;' . Horde::link($url, _("View task"), null, '_blank') . Horde_Themes_Image::tag('mime/icalendar.png', array('alt' => _("View task"))) . '</a>', 'horde.success', array('content.raw'));
                                 $result = true;
                             } catch (Horde_Exception $e) {
                                 $notification->push(sprintf(_("There was an error importing the task: %s"), $e->getMessage()), 'horde.error');
                             }
                         } else {
                             $notification->push(_("This action is not supported."), 'horde.warning');
                         }
                         break;
                     case 'vJournal':
                     default:
                         $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 if ($action == 'import') {
                     break;
                 }
                 // Fall-through for 'accept-import'
             // Fall-through for 'accept-import'
             case 'accept':
             case 'deny':
             case 'tentative':
                 // vEvent request.
                 if (isset($components[$key]) && $components[$key]->getType() == 'vEvent') {
                     $vEvent = $components[$key];
                     $resource = new Horde_Itip_Resource_Identity($injector->getInstance('IMP_Identity'), $vEvent->getAttribute('ATTENDEE'), $vars->identity);
                     switch ($action) {
                         case 'accept':
                         case 'accept-import':
                             $type = new Horde_Itip_Response_Type_Accept($resource);
                             break;
                         case 'deny':
                             $type = new Horde_Itip_Response_Type_Decline($resource);
                             break;
                         case 'tentative':
                             $type = new Horde_Itip_Response_Type_Tentative($resource);
                             break;
                     }
                     try {
                         // Send the reply.
                         Horde_Itip::factory($vEvent, $resource)->sendMultiPartResponse($type, new Horde_Core_Itip_Response_Options_Horde('UTF-8', array()), $injector->getInstance('IMP_Mail'));
                         $notification->push(_("Reply Sent."), 'horde.success');
                         $result = true;
                     } catch (Horde_Itip_Exception $e) {
                         $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("This action is not supported."), 'horde.warning');
                 }
                 break;
             case 'send':
             case 'reply':
             case 'reply2m':
                 // vfreebusy request.
                 if (isset($components[$key]) && $components[$key]->getType() == 'vFreebusy') {
                     $vFb = $components[$key];
                     // Get the organizer details.
                     try {
                         $organizer = parse_url($vFb->getAttribute('ORGANIZER'));
                     } catch (Horde_Icalendar_Exception $e) {
                         break;
                     }
                     $organizerEmail = $organizer['path'];
                     $organizer = $vFb->getAttribute('ORGANIZER', true);
                     $organizerFullEmail = new Horde_Mail_Rfc822_Address($organizerEmail);
                     if (isset($organizer['cn'])) {
                         $organizerFullEmail->personal = $organizer['cn'];
                     }
                     if ($action == 'reply2m') {
                         $startStamp = time();
                         $endStamp = $startStamp + 60 * 24 * 3600;
                     } else {
                         try {
                             $startStamp = $vFb->getAttribute('DTSTART');
                         } catch (Horde_Icalendar_Exception $e) {
                             $startStamp = time();
                         }
                         try {
                             $endStamp = $vFb->getAttribute('DTEND');
                         } catch (Horde_Icalendar_Exception $e) {
                         }
                         if (!$endStamp) {
                             try {
                                 $duration = $vFb->getAttribute('DURATION');
                                 $endStamp = $startStamp + $duration;
                             } catch (Horde_Icalendar_Exception $e) {
                                 $endStamp = $startStamp + 60 * 24 * 3600;
                             }
                         }
                     }
                     $vfb_reply = $registry->call('calendar/getFreeBusy', array($startStamp, $endStamp));
                     // Find out who we are and update status.
                     $identity = $injector->getInstance('IMP_Identity');
                     $email = $identity->getFromAddress();
                     // Build the reply.
                     $msg_headers = new Horde_Mime_Headers();
                     $vCal = new Horde_Icalendar();
                     $vCal->setAttribute('PRODID', '-//The Horde Project//' . $msg_headers->getUserAgent() . '//EN');
                     $vCal->setAttribute('METHOD', 'REPLY');
                     $vCal->addComponent($vfb_reply);
                     $message = _("Attached is a reply to a calendar request you sent.");
                     $body = new Horde_Mime_Part();
                     $body->setType('text/plain');
                     $body->setCharset('UTF-8');
                     $body->setContents(Horde_String::wrap($message, 76));
                     $ics = new Horde_Mime_Part();
                     $ics->setType('text/calendar');
                     $ics->setCharset('UTF-8');
                     $ics->setContents($vCal->exportvCalendar());
                     $ics->setName('icalendar.ics');
                     $ics->setContentTypeParameter('METHOD', 'REPLY');
                     $mime = new Horde_Mime_Part();
                     $mime->addPart($body);
                     $mime->addPart($ics);
                     // Build the reply headers.
                     $msg_headers->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name']));
                     $msg_headers->addMessageIdHeader();
                     $msg_headers->addHeader('Date', date('r'));
                     $msg_headers->addHeader('From', $email);
                     $msg_headers->addHeader('To', $organizerFullEmail);
                     $identity->setDefault($vars->identity);
                     $replyto = $identity->getValue('replyto_addr');
                     if (!empty($replyto) && !$email->match($replyto)) {
                         $msg_headers->addHeader('Reply-To', $replyto);
                     }
                     $msg_headers->addHeader('Subject', _("Free/Busy Request Response"));
                     // Send the reply.
                     try {
                         $mime->send($organizerEmail, $msg_headers, $injector->getInstance('IMP_Mail'));
                         $notification->push(_("Reply Sent."), 'horde.success');
                         $result = true;
                     } catch (Exception $e) {
                         $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error');
                     }
                 } else {
                     $notification->push(_("Invalid Action selected for this component."), 'horde.warning');
                 }
                 break;
             case 'nosup':
                 // vFreebusy request.
             // vFreebusy request.
             default:
                 $notification->push(_("This action is not supported."), 'horde.warning');
                 break;
         }
     }
     return $result;
 }
Пример #26
0
 public function testBug12869RecurrenceEndFromIcalendar()
 {
     date_default_timezone_set('Europe/Amsterdam');
     $iCal = new Horde_Icalendar();
     $iCal->parsevCalendar(file_get_contents(__DIR__ . '/fixtures/bug12869.ics'));
     $components = $iCal->getComponents();
     foreach ($components as $content) {
         if ($content instanceof Horde_Icalendar_Vevent) {
             $start = new Horde_Date($content->getAttribute('DTSTART'));
             $end = new Horde_Date($content->getAttribute('DTEND'));
             $rrule = $content->getAttribute('RRULE');
             $recurrence = new Horde_Date_Recurrence($start, $end);
             $recurrence->fromRRule20($rrule);
             break;
         }
     }
     $after = array('year' => 2013, 'month' => 12);
     $after['mday'] = 11;
     $this->assertEquals('2013-12-12 13:45:00', (string) $recurrence->nextRecurrence($after));
     $after['mday'] = 18;
     $this->assertEquals('2013-12-19 13:45:00', (string) $recurrence->nextRecurrence($after));
     $after['mday'] = 20;
     $this->assertEquals('', (string) $recurrence->nextRecurrence($after));
     date_default_timezone_set('Europe/Berlin');
 }