Return a reference to a new component.
public static newComponent ( string $type, Horde_Icalendar $container ) : object | ||
$type | string | The type of component to return |
$container | Horde_Icalendar | A container that this component will be associated with. |
리턴 | object | Reference to a Horde_Icalendar_* object as specified. |
/** */ protected function _create($mbox, $subject, $body) { global $notification, $registry; $list = str_replace(self::TASKLIST_EDIT, '', $mbox); /* Create a new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//IMP ' . $registry->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); /* Create a new vTodo object using this message's contents. */ $vTodo = Horde_Icalendar::newComponent('vtodo', $vCal); $vTodo->setAttribute('SUMMARY', $subject); $vTodo->setAttribute('DESCRIPTION', $body); $vTodo->setAttribute('PRIORITY', '3'); /* Get the list of editable tasklists. */ $lists = $this->getTasklists(true); /* Attempt to add the new vTodo item to the requested tasklist. */ try { $res = $registry->call('tasks/import', array($vTodo, 'text/calendar', $list)); } catch (Horde_Exception $e) { $notification->push($e); return; } if (!$res) { $notification->push(_("An unknown error occured while creating the new task."), 'horde.error'); } elseif (!empty($lists)) { $name = '"' . htmlspecialchars($subject) . '"'; /* Attempt to convert the object name into a hyperlink. */ if ($registry->hasLink('tasks/show')) { $name = sprintf('<a href="%s">%s</a>', Horde::url($registry->link('tasks/show', array('uid' => $res))), $name); } $notification->push(sprintf(_("%s was successfully added to \"%s\"."), $name, htmlspecialchars($lists[$list]->get('name'))), 'horde.success', array('content.raw')); } }
/** * Return the response as an iCalendar vEvent object. * * @param Horde_Itip_Response_Type $type The response type. * @param Horde_Icalendar|boolean $vCal The parent container or false if not * provided. * * @return Horde_Icalendar_Vevent The response object. */ public function getVevent(Horde_Itip_Response_Type $type, $vCal = false) { $itip_reply = new Horde_Itip_Event_Vevent(Horde_Icalendar::newComponent('VEVENT', $vCal)); $this->_request->copyEventInto($itip_reply); $type->setRequest($this->_request); $itip_reply->setAttendee($this->_resource->getMailAddress(), $this->_resource->getCommonName(), $type->getStatus()); return $itip_reply->getVevent(); }
/** * Exports this event in iCalendar format. * * @param Horde_Icalendar $calendar A Horde_Icalendar object that acts as * a container. * * @return array An array of Horde_Icalendar_Vevent objects for this event. */ public function toiCalendar($calendar) { $vEvent = Horde_Icalendar::newComponent('vevent', $calendar); $v1 = $calendar->getAttribute('VERSION') == '1.0'; $vEvents = array(); // For certain recur types, we must output in the event's timezone // so that the BYDAY values do not get out of sync with the UTC // date-time. See Bug: 11339 if ($this->recurs()) { switch ($this->recurrence->getRecurType()) { case Horde_Date_Recurrence::RECUR_WEEKLY: case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: if (!$this->timezone) { $this->timezone = date_default_timezone_get(); } } } if ($this->isAllDay()) { $vEvent->setAttribute('DTSTART', $this->start, array('VALUE' => 'DATE')); $vEvent->setAttribute('DTEND', $this->end, array('VALUE' => 'DATE')); $vEvent->setAttribute('X-FUNAMBOL-ALLDAY', 1); } else { $this->setTimezone(true); $params = array(); if ($this->timezone) { try { if (!$this->baseid) { $tz = $GLOBALS['injector']->getInstance('Horde_Timezone'); $vEvents[] = $tz->getZone($this->timezone)->toVtimezone(); } $params['TZID'] = $this->timezone; } catch (Horde_Exception $e) { Horde::log('Unable to locate the tz database.', 'WARN'); } } $vEvent->setAttribute('DTSTART', clone $this->start, $params); $vEvent->setAttribute('DTEND', clone $this->end, $params); } $vEvent->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vEvent->setAttribute('UID', $this->uid); /* Get the event's create and last modify date. */ $created = $modified = null; try { $history = $GLOBALS['injector']->getInstance('Horde_History'); $created = $history->getActionTimestamp('kronolith:' . $this->calendar . ':' . $this->uid, 'add'); $modified = $history->getActionTimestamp('kronolith:' . $this->calendar . ':' . $this->uid, 'modify'); /* The history driver returns 0 for not found. If 0 or null does * not matter, strip this. */ if ($created == 0) { $created = null; } if ($modified == 0) { $modified = null; } } catch (Exception $e) { } if (!empty($created)) { $vEvent->setAttribute($v1 ? 'DCREATED' : 'CREATED', $created); if (empty($modified)) { $modified = $created; } } if (!empty($modified)) { $vEvent->setAttribute('LAST-MODIFIED', $modified); } $vEvent->setAttribute('SUMMARY', $this->getTitle()); // Organizer if (count($this->attendees)) { $name = Kronolith::getUserName($this->creator); $email = Kronolith::getUserEmail($this->creator); $params = array(); if ($v1) { $tmp = new Horde_Mail_Rfc822_Address($email); if (!empty($name)) { $tmp->personal = $name; } $email = strval($tmp); } else { if (!empty($name)) { $params['CN'] = $name; } if (!empty($email)) { $email = 'mailto:' . $email; } } $vEvent->setAttribute('ORGANIZER', $email, $params); } if (!$this->isPrivate()) { if (!empty($this->description)) { $vEvent->setAttribute('DESCRIPTION', $this->description); } // Tags if ($this->tags) { $tags = implode(', ', $this->tags); $vEvent->setAttribute('CATEGORIES', $tags); } // Location if (!empty($this->location)) { $vEvent->setAttribute('LOCATION', $this->location); } if ($this->geoLocation) { $vEvent->setAttribute('GEO', array('latitude' => $this->geoLocation['lat'], 'longitude' => $this->geoLocation['lon'])); } // URL if (!empty($this->url)) { $vEvent->setAttribute('URL', $this->url); } } $vEvent->setAttribute('CLASS', $this->private ? 'PRIVATE' : 'PUBLIC'); // Status. switch ($this->status) { case Kronolith::STATUS_FREE: // This is not an official iCalendar value, but we need it for // synchronization. $vEvent->setAttribute('STATUS', 'FREE'); $vEvent->setAttribute('TRANSP', $v1 ? 1 : 'TRANSPARENT'); break; case Kronolith::STATUS_TENTATIVE: $vEvent->setAttribute('STATUS', 'TENTATIVE'); $vEvent->setAttribute('TRANSP', $v1 ? 0 : 'OPAQUE'); break; case Kronolith::STATUS_CONFIRMED: $vEvent->setAttribute('STATUS', 'CONFIRMED'); $vEvent->setAttribute('TRANSP', $v1 ? 0 : 'OPAQUE'); break; case Kronolith::STATUS_CANCELLED: if ($v1) { $vEvent->setAttribute('STATUS', 'DECLINED'); $vEvent->setAttribute('TRANSP', 1); } else { $vEvent->setAttribute('STATUS', 'CANCELLED'); $vEvent->setAttribute('TRANSP', 'TRANSPARENT'); } break; } // Attendees. foreach ($this->attendees as $email => $status) { $params = array(); switch ($status['attendance']) { case Kronolith::PART_REQUIRED: if ($v1) { $params['EXPECT'] = 'REQUIRE'; } else { $params['ROLE'] = 'REQ-PARTICIPANT'; } break; case Kronolith::PART_OPTIONAL: if ($v1) { $params['EXPECT'] = 'REQUEST'; } else { $params['ROLE'] = 'OPT-PARTICIPANT'; } break; case Kronolith::PART_NONE: if ($v1) { $params['EXPECT'] = 'FYI'; } else { $params['ROLE'] = 'NON-PARTICIPANT'; } break; } switch ($status['response']) { case Kronolith::RESPONSE_NONE: if ($v1) { $params['STATUS'] = 'NEEDS ACTION'; $params['RSVP'] = 'YES'; } else { $params['PARTSTAT'] = 'NEEDS-ACTION'; $params['RSVP'] = 'TRUE'; } break; case Kronolith::RESPONSE_ACCEPTED: if ($v1) { $params['STATUS'] = 'ACCEPTED'; } else { $params['PARTSTAT'] = 'ACCEPTED'; } break; case Kronolith::RESPONSE_DECLINED: if ($v1) { $params['STATUS'] = 'DECLINED'; } else { $params['PARTSTAT'] = 'DECLINED'; } break; case Kronolith::RESPONSE_TENTATIVE: if ($v1) { $params['STATUS'] = 'TENTATIVE'; } else { $params['PARTSTAT'] = 'TENTATIVE'; } break; } if (strpos($email, '@') === false) { $email = ''; } if ($v1) { if (empty($email)) { if (!empty($status['name'])) { $email = $status['name']; } } else { $tmp = new Horde_Mail_Rfc822_Address($email); if (!empty($status['name'])) { $tmp->personal = $status['name']; } $email = strval($tmp); } } else { if (!empty($status['name'])) { $params['CN'] = $status['name']; } if (!empty($email)) { $email = 'mailto:' . $email; } } $vEvent->setAttribute('ATTENDEE', $email, $params); } // Alarms. if (!empty($this->alarm)) { if ($v1) { $alarm = new Horde_Date($this->start); $alarm->min -= $this->alarm; $vEvent->setAttribute('AALARM', $alarm); } else { $vAlarm = Horde_Icalendar::newComponent('valarm', $vEvent); $vAlarm->setAttribute('ACTION', 'DISPLAY'); $vAlarm->setAttribute('DESCRIPTION', $this->getTitle()); $vAlarm->setAttribute('TRIGGER;VALUE=DURATION', ($this->alarm > 0 ? '-' : '') . 'PT' . abs($this->alarm) . 'M'); $vEvent->addComponent($vAlarm); } $hordeAlarm = $GLOBALS['injector']->getInstance('Horde_Alarm'); if ($hordeAlarm->exists($this->uid, $GLOBALS['registry']->getAuth()) && $hordeAlarm->isSnoozed($this->uid, $GLOBALS['registry']->getAuth())) { $vEvent->setAttribute('X-MOZ-LASTACK', new Horde_Date($_SERVER['REQUEST_TIME'])); $alarm = $hordeAlarm->get($this->uid, $GLOBALS['registry']->getAuth()); if (!empty($alarm['snooze'])) { $alarm['snooze']->setTimezone(date_default_timezone_get()); $vEvent->setAttribute('X-MOZ-SNOOZE-TIME', $alarm['snooze']); } } } // Recurrence. if ($this->recurs()) { if ($v1) { $rrule = $this->recurrence->toRRule10($calendar); } else { $rrule = $this->recurrence->toRRule20($calendar); } if (!empty($rrule)) { $vEvent->setAttribute('RRULE', $rrule); } // Exceptions. An exception with no replacement event is represented // by EXDATE, and those with replacement events are represented by // a new vEvent element. We get all known replacement events first, // then remove the exceptionoriginaldate from the list of the event // exceptions. Any exceptions left should represent exceptions with // no replacement. $exceptions = $this->recurrence->getExceptions(); $kronolith_driver = Kronolith::getDriver(null, $this->calendar); $search = new stdClass(); $search->baseid = $this->uid; $results = $kronolith_driver->search($search); foreach ($results as $days) { foreach ($days as $exceptionEvent) { // Need to change the UID so it links to the original // recurring event, but only if not using $v1. If using $v1, // we add the date to EXDATE and do NOT change the UID. if (!$v1) { $exceptionEvent->uid = $this->uid; } $vEventException = $exceptionEvent->toiCalendar($calendar); // This should never happen, but protect against it anyway. if (count($vEventException) > 2 || count($vEventException) > 1 && !$vEventException[0] instanceof Horde_Icalendar_Vtimezone && !$vEventException[1] instanceof Horde_Icalendar_Vtimezone) { throw new Kronolith_Exception(_("Unable to parse event.")); } $vEventException = array_pop($vEventException); // If $v1, need to add to EXDATE if (!$this->isAllDay()) { $exceptionEvent->setTimezone(true); } if (!$v1) { $vEventException->setAttribute('RECURRENCE-ID', $exceptionEvent->exceptionoriginaldate); } else { $vEvent->setAttribute('EXDATE', array($exceptionEvent->exceptionoriginaldate), array('VALUE' => 'DATE')); } $originaldate = $exceptionEvent->exceptionoriginaldate->format('Ymd'); $key = array_search($originaldate, $exceptions); if ($key !== false) { unset($exceptions[$key]); } $vEvents[] = $vEventException; } } /* The remaining exceptions represent deleted recurrences */ foreach ($exceptions as $exception) { if (!empty($exception)) { // Use multiple EXDATE attributes instead of EXDATE // attributes with multiple values to make Apple iCal // happy. list($year, $month, $mday) = sscanf($exception, '%04d%02d%02d'); if ($this->isAllDay()) { $vEvent->setAttribute('EXDATE', array(new Horde_Date($year, $month, $mday)), array('VALUE' => 'DATE')); } else { // Another Apple iCal/Calendar fix. EXDATE is only // recognized if the full datetime is present and matches // the time part given in DTSTART. $params = array(); if ($this->timezone) { $params['TZID'] = $this->timezone; } $exdate = clone $this->start; $exdate->year = $year; $exdate->month = $month; $exdate->mday = $mday; $vEvent->setAttribute('EXDATE', array($exdate), $params); } } } } array_unshift($vEvents, $vEvent); $this->setTimezone(false); return $vEvents; }
/** * Fetch the free/busy data. * * @params array $params Additional options. * * @return array The free/busy data. */ public function fetch($params = array()) { $this->logger->debug(sprintf("Free/busy data of owner %s requested by user %s (remote: %s).", $this->callee, $this->user, $this->remote)); if (!empty($this->remote)) { /* Try to fetch the data if it is stored on a remote server */ //@todo: How to determine which hook/processor to run? return $this->fetchRemote($params); // if (is_a($result, 'PEAR_Error')) { // $error = array('type' => FREEBUSY_ERROR_UNAUTHORIZED, 'error' => $result); } global $conf; /* Which files will we access? */ if (!empty($conf['fb']['use_acls'])) { $aclcache =& Horde_Kolab_FreeBusy_Cache_DB_acl::singleton('acl', $this->_cache_dir); $files = $aclcache->get($access->owner); if (is_a($files, 'PEAR_Error')) { return $files; } } else { $file_uid = str_replace("", '', str_replace(".", "^", $access->owner)); $files = array(); $this->findAll_readdir($file_uid, $conf['fb']['cache_dir'] . '/' . $file_uid, $files); } $owner = $access->owner; if (ereg('(.*)@(.*)', $owner, $regs)) { $owner = $regs[2] . '/' . $regs[1]; } $user = $access->user; if (ereg('(.*)@(.*)', $user, $regs)) { $user = $regs[2] . '/' . $regs[1]; } $c_file = str_replace("", '', str_replace('.', '^', $user . '/' . $owner)); $c_vcal = new Horde_Kolab_FreeBusy_Cache_File_vcal($this->_cache_dir, $c_file, $extended); /* If the current vCal cache did not expire, we can deliver it */ if (!$this->cache->expired($files)) { return $this->cache->loadVcal(); } // Create the new iCalendar. $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//kolab.org//NONSGML Kolab Server 2//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); // Create new vFreebusy. $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $params = array(); $cn = $access->owner_object->get(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_CN); if (!empty($cn) || is_a($cn, 'PEAR_Error')) { $params['cn'] = $access->owner_object->get(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_CN); } $vFb->setAttribute('ORGANIZER', 'MAILTO:' . $access->owner, $params); $vFb->setAttribute('DTSTAMP', time()); if (isset($_SERVER['SERVER_NAME'])) { $host = $_SERVER['SERVER_NAME']; } else { $host = 'localhost'; } if (isset($_SERVER['REQUEST_URI'])) { $uri = $_SERVER['REQUEST_URI']; } else { $uri = '/'; } $vFb->setAttribute('URL', 'http://' . $host . $uri); $mtimes = array(); foreach ($files as $file) { if ($extended && !empty($conf['fb']['use_acls'])) { $extended_pvc = $this->_allowExtended($file, $access); } else { $extended_pvc = $extended; } $c_pvcal = new Horde_Kolab_FreeBusy_Cache_File_pvcal($this->_cache_dir, $file); $pvCal = $c_pvcal->loadPVcal($extended_pvc); if (is_a($pvCal, 'PEAR_Error')) { Horde::log(sprintf("Ignoring partial free/busy file %s: %s)", $file, $pvCal->getMessage()), 'INFO'); continue; } $pvFb =& $pvCal->findComponent('vfreebusy'); if (!$pvFb) { Horde::log(sprintf("Could not find free/busy info in file %s.)", $file), 'INFO'); continue; } if ($ets = $pvFb->getAttributeDefault('DTEND', false) !== false) { // PENDING(steffen): Make value configurable if ($ets < time()) { Horde::log(sprintf("Free/busy info in file %s is too old.)", $file), 'INFO'); $c_pvcal->purge(); continue; } } $vFb->merge($pvFb); /* Store last modification time */ $mtimes[$file] = array($c_pvcal->getFile(), $c_pvcal->getMtime()); } if (!empty($conf['fb']['remote_servers'])) { $remote_vfb = $this->_fetchRemote($conf['fb']['remote_servers'], $access); if (is_a($remote_vfb, 'PEAR_Error')) { Horde::log(sprintf("Ignoring remote free/busy files: %s)", $remote_vfb->getMessage()), 'INFO'); } else { $vFb->merge($remote_vfb); } } if (!(bool) $vFb->getBusyPeriods()) { /* No busy periods in fb list. We have to add a * dummy one to be standards compliant */ $vFb->setAttribute('COMMENT', 'This is a dummy vfreebusy that indicates an empty calendar'); $vFb->addBusyPeriod('BUSY', 0, 0, null); } $vCal->addComponent($vFb); $c_vcal->storeVcal($vCal, $mtimes); return $vCal; $result = $this->app->getCache->load($access, $extended); // if (is_a($result, 'PEAR_Error')) { // $error = array('type' => FREEBUSY_ERROR_NOTFOUND, 'error' => $result); //$data = array('fb' => $result, 'name' => $access->owner . '.vfb'); //$view = &new Horde_Kolab_FreeBusy_View_vfb($data); }
/** * Export this memo in iCalendar format. * * @param array memo The memo (hash array) to export * @param Horde_Icalendar A Horde_Icalendar object that acts as container. * * @return Horde_Icalendar_Vnote object for this event. */ public function toiCalendar($memo, $calendar) { global $prefs; $vnote = Horde_Icalendar::newComponent('vnote', $calendar); $vnote->setAttribute('UID', $memo['uid']); $vnote->setAttribute('BODY', $memo['body']); $vnote->setAttribute('SUMMARY', $memo['desc']); if (!empty($memo['tags'])) { $vnote->setAttribute('CATEGORIES', implode(', ', $memo['tags'])); } /* Get the note's history. */ $history = $GLOBALS['injector']->getInstance('Horde_History'); $log = $history->getHistory('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid']); if ($log) { foreach ($log as $entry) { switch ($entry['action']) { case 'add': $created = $entry['ts']; break; case 'modify': $modified = $entry['ts']; break; } } } if (!empty($created)) { $vnote->setAttribute('DCREATED', $created); } if (!empty($modified)) { $vnote->setAttribute('LAST-MODIFIED', $modified); } return $vnote; }
private function _getMinimalInvitation() { $start = new Horde_Date('20080926T110000'); $end = new Horde_Date('20080926T120000'); $vCal = new Horde_Icalendar(); $vCal->setAttribute('METHOD', 'REQUEST'); $inv = Horde_Icalendar::newComponent('VEVENT', $vCal); $inv->setAttribute('UID', '1001'); $inv->setAttribute('ORGANIZER', 'mailto:orga@example.org', array('cn' => 'Mr. Orga')); $inv->setAttribute('DTSTART', $start->timestamp()); $inv->setAttribute('DTEND', $end->timestamp()); return $inv; }
/** * Exports this task in iCalendar format. * * @param Horde_Icalendar $calendar A Horde_Icalendar object that acts as * the container. * * @return Horde_Icalendar_Vtodo A vtodo component of this task. */ public function toiCalendar(Horde_Icalendar $calendar) { $vTodo = Horde_Icalendar::newComponent('vtodo', $calendar); $v1 = $calendar->getAttribute('VERSION') == '1.0'; $vTodo->setAttribute('UID', $this->uid); if (!empty($this->assignee)) { $vTodo->setAttribute('ATTENDEE', Nag::getUserEmail($this->assignee), array('ROLE' => 'REQ-PARTICIPANT')); } $vTodo->setAttribute('ORGANIZER', !empty($this->organizer) ? Nag::getUserEmail($this->organizer) : Nag::getUserEmail($this->owner)); if (!empty($this->name)) { $vTodo->setAttribute('SUMMARY', $this->name); } if (!empty($this->desc)) { $vTodo->setAttribute('DESCRIPTION', $this->desc); } if (isset($this->priority)) { $vTodo->setAttribute('PRIORITY', $this->priority); } if (!empty($this->parent_id) && !empty($this->parent)) { $vTodo->setAttribute('RELATED-TO', $this->parent->uid); } if ($this->private) { $vTodo->setAttribute('CLASS', 'PRIVATE'); } if (!empty($this->start)) { $vTodo->setAttribute('DTSTART', $this->start); } if ($this->due) { $vTodo->setAttribute('DUE', $this->due); if ($this->alarm) { if ($v1) { $vTodo->setAttribute('AALARM', $this->due - $this->alarm * 60); } else { $vAlarm = Horde_Icalendar::newComponent('valarm', $vTodo); $vAlarm->setAttribute('ACTION', 'DISPLAY'); $vAlarm->setAttribute('TRIGGER;VALUE=DURATION', '-PT' . $this->alarm . 'M'); $vTodo->addComponent($vAlarm); } } } if ($this->completed) { $vTodo->setAttribute('STATUS', 'COMPLETED'); $vTodo->setAttribute('COMPLETED', $this->completed_date ? $this->completed_date : $_SERVER['REQUEST_TIME']); $vTodo->setAttribute('PERCENT-COMPLETE', '100'); } else { if (!empty($this->estimate)) { $vTodo->setAttribute('PERCENT-COMPLETE', $this->actual / $this->estimate * 100); } if ($v1) { $vTodo->setAttribute('STATUS', 'NEEDS ACTION'); } else { $vTodo->setAttribute('STATUS', 'NEEDS-ACTION'); } } // Recurrence. // We may have to implicitely set DTSTART if not set explicitely, may // some clients choke on missing DTSTART attributes while RRULE exists. if ($this->recurs()) { if ($v1) { $rrule = $this->recurrence->toRRule10($calendar); } else { $rrule = $this->recurrence->toRRule20($calendar); } if (!empty($rrule)) { $vTodo->setAttribute('RRULE', $rrule); } /* The completions represent deleted recurrences */ foreach ($this->recurrence->getCompletions() as $exception) { if (!empty($exception)) { // Use multiple EXDATE attributes instead of EXDATE // attributes with multiple values to make Apple iCal // happy. list($year, $month, $mday) = sscanf($exception, '%04d%02d%02d'); $vTodo->setAttribute('EXDATE', array(new Horde_Date($year, $month, $mday)), array('VALUE' => 'DATE')); } } } if ($this->tags) { $vTodo->setAttribute('CATEGORIES', implode(', ', $this->tags)); } /* Get the task's history. */ $created = $modified = null; try { $log = $GLOBALS['injector']->getInstance('Horde_History')->getHistory('nag:' . $this->tasklist . ':' . $this->uid); foreach ($log as $entry) { switch ($entry['action']) { case 'add': $created = $entry['ts']; break; case 'modify': $modified = $entry['ts']; break; } } } catch (Exception $e) { } if (!empty($created)) { $vTodo->setAttribute($v1 ? 'DCREATED' : 'CREATED', $created); if (empty($modified)) { $modified = $created; } } if (!empty($modified)) { $vTodo->setAttribute('LAST-MODIFIED', $modified); } return $vTodo; }
public function testGetMethodReturnsDefaultMethod() { $inv = Horde_Icalendar::newComponent('VEVENT', false); $vevent = new Horde_Itip_Event_Vevent($inv); $this->assertEquals('REQUEST', $vevent->getMethod()); }
/** * Exports this task in iCalendar format. * * @param Horde_Icalendar $calendar A Horde_Icalendar object that acts as * the container. * * @return Horde_Icalendar_Vtodo A vtodo component of this task. */ public function toiCalendar(Horde_Icalendar $calendar) { $vTodo = Horde_Icalendar::newComponent('vtodo', $calendar); $v1 = $calendar->getAttribute('VERSION') == '1.0'; $vTodo->setAttribute('UID', $this->uid); if (!empty($this->assignee)) { $vTodo->setAttribute('ORGANIZER', $this->assignee); } if (!empty($this->name)) { $vTodo->setAttribute('SUMMARY', $this->name); } if (!empty($this->desc)) { $vTodo->setAttribute('DESCRIPTION', $this->desc); } if (isset($this->priority)) { $vTodo->setAttribute('PRIORITY', $this->priority); } if (!empty($this->parent_id) && !empty($this->parent)) { $vTodo->setAttribute('RELATED-TO', $this->parent->uid); } if ($this->private) { $vTodo->setAttribute('CLASS', 'PRIVATE'); } if (!empty($this->start)) { $vTodo->setAttribute('DTSTART', $this->start); } if ($this->due) { $vTodo->setAttribute('DUE', $this->due); if ($this->alarm) { if ($v1) { $vTodo->setAttribute('AALARM', $this->due - $this->alarm * 60); } else { $vAlarm = Horde_Icalendar::newComponent('valarm', $vTodo); $vAlarm->setAttribute('ACTION', 'DISPLAY'); $vAlarm->setAttribute('TRIGGER;VALUE=DURATION', '-PT' . $this->alarm . 'M'); $vTodo->addComponent($vAlarm); } } } if ($this->completed) { $vTodo->setAttribute('STATUS', 'COMPLETED'); $vTodo->setAttribute('COMPLETED', $this->completed_date ? $this->completed_date : $_SERVER['REQUEST_TIME']); } else { if ($v1) { $vTodo->setAttribute('STATUS', 'NEEDS ACTION'); } else { $vTodo->setAttribute('STATUS', 'NEEDS-ACTION'); } } if ($this->tags) { $vTodo->setAttribute('CATEGORIES', implode(', ', $this->tags)); } /* Get the task's history. */ $created = $modified = null; try { $log = $GLOBALS['injector']->getInstance('Horde_History')->getHistory('nag:' . $this->tasklist . ':' . $this->uid); foreach ($log as $entry) { switch ($entry['action']) { case 'add': $created = $entry['ts']; break; case 'modify': $modified = $entry['ts']; break; } } } catch (Exception $e) { } if (!empty($created)) { $vTodo->setAttribute($v1 ? 'DCREATED' : 'CREATED', $created); if (empty($modified)) { $modified = $created; } } if (!empty($modified)) { $vTodo->setAttribute('LAST-MODIFIED', $modified); } return $vTodo; }
protected function _tovTodo() { $iCal = new Horde_Icalendar(); $iCal->setAttribute('METHOD', $this->_method); $vtodo = Horde_Icalendar::newComponent('vtodo', $iCal); $vtodo->setAttribute('UID', $this->_guid); // For REQUESTS, we MUST have the ORGANIZER and an ATTENDEE. if ($this->_state == self::STATE_ASSIGNERS_COPY || $this->_ownership == self::OWNERSHIP_ASSIGNERS_COPY) { // When sending a REQUEST the lastUser to edit it should be the // ORGANIZER. I can't find any of the other properties that work // consistently. $vtodo->setAttribute('ORGANIZER', 'mailto: ' . $this->_lastUser); $list = new Horde_Mail_Rfc822_List($this->_owner); foreach ($list as $email) { $vtodo->setAttribute('ATTENDEE', $email, array('ROLE' => 'REQ-PARTICIPANT')); } } if ($this->_due) { $vtodo->setAttribute('DUE', $this->_due); } if ($this->_start) { $vtodo->setAttribute('DTSTART', $this->_start); } if ($this->_completed) { $vtodo->setAttribute('COMPLETED', $this->_completed); } if (isset($this->_percentComplete)) { $vtodo->setAttribute('PERCENT-COMPLETE', $this->_percentComplete); } // Summary is stored in the message data. $msg = $this->_options['parent']->getMsgInfo(); if ($msg->subject) { $vtodo->setAttribute('SUMMARY', $msg->subject); } // Figure out the body. if ($this->_bodyPlain) { $vtodo->setAttribute('DESCRIPTION', $this->_bodyPlain); } elseif ($this->_bodyHtml) { $vtodo->setAttribute('DESCRIPTION', Horde_Text_Filter::filter($this->_bodyHtml, 'html2text')); } $iCal->addComponent($vtodo); return array('type' => 'text', 'subtype' => 'calendar', 'name' => $msg->subject ? $msg->subject . '.vtodo' : 'Untitled.vtodo', 'stream' => $iCal->exportvCalendar()); }
private function _getInvitation() { $vCal = new Horde_Icalendar(); $inv = Horde_Icalendar::newComponent('VEVENT', $vCal); $inv->setAttribute('METHOD', 'REQUEST'); $inv->setAttribute('UID', '1'); $inv->setAttribute('SUMMARY', 'Test Invitation'); $inv->setAttribute('DESCRIPTION', 'You are invited'); $inv->setAttribute('LOCATION', 'Somewhere'); $inv->setAttribute('ORGANIZER', '*****@*****.**'); $inv->setAttribute('DTSTART', 1222419600); $inv->setAttribute('DTEND', 1222423200); return $inv; }
/** * 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)); } }
/** * Renders the fb view * * @global Horde_Prefs $prefs * @param Horde_Date $day The day to render * * @return string The html of the rendered fb view. */ public function render(Horde_Date $day = null) { global $prefs; $this->_startHour = floor($prefs->getValue('day_hour_start') / 2); $this->_endHour = floor(($prefs->getValue('day_hour_end') + 1) / 2); $this->_render($day); $vCal = new Horde_Icalendar(); /* Required members */ $required = Horde_Icalendar::newComponent('vfreebusy', $vCal); foreach ($this->_requiredMembers as $member) { $required->merge($member, false); } foreach ($this->_requiredResourceMembers as $member) { $required->merge($member, false); } $required->simplify(); /* Optional members */ $optional = Horde_Icalendar::newComponent('vfreebusy', $vCal); foreach ($this->_optionalMembers as $member) { $optional->merge($member, false); } foreach ($this->_optionalResourceMembers as $member) { $optional->merge($member, false); } $optional->simplify(); /* Optimal time calculation */ $optimal = Horde_Icalendar::newComponent('vfreebusy', $vCal); $optimal->merge($required, false); $optimal->merge($optional); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('title', $this->_title()); $html = $template->fetch(KRONOLITH_TEMPLATES . '/fbview/header.html'); $hours_html = $this->_hours(); // Set C locale to avoid localized decimal separators during CSS width // calculation. $lc = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, 'C'); // Required to attend. if (count($this->_requiredMembers) > 0) { $rows = ''; foreach ($this->_requiredMembers as $member) { $member->simplify(); $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('blocks', $blocks); $template->set('name', htmlspecialchars($member->getName())); $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); } $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('title', _("Required Attendees")); $template->set('rows', $rows); $template->set('span', count($this->_timeBlocks)); $template->set('hours', $hours_html); $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/section.html'); } // Optional to attend. if (count($this->_optionalMembers) > 0) { $rows = ''; foreach ($this->_optionalMembers as $member) { $member->simplify(); $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('blocks', $blocks); $template->set('name', htmlspecialchars($member->getName())); $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); } $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('title', _("Optional Attendees")); $template->set('rows', $rows); $template->set('span', count($this->_timeBlocks)); $template->set('hours', $hours_html); $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/section.html'); } // Resources if (count($this->_requiredResourceMembers) > 0 || count($this->_optionalResourceMembers) > 0) { $template = $GLOBALS['injector']->createInstance('Horde_Template'); $rows = ''; foreach ($this->_requiredResourceMembers as $member) { $member->simplify(); $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('blocks', $blocks); $template->set('name', htmlspecialchars($member->getName())); $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); } foreach ($this->_optionalResourceMembers as $member) { $member->simplify(); $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('blocks', $blocks); $template->set('name', htmlspecialchars($member->getName())); $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); } $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('title', _("Required Resources")); $template->set('rows', $rows); $template->set('span', count($this->_timeBlocks)); $template->set('hours', $hours_html); $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/section.html'); } // Possible meeting times. $optimal->setAttribute('ORGANIZER', _("All Attendees")); $blocks = $this->_getBlocks($optimal, $optimal->getFreePeriods($this->_start->timestamp(), $this->_end->timestamp()), 'meetingblock.html', _("All Attendees")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('name', _("All Attendees")); $template->set('blocks', $blocks); $rows = $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); // Possible meeting times. $required->setAttribute('ORGANIZER', _("Required Attendees")); $blocks = $this->_getBlocks($required, $required->getFreePeriods($this->_start->timestamp(), $this->_end->timestamp()), 'meetingblock.html', _("Required Attendees")); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('name', _("Required Attendees")); $template->set('blocks', $blocks); $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html'); // Reset locale. setlocale(LC_NUMERIC, $lc); $template = $GLOBALS['injector']->createInstance('Horde_Template'); $template->set('rows', $rows); $template->set('title', _("Overview")); $template->set('span', count($this->_timeBlocks)); $template->set('hours', $hours_html); $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/section.html'); $template = $GLOBALS['injector']->createInstance('Horde_Template'); if ($prefs->getValue('show_fb_legend')) { $template->setOption('gettext', true); $template->set('span', count($this->_timeBlocks)); $template->set('legend', $template->fetch(KRONOLITH_TEMPLATES . '/fbview/legend.html')); } else { $template->set('legend', ''); } $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/footer.html'); return $html; }
/** * Generate an iTip from embedded TNEF MEETING data. * * @return array see @self::toArray(). */ protected function _toItip() { $iCal = new Horde_Icalendar(); // METHOD if ($this->_type) { switch ($this->_type) { case Horde_Compress_Tnef::MAPI_MEETING_INITIAL: case Horde_Compress_Tnef::MAPI_MEETING_FULL_UPDATE: $this->_method = 'REQUEST'; break; case Horde_Compress_Tnef::MAPI_MEETING_INFO: $this->_method = 'PUBLISH'; break; } } $iCal->setAttribute('METHOD', $this->_method); // VEVENT $vEvent = Horde_Icalendar::newComponent('vevent', $iCal); if (empty($this->_endUtc)) { return; } $end = clone $this->_endUtc; $end->sec++; if ($this->_allday) { $vEvent->setAttribute('DTSTART', $this->_startUtc, array('VALUE' => 'DATE')); $vEvent->setAttribute('DTEND', $end, array('VALUE' => 'DATE')); } else { $vEvent->setAttribute('DTSTART', $this->_startUtc); $vEvent->setAttribute('DTEND', $end); } $vEvent->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vEvent->setAttribute('UID', $this->_uid); if ($this->_created) { $vEvent->setAttribute('CREATED', $this->_created); } if ($this->_modified) { $vEvent->setAttribute('LAST-MODIFIED', $this->_modified); } // SUMMARY and DESCRIPTION $vEvent->setAttribute('SUMMARY', $this->_summary); if ($this->_description) { $vEvent->setAttribute('DESCRIPTION', trim($this->_description)); } // ORGANIZER if (!$this->_organizer && $this->_lastModifier) { $email = $this->_lastModifier; } else { if ($this->_organizer) { $email = $this->_organizer; } } if (!empty($email)) { $vEvent->setAttribute('ORGANIZER', 'mailto:' . $email); } // ATTENDEE if (empty($this->_requiredAttendees) && $this->_method == 'REPLY') { $this->_requiredAttendees = $this->_from; } if (!empty($this->_requiredAttendees)) { $list = new Horde_Mail_Rfc822_List($this->_requiredAttendees); foreach ($list as $email) { $params = array('ROLE' => 'REQ-PARTICIPANT'); if (!empty($this->_partStat)) { $params['PARTSTAT'] = $this->_partStat; } if ($this->_rsvp) { $params['RSVP'] = 'TRUE'; } $vEvent->setAttribute('ATTENDEE', $email->bare_address, $params); } } // LOCATION if ($this->_location) { $vEvent->setAttribute('LOCATION', $this->_location); } // URL if ($this->_url) { $vEvent->setAttribute('URL', $this->_url); } // RECUR if (!empty($this->_recurrence['recur'])) { $rrule = $this->_recurrence['recur']->toRRule20($iCal); $vEvent->setAttribute('RRULE', $rrule); } $iCal->addComponent($vEvent); $this->_content = $iCal->exportvCalendar(); return array('type' => 'text', 'subtype' => 'calendar', 'name' => $this->_summary, 'stream' => $this->_content); }
public function testTimezone() { $date = new Horde_Date(array('year' => 2010, 'month' => 1, 'mday' => 1, 'hour' => 1, 'min' => 0, 'sec' => 0), 'UTC'); $ical = new Horde_Icalendar(); $event = Horde_Icalendar::newComponent('vevent', $ical); $event->setAttribute('UID', 'uid'); $event->setAttribute('DTSTAMP', $date); $event->setAttribute('DTSTART', $date); $ical->addComponent($event); $this->assertEquals('BEGIN:VCALENDAR VERSION:2.0 PRODID:-//The Horde Project//Horde iCalendar Library//EN BEGIN:VEVENT UID:uid DTSTAMP:20100101T010000Z DTSTART:20100101T010000Z END:VEVENT END:VCALENDAR ', $ical->exportVCalendar()); $ical = new Horde_Icalendar(); $event = Horde_Icalendar::newComponent('vevent', $ical); $event->setAttribute('UID', 'uid'); $event->setAttribute('DTSTAMP', $date); $date->setTimezone('Europe/Berlin'); $event->setAttribute('DTSTART', $date, array('TZID' => 'Europe/Berlin')); $ical->addComponent($event); $this->assertEquals('BEGIN:VCALENDAR VERSION:2.0 PRODID:-//The Horde Project//Horde iCalendar Library//EN BEGIN:VEVENT UID:uid DTSTAMP:20100101T010000Z DTSTART;TZID=Europe/Berlin:20100101T020000 END:VEVENT END:VCALENDAR ', $ical->exportVCalendar()); $ical = new Horde_Icalendar(); $tz = $ical->parsevCalendar('BEGIN:VCALENDAR BEGIN:VTIMEZONE TZID:Europe/Berlin BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 DTSTART:19800406T010000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU;UNTIL=19800406T00000Z TZNAME:CEST END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 DTSTART:19800928T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=9;UNTIL=19950923T23000Z TZNAME:CE-T END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 DTSTART:19810329T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 TZNAME:CEST END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 DTSTART:19961027T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:CE-T END:STANDARD END:VTIMEZONE END:VCALENDAR '); $tz = $ical->getComponent(0); $ical = new Horde_Icalendar(); $ical->addComponent($tz); $event = Horde_Icalendar::newComponent('vevent', $ical); $event->setAttribute('UID', 'uid'); $event->setAttribute('DTSTAMP', $date); $date->setTimezone('Europe/Berlin'); $event->setAttribute('DTSTART', $date, array('TZID' => 'Europe/Berlin')); $ical->addComponent($event); $ical->addComponent($tz); $event = Horde_Icalendar::newComponent('vevent', $ical); $event->setAttribute('UID', 'uid2'); $event->setAttribute('DTSTAMP', $date); $date->setTimezone('Europe/Berlin'); $start = clone $date; $start->mday++; $event->setAttribute('DTSTART', $start, array('TZID' => 'Europe/Berlin')); $ical->addComponent($event); $this->assertEquals('BEGIN:VCALENDAR VERSION:2.0 PRODID:-//The Horde Project//Horde iCalendar Library//EN BEGIN:VTIMEZONE TZID:Europe/Berlin BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 DTSTART:19800406T010000 RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU;UNTIL=19800406T00000Z TZNAME:CEST END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 DTSTART:19800928T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=9;UNTIL=19950923T23000Z TZNAME:CE-T END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 DTSTART:19810329T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 TZNAME:CEST END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 DTSTART:19961027T010000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:CE-T END:STANDARD END:VTIMEZONE BEGIN:VEVENT UID:uid DTSTAMP:20100101T010000Z DTSTART;TZID=Europe/Berlin:20100101T020000 END:VEVENT BEGIN:VEVENT UID:uid2 DTSTAMP:20100101T010000Z DTSTART;TZID=Europe/Berlin:20100102T020000 END:VEVENT END:VCALENDAR ', $ical->exportVCalendar()); }
/** * Generate an iTip from embedded TNEF MEETING data. * */ protected function _checkiTip(&$out) { // Meeting requests will have 'type' set to a non-empty value. if (!empty($this->_iTip[0]) && !empty($this->_iTip[0]['method'])) { $iCal = new Horde_Icalendar(); // METHOD if (!empty($this->_iTip[0]['type'])) { switch ($this->_iTip[0]['type']) { case self::MAPI_MEETING_INITIAL: case self::MAPI_MEETING_FULL_UPDATE: $method = 'REQUEST'; break; case self::MAPI_MEETING_INFO: $method = 'PUBLISH'; break; } } else { $method = $this->_iTip[0]['method']; } $iCal->setAttribute('METHOD', $method); // VEVENT $vEvent = Horde_Icalendar::newComponent('vevent', $iCal); if (empty($this->_iTip[0]['end_utc'])) { return; } $end = clone $this->_iTip[0]['end_utc']; $end->sec++; if ($this->_iTip[0]['allday']) { $vEvent->setAttribute('DTSTART', $this->_iTip[0]['start_utc'], array('VALUE' => 'DATE')); $vEvent->setAttribute('DTEND', $end, array('VALUE' => 'DATE')); } else { $vEvent->setAttribute('DTSTART', $this->_iTip[0]['start_utc']); $vEvent->setAttribute('DTEND', $end); } $vEvent->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vEvent->setAttribute('UID', $this->_iTip[0]['uid']); if (!empty($this->_iTip[0]['created'])) { $vEvent->setAttribute('CREATED', $this->_iTip[0]['created']); } if (!empty($this->_iTip[0]['modified'])) { $vEvent->setAttribute('LAST-MODIFIED', $this->_iTip[0]['modified']); } $vEvent->setAttribute('SUMMARY', $this->_conversation_topic); if (empty($this->_iTip[0]['organizer']) && !empty($this->_lastModifier)) { $email = $this->_lastModifier; } else { if (!empty($this->_iTip[0]['organizer'])) { $email = $this->_iTip[0]['organizer']; } } if (!empty($email)) { $vEvent->setAttribute('ORGANIZER', 'mailto:' . $email); } if (!empty($this->_iTip[0]['url'])) { $vEvent->setAttribute('URL', $this->_iTip[0]['url']); } if (!empty($this->_iTip[0]['recurrence']['recur'])) { $rrule = $this->_iTip[0]['recurrence']['recur']->toRRule20($iCal); $vEvent->setAttribute('RRULE', $rrule); } $iCal->addComponent($vEvent); array_unshift($out, array('type' => 'text', 'subtype' => 'calendar', 'name' => $this->_conversation_topic, 'stream' => $iCal->exportvCalendar())); } }
public function sif2vtodo($sif) { $a = Horde_SyncMl_Device_sync4j::sif2array($sif); $iCal = new Horde_Icalendar(); $iCal->setAttribute('PRODID', '-//The Horde Project//SyncML//EN'); $iCal->setAttribute('METHOD', 'PUBLISH'); $vtodo = Horde_Icalendar::newComponent('vtodo', $iCal); $vtodo->setAttribute('SUMMARY', $a['Subject']); $vtodo->setAttribute('DESCRIPTION', $a['Body']); if ($a['Importance'] == 0) { $vtodo->setAttribute('PRIORITY', 5); } elseif ($a['Importance'] == 2) { $vtodo->setAttribute('PRIORITY', 1); } else { $vtodo->setAttribute('PRIORITY', 3); } if (!empty($a['StartDate']) && $a['StartDate'] != '45001231T230000Z') { $vtodo->setAttribute('DTSTART', $iCal->_parseDateTime($a['StartDate'])); } $dueSet = false; if (!empty($a['DueDate']) && $a['DueDate'] != '45001231T230000Z') { $vtodo->setAttribute('DUE', $iCal->_parseDateTime($a['DueDate'])); $dueSet = true; } if (!empty($a['ReminderSet'])) { if (!$dueSet) { $vtodo->setAttribute('DUE', $iCal->_parseDateTime($a['ReminderTime'])); } $vtodo->setAttribute('AALARM', $iCal->_parseDateTime($a['ReminderTime'])); } if (!empty($a['Complete'])) { $vtodo->setAttribute('STATUS', 'COMPLETED'); } $vtodo->setAttribute('CATEGORIES', isset($a['Categories']) ? $a['Categories'] : ''); if (isset($a['Sensitivity'])) { switch ($a['Sensitivity']) { case 0: /* olNormal */ $vtodo->setAttribute('CLASS', 'PUBLIC'); break; case 1: /* olPersonal */ /* olPersonal */ case 2: /* olPrivate */ $vtodo->setAttribute('CLASS', 'PRIVATE'); break; case 3: /* olConfidential */ $vtodo->setAttribute('CLASS', 'CONFIDENTIAL'); break; } } return $vtodo->exportvCalendar(); }
/** * Retrieve Free/Busy data for the specified resource. * * @param string $resource Fetch the Free/Busy data for this resource * (usually a mail address). * * @return Horde_Icalendar_vfreebusy The Free/Busy data. */ public function get($resource) { /* Return an empty VFB object. */ $vCal = new Horde_Icalendar(); $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $vFb->setAttribute('ORGANIZER', $resource); return $vFb; }
public function testDuration0() { $ical = new Horde_Icalendar(); $vevent = Horde_Icalendar::newComponent('VEVENT', $ical); $vevent->setAttribute('SUMMARY', 'Testevent'); $vevent->setAttribute('UID', 'XXX'); $vevent->setAttribute('DTSTART', array('year' => 2015, 'month' => 7, 'mday' => 1), array('VALUE' => 'DATE')); $vevent->setAttribute('DTSTAMP', array('year' => 2015, 'month' => 7, 'mday' => 1), array('VALUE' => 'DATE')); $vevent->setAttribute('DURATION', 0); $ical->addComponent($vevent); $valarm = Horde_Icalendar::newComponent('VALARM', $vevent); $valarm->setAttribute('TRIGGER', 0, array('VALUE' => 'DURATION', 'RELATED' => 'START')); $valarm->setAttribute('DESCRIPTION', 'Alarm at event-start'); $vevent->addComponent($valarm); $this->assertStringEqualsFile(__DIR__ . '/fixtures/duration0.ics', $ical->exportVCalendar()); }
/** * Copies or moves a list of messages to a tasklist or notepad. * Handles search and Trash mailboxes. * * @param string $list The list in which the task or note will be * created. * @param string $action Either 'copy' or 'move'. * @param IMP_Indices $indices An indices object. * @param string $type The object type to create ('note' or * 'task'). */ protected function _createTasksOrNotes($list, $action, IMP_Indices $indices, $type) { global $injector, $registry, $notification; foreach ($indices as $ob) { foreach ($ob->uids as $uid) { /* Fetch the message contents. */ $imp_contents = $injector->getInstance('IMP_Factory_Contents')->create($ob->mbox->getIndicesOb($uid)); /* Fetch the message headers. */ $imp_headers = $imp_contents->getHeader(); $subject = $imp_headers->getValue('subject'); /* Re-flow the message for prettier formatting. */ $body_part = $imp_contents->getMIMEPart($imp_contents->findBody()); $flowed = new Horde_Text_Flowed($body_part->getContents()); if ($body_part->getContentTypeParameter('delsp') == 'yes') { $flowed->setDelSp(true); } $body = $flowed->toFlowed(false); /* Convert to current charset */ /* TODO: When Horde_Icalendar supports setting of charsets * we need to set it there instead of relying on the fact * that both Nag and IMP use the same charset. */ $body = Horde_String::convertCharset($body, $body_part->getCharset(), 'UTF-8'); /* Create a new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//IMP ' . $registry->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); switch ($type) { case 'task': /* Create a new vTodo object using this message's * contents. */ $vTodo = Horde_Icalendar::newComponent('vtodo', $vCal); $vTodo->setAttribute('SUMMARY', $subject); $vTodo->setAttribute('DESCRIPTION', $body); $vTodo->setAttribute('PRIORITY', '3'); /* Get the list of editable tasklists. */ try { $lists = $registry->call('tasks/listTasklists', array(false, Horde_Perms::EDIT)); } catch (Horde_Exception $e) { $lists = null; $notification->push($e); } /* Attempt to add the new vTodo item to the requested * tasklist. */ try { $res = $registry->call('tasks/import', array($vTodo, 'text/calendar', $list)); } catch (Horde_Exception $e) { $res = null; $notification->push($e); } break; case 'note': /* Create a new vNote object using this message's * contents. */ $vNote = Horde_Icalendar::newComponent('vnote', $vCal); $vNote->setAttribute('BODY', $subject . "\n" . $body); /* Get the list of editable notepads. */ try { $lists = $registry->call('notes/listNotepads', array(false, Horde_Perms::EDIT)); } catch (Horde_Exception $e) { $lists = null; $notification->push($e); } /* Attempt to add the new vNote item to the requested * notepad. */ try { $res = $registry->call('notes/import', array($vNote, 'text/x-vnote', $list)); } catch (Horde_Exception $e) { $res = null; $notification->push($e); } break; } if (!is_null($res)) { if (!$res) { switch ($type) { case 'task': $notification->push(_("An unknown error occured while creating the new task."), 'horde.error'); break; case 'note': $notification->push(_("An unknown error occured while creating the new note."), 'horde.error'); break; } } elseif (!is_null($lists)) { $name = '"' . htmlspecialchars($subject) . '"'; /* Attempt to convert the object name into a * hyperlink. */ try { switch ($type) { case 'task': $link = $registry->link('tasks/show', array('uid' => $res)); break; case 'note': $link = $registry->hasMethod('notes/show') ? $registry->link('notes/show', array('uid' => $res)) : false; break; } if ($link) { $name = sprintf('<a href="%s">%s</a>', Horde::url($link), $name); } $notification->push(sprintf(_("%s was successfully added to \"%s\"."), $name, htmlspecialchars($lists[$list]->get('name'))), 'horde.success', array('content.raw')); } catch (Horde_Exception $e) { } } } } } /* Delete the original messages if this is a "move" operation. */ if ($action == 'move') { $this->delete($indices); } }