Files
server/usr/share/psa-horde/kronolith/lib/Application.php
2026-01-07 20:52:11 +01:00

872 lines
33 KiB
PHP

<?php
/**
* Kronolith application API.
*
* This file defines Horde's core API interface. Other core Horde libraries
* can interact with Kronolith through this API.
*
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @package Kronolith
*/
/* Determine the base directories. */
if (!defined('KRONOLITH_BASE')) {
define('KRONOLITH_BASE', realpath(__DIR__ . '/..'));
}
if (!defined('HORDE_BASE')) {
/* If Horde does not live directly under the app directory, the HORDE_BASE
* constant should be defined in config/horde.local.php. */
if (file_exists(KRONOLITH_BASE . '/config/horde.local.php')) {
include KRONOLITH_BASE . '/config/horde.local.php';
} else {
define('HORDE_BASE', realpath(KRONOLITH_BASE . '/..'));
}
}
/* Load the Horde Framework core (needed to autoload
* Horde_Registry_Application::). */
require_once HORDE_BASE . '/lib/core.php';
use Sabre\CalDAV;
class Kronolith_Application extends Horde_Registry_Application
{
/**
*/
public $features = array(
'alarmHandler' => true,
'dynamicView' => true,
'smartmobileView' => true,
'modseq' => true
);
/**
*/
public $version = 'H5 (4.2.29)';
/**
* Global variables defined:
* - $kronolith_shares: TODO
*/
protected function _init()
{
/* For now, autoloading the Content_* classes depend on there being a
* registry entry for the 'content' application that contains at least
* the fileroot entry. */
$GLOBALS['injector']->getInstance('Horde_Autoloader')
->addClassPathMapper(
new Horde_Autoloader_ClassPathMapper_Prefix('/^Content_/', $GLOBALS['registry']->get('fileroot', 'content') . '/lib/'));
if (!class_exists('Content_Tagger')) {
throw new Horde_Exception(_("The Content_Tagger class could not be found. Make sure the Content application is installed."));
}
$GLOBALS['injector']->bindFactory('Kronolith_Geo', 'Kronolith_Factory_Geo', 'create');
$GLOBALS['injector']->bindFactory('Kronolith_Shares', 'Kronolith_Factory_Shares', 'create');
/* Set the timezone variable, if available. */
$GLOBALS['registry']->setTimeZone();
/* Store the request timestamp if it's not already present. */
if (!isset($_SERVER['REQUEST_TIME'])) {
$_SERVER['REQUEST_TIME'] = time();
}
if (!$GLOBALS['prefs']->getValue('dynamic_view')) {
$this->features['dynamicView'] = false;
}
if ($GLOBALS['registry']->getView() != Horde_Registry::VIEW_DYNAMIC ||
!$GLOBALS['prefs']->getValue('dynamic_view') ||
empty($this->initParams['nodynamicinit'])) {
Kronolith::initialize();
}
}
/**
*/
public function perms()
{
return array(
'max_events' => array(
'title' => _("Maximum Number of Events"),
'type' => 'int'
),
'resource_management' => array(
'title' => _("Resource Management"),
'type' => 'boolean')
);
}
/**
*/
public function menu($menu)
{
global $browser, $conf, $notification, $page_output, $registry, $session;
/* Check here for guest calendars so that we don't get multiple
* messages after redirects, etc. */
if (!$registry->getAuth() && !count(Kronolith::listCalendars())) {
$notification->push(_("No calendars are available to guests."));
}
if ($browser->hasFeature('dom')) {
Horde_Core_Ui_JsCalendar::init(array(
'click_month' => true,
'click_week' => true,
'click_year' => true,
'full_weekdays' => true
));
$page_output->addScriptFile('goto.js');
$page_output->addInlineJsVars(array(
'KronolithGoto.dayurl' => strval(Horde::url('day.php')),
'KronolithGoto.monthurl' => strval(Horde::url('month.php')),
'KronolithGoto.weekurl' => strval(Horde::url('week.php')),
'KronolithGoto.yearurl' => strval(Horde::url('year.php'))
));
$menu->add(new Horde_Url(''), _("_Goto"), 'kronolith-icon-goto', null, '', null, 'kgotomenu');
}
$menu->add(Horde::url('search.php'), _("_Search"), 'kronolith-icon-search');
/* Import/Export. */
if ($conf['menu']['import_export'] &&
!Kronolith::showAjaxView()) {
$menu->add(Horde::url('data.php'), _("_Import/Export"), 'horde-data');
}
if (strlen($session->get('kronolith', 'display_cal'))) {
$menu->add(Horde::selfUrl(true)->add('display_cal', ''),
$registry->getAuth()
? _("Return to my calendars")
: _("Return to calendars"),
'kronolith-icon-back',
null, null, null, '__noselection');
}
}
/**
* Adds additional items to the sidebar.
*
* This is for the traditional view. For the dynamic view, see
* Kronolith_View_Sidebar.
*
* @param Horde_View_Sidebar $sidebar The sidebar object.
*/
public function sidebar($sidebar)
{
$perms = $GLOBALS['injector']->getInstance('Horde_Core_Perms');
if (Kronolith::getDefaultCalendar(Horde_Perms::EDIT) &&
($perms->hasAppPermission('max_events') === true ||
$perms->hasAppPermission('max_events') > Kronolith::countEvents())) {
$sidebar->addNewButton(_("_New Event"), Horde::url('new.php')->add('url', Horde::signUrl(Horde::selfUrl(true, false, true))));
}
if (strlen($GLOBALS['session']->get('kronolith', 'display_cal'))) {
$calendars = Kronolith::displayedCalendars();
$sidebar->containers['calendars'] = array(
'header' => array(
'id' => 'kronolith-toggle-calendars',
'label' => ngettext("Showing calendar:", "Showing calendars:", count($calendars)),
'collapsed' => false,
),
);
foreach ($calendars as $calendar) {
$row = array(
'label' => $calendar->name(),
'color' => $calendar->background(),
'type' => 'checkbox',
);
$sidebar->addRow($row, 'calendars');
}
return;
}
$user = $GLOBALS['registry']->getAuth();
$url = Horde::selfUrl();
$edit = Horde::url('calendars/edit.php');
$sidebar->containers['my'] = array(
'header' => array(
'id' => 'kronolith-toggle-my',
'label' => _("My Calendars"),
'collapsed' => false,
),
);
if (!$GLOBALS['prefs']->isLocked('default_share')) {
$sidebar->containers['my']['header']['add'] = array(
'url' => Horde::url('calendars/create.php'),
'label' => _("Create a new Local Calendar"),
);
}
if ($GLOBALS['registry']->isAdmin()) {
$sidebar->containers['system'] = array(
'header' => array(
'id' => 'kronolith-toggle-system',
'label' => _("System Calendars"),
'collapsed' => true,
),
);
$sidebar->containers['system']['header']['add'] = array(
'url' => Horde::url('calendars/create.php')->add('system', 1),
'label' => _("Create a new System Calendar"),
);
}
$sidebar->containers['shared'] = array(
'header' => array(
'id' => 'kronolith-toggle-shared',
'label' => _("Shared Calendars"),
'collapsed' => true,
),
);
foreach (Kronolith::listInternalCalendars() as $id => $calendar) {
$row = array(
'selected' => in_array($id, $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS)),
'url' => $url->copy()->add('toggle_calendar', $id),
'label' => Kronolith::getLabel($calendar),
'color' => Kronolith::backgroundColor($calendar),
'edit' => $edit->add('c', $calendar->getName()),
'type' => 'checkbox',
);
if ($calendar->get('owner') && $calendar->get('owner') == $user) {
$sidebar->addRow($row, 'my');
} else {
$sidebar->addRow($row, 'shared');
}
}
if ($GLOBALS['registry']->isAdmin()) {
foreach ($GLOBALS['injector']->getInstance('Kronolith_Shares')->listSystemShares() as $id => $calendar) {
$row = array(
'selected' => in_array($id, $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS)),
'url' => $url->copy()->add('toggle_calendar', $id),
'label' => $calendar->get('name'),
'color' => Kronolith::backgroundColor($calendar),
'edit' => $edit->add('c', $calendar->getName()),
'type' => 'checkbox',
);
$sidebar->addRow($row, 'system');
}
}
if (!empty($GLOBALS['conf']['resource']['driver']) &&
($GLOBALS['registry']->isAdmin() || $GLOBALS['injector']->getInstance('Horde_Core_Perms')->hasAppPermission('resource_management'))) {
$sidebar->containers['groups'] = array(
'header' => array(
'id' => 'kronolith-toggle-groups',
'label' => _("Resource Groups"),
'collapsed' => true,
'add' => array(
'url' => Horde::url('resources/groups/create.php'),
'label' => _("Create a new Resource Group"),
),
),
);
$editGroups = Horde::url('resources/groups/edit.php');
$sidebar->containers['resources'] = array(
'header' => array(
'id' => 'kronolith-toggle-resources',
'label' => _("Resources"),
'collapsed' => true,
'add' => array(
'url' => Horde::url('resources/create.php'),
'label' => _("Create a new Resource"),
),
),
);
$edit = Horde::url('resources/edit.php');
foreach (Kronolith::getDriver('Resource')->listResources() as $resource) {
if ($resource->get('type') == Kronolith_Resource::TYPE_GROUP) {
$row = array(
'label' => $resource->get('name'),
'color' => '#dddddd',
'edit' => $editGroups->add('c', $resource->getId()),
'type' => 'radiobox',
);
$sidebar->addRow($row, 'groups');
} else {
$calendar = new Kronolith_Calendar_Resource(array(
'resource' => $resource
));
$row = array(
'selected' => in_array($resource->get('calendar'), $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_RESOURCE_CALENDARS)),
'url' => $url->copy()->add('toggle_calendar', 'resource_' . $resource->get('calendar')),
'label' => $calendar->name(),
'color' => $calendar->background(),
'edit' => $edit->add('c', $resource->getId()),
'type' => 'checkbox',
);
$sidebar->addRow($row, 'resources');
}
}
}
foreach ($GLOBALS['calendar_manager']->get(Kronolith::ALL_EXTERNAL_CALENDARS) as $id => $calendar) {
if (!$calendar->display()) {
continue;
}
$app = $GLOBALS['registry']->get(
'name',
$GLOBALS['registry']->hasInterface($calendar->api()));
if (!strlen($app)) {
$app = _("Other events");
}
$container = 'external_' . $app;
if (!isset($sidebar->containers[$container])) {
$sidebar->containers[$container] = array(
'header' => array(
'id' => 'kronolith-toggle-external-' . $calendar->api(),
'label' => $app,
'collapsed' => true,
),
);
}
$row = array(
'selected' => in_array($id, $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_EXTERNAL_CALENDARS)),
'url' => $url->copy()->add('toggle_calendar', 'external_' . $id),
'label' => $calendar->name(),
'color' => $calendar->background(),
'type' => 'checkbox',
);
$sidebar->addRow($row, $container);
}
$sidebar->containers['remote'] = array(
'header' => array(
'id' => 'kronolith-toggle-remote',
'label' => _("Remote Calendars"),
'collapsed' => true,
'add' => array(
'url' => Horde::url('calendars/remote_subscribe.php'),
'label' => _("Subscribe to a Remote Calendar"),
),
),
);
$edit = Horde::url('calendars/remote_edit.php');
foreach ($GLOBALS['calendar_manager']->get(Kronolith::ALL_REMOTE_CALENDARS) as $calendar) {
$row = array(
'selected' => in_array($calendar->url(), $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_REMOTE_CALENDARS)),
'url' => $url->copy()->add('toggle_calendar', 'remote_' . $calendar->url()),
'label' => $calendar->name(),
'color' => $calendar->background(),
'edit' => $edit->add('url', $calendar->url()),
'type' => 'checkbox',
);
$sidebar->addRow($row, 'remote');
}
if (!empty($GLOBALS['conf']['holidays']['enable'])) {
$sidebar->containers['holidays'] = array(
'header' => array(
'id' => 'kronolith-toggle-holidays',
'label' => _("Holidays"),
'collapsed' => true,
),
);
foreach ($GLOBALS['calendar_manager']->get(Kronolith::ALL_HOLIDAYS) as $id => $calendar) {
$row = array(
'selected' => in_array($id, $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_HOLIDAYS)),
'url' => $url->copy()->add('toggle_calendar', 'holiday_' . $id),
'label' => $calendar->name(),
'color' => $calendar->background(),
'type' => 'checkbox',
);
$sidebar->addRow($row, 'holidays');
}
}
}
/**
*/
public function hasPermission($permission, $allowed, $opts = array())
{
if (is_array($allowed)) {
switch ($permission) {
case 'max_events':
$allowed = max($allowed);
break;
}
}
return $allowed;
}
/**
*/
public function removeUserData($user)
{
$error = false;
// Remove all events owned by the user in all calendars.
try {
Kronolith::removeUserEvents($user);
} catch (Exception $e) {
Horde::log($e, 'NOTICE');
$error = true;
}
// Get the shares owned by the user being deleted.
try {
$kronolith_shares = $GLOBALS['injector']->getInstance('Kronolith_Shares');
$shares = $kronolith_shares->listShares(
$user,
array('attributes' => $user)
);
foreach ($shares as $share) {
$kronolith_shares->removeShare($share);
}
} catch (Exception $e) {
Horde::log($e, 'NOTICE');
$error = true;
}
/* Get a list of all shares this user has perms to and remove the
* perms */
try {
$shares = $kronolith_shares->listShares($user);
foreach ($shares as $share) {
$share->removeUser($user);
}
} catch (Horde_Share_Exception $e) {
Horde::log($e, 'NOTICE');
$error = true;
}
if ($error) {
throw new Kronolith_Exception(sprintf(_("There was an error removing calendars for %s. Details have been logged."), $user));
}
}
/* Topbar method. */
/**
*/
public function topbarCreate(Horde_Tree_Renderer_Base $tree, $parent = null,
array $params = array())
{
switch ($params['id']) {
case 'menu':
$menus = array(
array('new', _("New Event"), 'new.png', Horde::url('new.php')),
array('day', _("Day"), 'dayview.png', Horde::url('day.php')),
array('work', _("Work Week"), 'workweekview.png', Horde::url('workweek.php')),
array('week', _("Week"), 'weekview.png', Horde::url('week.php')),
array('month', _("Month"), 'monthview.png', Horde::url('month.php')),
array('year', _("Year"), 'yearview.png', Horde::url('year.php'))
);
// Dynamic view has no dedicated search page.
if (!Kronolith::showAjaxView()) {
$menus[] = array('search', _("Search"), 'search.png', Horde::url('search.php'));
}
foreach ($menus as $menu) {
$tree->addNode(array(
'id' => $parent . $menu[0],
'parent' => $parent,
'label' => $menu[1],
'expanded' => false,
'params' => array(
'icon' => Horde_Themes::img($menu[2]),
'url' => $menu[3]
)
));
}
break;
}
}
/* Alarm method. */
/**
*/
public function listAlarms($time, $user = null)
{
$current_user = $GLOBALS['registry']->getAuth();
if ((empty($user) || $user != $current_user) && !$GLOBALS['registry']->isAdmin()) {
throw new Horde_Exception_PermissionDenied();
}
$group = $GLOBALS['injector']->getInstance('Horde_Group');
$kronolith_shares = $GLOBALS['injector']->getInstance('Kronolith_Shares');
$alarm_list = array();
$time = new Horde_Date($time);
$calendars = is_null($user)
? array_keys($kronolith_shares->listAllShares())
: $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS);
$alarms = Kronolith::listAlarms($time, $calendars, true);
foreach ($alarms as $calendar => $cal_alarms) {
if (!$cal_alarms) {
continue;
}
try {
$share = $kronolith_shares->getShare($calendar);
} catch (Exception $e) {
continue;
}
if (empty($user)) {
$users = $share->listUsers(Horde_Perms::READ);
$groups = $share->listGroups(Horde_Perms::READ);
foreach ($groups as $gid) {
try {
$users = array_merge($users, $group->listUsers($gid));
} catch (Horde_Group_Exception $e) {}
}
$users = array_unique($users);
} else {
$users = array($user);
}
$owner = $share->get('owner');
foreach ($cal_alarms as $event) {
foreach ($users as $alarm_user) {
if ($alarm_user == $current_user) {
$prefs = $GLOBALS['prefs'];
} else {
$prefs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Prefs')->create('kronolith', array(
'cache' => false,
'user' => $alarm_user
));
}
// Don't show alarms for private events if not the owner.
if ($event->isPrivate($alarm_user)) {
continue;
}
$shown_calendars = unserialize($prefs->getValue('display_cals'));
$reminder = $prefs->getValue('event_reminder');
if (($reminder == 'owner' && $alarm_user == $owner) ||
($reminder == 'show' && in_array($calendar, $shown_calendars)) ||
$reminder == 'read') {
$GLOBALS['registry']->setLanguageEnvironment($prefs->getValue('language'));
$alarm = $event->toAlarm($time, $alarm_user, $prefs);
if ($alarm) {
$alarm_list[] = $alarm;
}
}
}
}
}
return $alarm_list;
}
/* Download data. */
/**
* @throws Kronolith_Exception
*/
public function download(Horde_Variables $vars)
{
global $display_calendars, $injector;
switch ($vars->actionID) {
case 'export':
if ($vars->all_events) {
$end = $start = null;
} else {
$start = new Horde_Date(
$vars->start_year,
$vars->start_month,
$vars->start_day
);
$end = new Horde_Date(
$vars->end_year,
$vars->end_month,
$vars->end_day
);
}
$calendars = $vars->get('exportCal', $display_calendars);
if (!is_array($calendars)) {
$calendars = array($calendars);
}
$events = array();
foreach ($calendars as $calendar) {
list($type, $cal) = explode('_', $calendar, 2);
$kronolith_driver = Kronolith::getDriver($type, $cal);
$calendarObject = Kronolith::getCalendar($kronolith_driver);
if (!$calendarObject ||
!$calendarObject->hasPermission(Horde_Perms::READ)) {
throw new Horde_Exception_PermissionDenied();
}
$events[$calendar] = $kronolith_driver->listEvents(
$start,
$end,
array(
'cover_dates' => false,
'hide_exceptions' => ($vars->exportID == Horde_Data::EXPORT_ICALENDAR)
)
);
}
switch ($vars->exportID) {
case Horde_Data::EXPORT_CSV:
$data = array();
foreach ($events as $calevents) {
foreach ($calevents as $dayevents) {
foreach ($dayevents as $event) {
$row = array(
'alarm' => $event->alarm,
'description' => $event->description,
'end_date' => $event->end->format('Y-m-d'),
'end_time' => $event->end->format('H:i:s'),
'location' => $event->location,
'private' => intval($event->private),
'recur_type' => null,
'recur_end_date' => null,
'recur_interval' => null,
'recur_data' => null,
'start_date' => $event->start->format('Y-m-d'),
'start_time' => $event->start->format('H:i:s'),
'tags' => implode(', ', $event->tags),
'title' => $event->getTitle()
);
if ($event->recurs()) {
$row['recur_type'] = $event->recurrence->getRecurType();
if ($event->recurrence->hasRecurEnd()) {
$row['recur_end_date'] = $event->recurrence->recurEnd->format('Y-m-d');
}
$row['recur_interval'] = $event->recurrence->getRecurInterval();
$row['recur_data'] = $event->recurrence->recurData;
}
$data[] = $row;
}
}
}
$injector->getInstance('Horde_Core_Factory_Data')
->create('Csv', array('cleanup' => array($this, 'cleanupData')))
->exportFile(_("events.csv"), $data, true);
exit;
case Horde_Data::EXPORT_ICALENDAR:
$calNames = array();
$iCal = new Horde_Icalendar();
foreach ($events as $calevents) {
foreach ($calevents as $dayevents) {
foreach ($dayevents as $event) {
$calNames[Kronolith::getCalendar($event->getDriver())->name()] = true;
$iCal->addComponent($event->toiCalendar($iCal));
}
}
}
$iCal->setAttribute('X-WR-CALNAME', implode(', ', array_keys($calNames)));
return array(
'data' => $iCal->exportvCalendar(),
'name' => _("events.ics"),
'type' => 'text/calendar'
);
}
}
}
/**
*/
public function cleanupData()
{
$GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
/* DAV methods. */
/**
*/
public function davGetCollections($user)
{
global $calendar_manager, $injector, $registry;
$hordeUser = $registry->convertUsername($user, true);
$shares = $injector->getInstance('Kronolith_Shares')
->listShares($hordeUser);
$dav = $injector->getInstance('Horde_Dav_Storage');
$calendars = array();
foreach ($shares as $id => $share) {
if ($user == '-system-' && $share->get('owner')) {
continue;
}
if (!$calendar = $calendar_manager->getEntry(Kronolith::ALL_CALENDARS, $id)) {
Horde::log(sprintf('Unable to find share id: %s', $id));
continue;
}
$calendar = $calendar->toHash();
try {
$id = $dav->getExternalCollectionId($id, 'calendar');
} catch (Horde_Dav_Exception $e) {
}
$calendars[] = array(
'id' => $id,
'uri' => $id,
'{' . CalDAV\Plugin::NS_CALENDARSERVER . '}shared-url' =>
$calendar['caldav'],
'principaluri' => 'principals/' . $user,
'{http://sabredav.org/ns}owner-principal' =>
'principals/'
. ($share->get('owner')
? $registry->convertUsername($share->get('owner'), false)
: '-system-'
),
'{DAV:}displayname' => Kronolith::getLabel($share),
'{' . CalDAV\Plugin::NS_CALDAV . '}calendar-description' =>
$share->get('desc'),
'{http://apple.com/ns/ical/}calendar-color' =>
$share->get('color') . 'ff',
'{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Property\SupportedCalendarComponentSet(array('VEVENT')),
'{http://sabredav.org/ns}read-only' => !$share->hasPermission($hordeUser, Horde_Perms::EDIT),
);
}
return $calendars;
}
/**
*/
public function davGetObjects($collection)
{
$dav = $GLOBALS['injector']
->getInstance('Horde_Dav_Storage');
$internal = $dav->getInternalCollectionId($collection, 'calendar') ?: $collection;
if (!Kronolith::hasPermission($internal, Horde_Perms::SHOW)) {
throw new Kronolith_Exception(_("Calendar does not exist or no permission to edit"));
}
$kronolith_driver = Kronolith::getDriver(null, $internal);
$allEvents = $kronolith_driver->listEvents(
null,
null,
array('cover_dates' => false, 'hide_exceptions' => true)
);
$events = array();
foreach ($allEvents as $dayevents) {
foreach ($dayevents as $event) {
$id = $event->id;
$event->loadHistory();
$modified = $event->modified ?: $event->created;
try {
$id = $dav->getExternalObjectId($id, $internal) ?: $id . '.ics';
} catch (Horde_Dav_Exception $e) {
}
$events[] = array(
'id' => $id,
'uri' => $id,
'lastmodified' => $modified,
'etag' => '"' . md5($event->id . '|' . $modified) . '"',
'calendarid' => $collection,
);
}
}
return $events;
}
/**
*/
public function davGetObject($collection, $object)
{
$dav = $GLOBALS['injector']
->getInstance('Horde_Dav_Storage');
$internal = $dav->getInternalCollectionId($collection, 'calendar') ?: $collection;
if (!Kronolith::hasPermission($internal, Horde_Perms::SHOW)) {
throw new Kronolith_Exception(_("Calendar does not exist or no permission to edit"));
}
$kronolith_driver = Kronolith::getDriver(null, $internal);
try {
$object = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\.ics$/', '', $object);
} catch (Horde_Dav_Exception $e) {
}
$event = $kronolith_driver->getEvent($object);
$id = $event->id;
try {
$id = $dav->getExternalObjectId($id, $internal) ?: $id . '.ics';
} catch (Horde_Dav_Exception $e) {
}
$event->loadHistory();
$modified = $event->modified ?: $event->created;
$share = $GLOBALS['injector']
->getInstance('Kronolith_Shares')
->getShare($event->calendar);
$ical = new Horde_Icalendar('2.0');
$ical->setAttribute('X-WR-CALNAME', $share->get('name'));
$ical->addComponent($event->toiCalendar($ical));
$data = $ical->exportvCalendar();
return array(
'id' => $id,
'calendardata' => $data,
'uri' => $id,
'lastmodified' => $modified,
'etag' => '"' . md5($event->id . '|' . $modified) . '"',
'calendarid' => $collection,
'size' => strlen($data),
);
}
/**
*/
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."));
}
$importer = new Kronolith_Icalendar_Handler_Dav(
$ical, Kronolith::getDriver(null, $internal), array('object' => $object)
);
$importer->process();
}
/**
*/
public function davDeleteObject($collection, $object)
{
$dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage');
$internal = $dav->getInternalCollectionId($collection, 'calendar') ?: $collection;
if (!Kronolith::hasPermission($internal, Horde_Perms::DELETE)) {
throw new Kronolith_Exception(_("Calendar does not exist or no permission to delete"));
}
try {
$object = $dav->getInternalObjectId($object, $internal)
?: preg_replace('/\.ics$/', '', $object);
} catch (Horde_Dav_Exception $e) {
}
$kronolith_driver = Kronolith::getDriver(null, $internal);
$event = $kronolith_driver->getEvent($object);
$kronolith_driver->deleteEvent($object);
try {
$dav->deleteExternalObjectId($object, $internal);
} catch (Horde_Dav_Exception $e) {
}
// 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_CANCEL
);
}
}