mirror of https://github.com/nextcloud/calendar
save current work state
This commit is contained in:
parent
5d5d9adb48
commit
a604975b4a
|
@ -246,7 +246,7 @@ abstract class Document extends Component {
|
|||
|
||||
$valueParam = strtoupper($valueParam);
|
||||
if (isset(static::$valueMap[$valueParam])) {
|
||||
return static::$valueMap[$valueParam];
|
||||
return 'OCA\\Calendar\\' . static::$valueMap[$valueParam];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,4 +19,17 @@ $app->registerCron();
|
|||
$app->registerHooks();
|
||||
$app->registerProviders();
|
||||
|
||||
Sabre\VObject\Document::$propertyMap['DateTime'] = '\OCA\Calendar\CustomSabre\Property\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$valueMap['DATE-TIME'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$valueMap['DATE'] = 'SabreProperty\DateTime';
|
||||
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['COMPLETED'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['DTEND'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['DUE'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['DTSTART'] = 'SabreProperty\DateTime';
|
||||
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['RECURRENCE-ID'] = 'SabreProperty\DateTime';
|
||||
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['CREATED'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['DTSTAMP'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['LAST-MODIFIED'] = 'SabreProperty\DateTime';
|
||||
\OCA\Calendar\Sabre\VObject\Component\VCalendar::$propertyMap['ACKNOWLEDGED'] = 'SabreProperty\DateTime';
|
|
@ -51,8 +51,12 @@
|
|||
\OC::$CLASSPATH['OCA\Calendar\Db\ObjectType'] = 'calendar/db/objecttype.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Db\Permissions'] = 'calendar/db/permissions.php';
|
||||
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\JSONResponse'] = 'calendar/http/jsonresponse.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\IResponse'] = 'calendar/http/iresponse.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\IReader'] = 'calendar/http/ireader.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\ISerializer'] = 'calendar/http/iserializer.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\Manager'] = 'calendar/http/manager.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\Reader'] = 'calendar/http/reader.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\Serializer'] = 'calendar/http/serializer.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\Response'] = 'calendar/http/response.php';
|
||||
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\ICS\ICS'] = 'calendar/http/ics/ics.php';
|
||||
\OC::$CLASSPATH['OCA\Calendar\Http\ICS\ICSCollection'] = 'calendar/http/ics/icscollection.php';
|
||||
|
|
|
@ -28,6 +28,11 @@ $this->create('calendar.calendars.forceUpdate', '/v1/calendars-forceUpdate')->ac
|
|||
$app->dispatch('CalendarController', 'forceUpdate');
|
||||
});
|
||||
|
||||
$this->create('calendar.calendars.indexInPeriod', '/v1/calendars/{calendarId}/objects/inPeriod/{start}/{end}')->action(function($params){
|
||||
$app = new \OCA\Calendar\App($params);
|
||||
$app->dispatch('ObjectController', 'indexInPeriod');
|
||||
});
|
||||
|
||||
//set up resources
|
||||
$routes = array(
|
||||
'resources' => array(
|
||||
|
|
|
@ -20,14 +20,15 @@ define('OCA\Calendar\Backend\CREATE_CALENDAR', 1);
|
|||
define('OCA\Calendar\Backend\UPDATE_CALENDAR', 2);
|
||||
define('OCA\Calendar\Backend\DELETE_CALENDAR', 4);
|
||||
define('OCA\Calendar\Backend\MERGE_CALENDAR', 8);
|
||||
define('OCA\Calendar\Backend\CREATE_OBJECT', 16);
|
||||
define('OCA\Calendar\Backend\UPDATE_OBJECT', 32);
|
||||
define('OCA\Calendar\Backend\DELETE_OBJECT', 64);
|
||||
define('OCA\Calendar\Backend\FIND_IN_PERIOD', 128);
|
||||
define('OCA\Calendar\Backend\FIND_OBJECTS_BY_TYPE', 256);
|
||||
define('OCA\Calendar\Backend\FIND_IN_PERIOD_BY_TYPE', 521);
|
||||
define('OCA\Calendar\Backend\SEARCH_BY_PROPERTIES', 1024);
|
||||
define('OCA\Calendar\Backend\PROVIDES_CRON_SCRIPT', 2048);
|
||||
define('OCA\Calendar\Backend\MOVE_CALENDAR', 16);
|
||||
define('OCA\Calendar\Backend\CREATE_OBJECT', 32);
|
||||
define('OCA\Calendar\Backend\UPDATE_OBJECT', 64);
|
||||
define('OCA\Calendar\Backend\DELETE_OBJECT', 128);
|
||||
define('OCA\Calendar\Backend\FIND_IN_PERIOD', 256);
|
||||
define('OCA\Calendar\Backend\FIND_OBJECTS_BY_TYPE', 512);
|
||||
define('OCA\Calendar\Backend\FIND_IN_PERIOD_BY_TYPE', 1024);
|
||||
define('OCA\Calendar\Backend\SEARCH_BY_PROPERTIES', 2048);
|
||||
define('OCA\Calendar\Backend\PROVIDES_CRON_SCRIPT', 4096);
|
||||
|
||||
abstract class Backend implements IBackend {
|
||||
|
||||
|
@ -52,6 +53,7 @@ abstract class Backend implements IBackend {
|
|||
UPDATE_CALENDAR => 'updateCalendar',
|
||||
DELETE_CALENDAR => 'deleteCalendar',
|
||||
MERGE_CALENDAR => 'mergeCalendar',
|
||||
MOVE_CALENDAR => 'moveCalendar',
|
||||
CREATE_OBJECT => 'createObject',
|
||||
UPDATE_OBJECT => 'updateObject',
|
||||
DELETE_OBJECT => 'deleteObject',
|
||||
|
|
|
@ -1,166 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* Copyright (c) 2014 Thomas Tanghus <thomas@tanghus.net>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Backend;
|
||||
|
||||
use \OCA\Calendar\AppFramework\Core\API;
|
||||
use \OCA\Calendar\AppFramework\Db\Mapper;
|
||||
use \OCA\Calendar\AppFramework\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
|
||||
use \OCA\Calendar\Db\Calendar;
|
||||
use \OCA\Calendar\Db\CalendarCollection;
|
||||
use \OCA\Calendar\Db\Object;
|
||||
use \OCA\Calendar\Db\ObjectCollection;
|
||||
use \OCA\Calendar\Db\TimeZone;
|
||||
use \OCA\Calendar\Db\TimeZoneCollection;
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
class Birthday extends Backend {
|
||||
|
||||
public $calendarURI;
|
||||
|
||||
public function __construct($api, $parameters){
|
||||
parent::__construct($api, 'Birthday');
|
||||
|
||||
$this->calendarURI = 'birthday';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns whether or not a backend can be enabled
|
||||
* @returns boolean
|
||||
*
|
||||
* This method returns a boolean.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function canBeEnabled() {
|
||||
return true;//\OCP\App::isEnabled('contacts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns whether or not calendar objects should be cached
|
||||
* @param string $calendarURI
|
||||
* @param string $userId
|
||||
* @returns boolean
|
||||
*
|
||||
* This method returns a boolen.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function cacheObjects($uri, $userId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns information about calendar $calendarURI of the user $userId
|
||||
* @param string $calendarURI
|
||||
* @param string $userId
|
||||
* @returns array with \OCA\Calendar\Db\Calendar object
|
||||
* @throws DoesNotExistException if uri does not exist
|
||||
*
|
||||
* This method returns an \OCA\Calendar\Db\Calendar object.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function findCalendar($calendarURI, $userId) {
|
||||
if($calendarURI !== $this->calendarURI) {
|
||||
$msg = 'Backend\Birthday::findCalendar(): ';
|
||||
$msg .= '"' . $calendarURI . '" doesn\'t exist';
|
||||
throw new DoesNotExistException($msg);
|
||||
}
|
||||
|
||||
$calendar = new Calendar();
|
||||
$calendar->setUserId($userId);
|
||||
$calendar->setOwnerId($userId);
|
||||
$calendar->setBackend($this->backend);
|
||||
$calendar->setUri($this->calendarURI);
|
||||
$calendar->setDisplayname('Birthday'); //TODO - use translation
|
||||
$calendar->setComponents(ObjectType::EVENT);
|
||||
$calendar->setCtag(1); //sum of all addressbook ctags
|
||||
$calendar->setTimezone(new TimeZone('UTC'));
|
||||
$calendar->setCruds(Permissions::READ + Permissions::SHARE);
|
||||
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns all calendars of the user $userId
|
||||
* @param string $userId
|
||||
* @returns \OCA\Calendar\Db\CalendarCollection
|
||||
* @throws DoesNotExistException if uri does not exist
|
||||
*
|
||||
* This method returns an \OCA\Calendar\Db\CalendarCollection object.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function findCalendars($userId, $limit=null, $offset=null) {
|
||||
$collection = new CalendarCollection($this->findCalendar($this->calendarURI, $userId));
|
||||
$collection = $collection->subset($limit, $offset);
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns number of calendar
|
||||
* @param string $userid
|
||||
* @returns integer
|
||||
*
|
||||
* This method returns an integer
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function countCalendars($userId) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns whether or not a calendar exists
|
||||
* @param string $calendarURI
|
||||
* @param string $userid
|
||||
* @returns boolean
|
||||
*
|
||||
* This method returns a boolean
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function doesCalendarExist($calendarURI, $userId) {
|
||||
if($calendarURI === $this->calendarURI) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns information about the object (event/journal/todo) with the uid $objectURI in the calendar $calendarURI of the user $userId
|
||||
* @param string $calendarURI
|
||||
* @param string $objectURI
|
||||
* @param string $userid
|
||||
* @returns \OCA\Calendar\Db\Object object
|
||||
* @throws DoesNotExistException if calendar does not exist
|
||||
* @throws DoesNotExistException if object does not exist
|
||||
*
|
||||
* This method returns an \OCA\Calendar\Db\Object object.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function findObject(Calendar &$calendar, $objectURI) {
|
||||
//TODO implement
|
||||
throw new DoesNotExistException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns all objects in the calendar $calendarURI of the user $userId
|
||||
* @param string $calendarURI
|
||||
* @param string $userId
|
||||
* @returns \OCA\Calendar\Db\ObjectCollection
|
||||
* @throws DoesNotExistException if calendar does not exist
|
||||
*
|
||||
* This method returns an \OCA\Calendar\Db\ObjectCollection object.
|
||||
* This method is mandatory!
|
||||
*/
|
||||
public function findObjects(Calendar &$calendar, $limit, $offset) {
|
||||
//TODO implement
|
||||
return new ObjectCollection();
|
||||
}
|
||||
}
|
|
@ -8,29 +8,29 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Backend;
|
||||
|
||||
use \OCA\Calendar\AppFramework\Core\API;
|
||||
use \OCA\Calendar\AppFramework\Db\Mapper;
|
||||
use \OCA\Calendar\AppFramework\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
|
||||
use \OCA\Calendar\Db\Calendar;
|
||||
use \OCA\Calendar\Db\CalendarCollection;
|
||||
|
||||
use \OCA\Calendar\Db\Object;
|
||||
use \OCA\Calendar\Db\ObjectCollection;
|
||||
|
||||
use \OCA\Calendar\Db\TimeZone;
|
||||
use \OCA\Calendar\Db\TimeZoneCollection;
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
class Anniversary extends Backend {
|
||||
class Contact extends Backend {
|
||||
|
||||
public $calendarURI;
|
||||
public $calendarURIs;
|
||||
|
||||
public function __construct($api, $parameters){
|
||||
parent::__construct($api, 'Anniversary');
|
||||
parent::__construct($api, 'Contact');
|
||||
|
||||
$this->calendarURI = 'anniversary';
|
||||
$this->calendarURIs = array(
|
||||
'anniversary',
|
||||
'birthday',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,8 +68,8 @@ class Anniversary extends Backend {
|
|||
* This method is mandatory!
|
||||
*/
|
||||
public function findCalendar($calendarURI, $userId) {
|
||||
if($calendarURI !== $this->calendarURI) {
|
||||
$msg = 'Backend\Anniversary::findCalendar(): ';
|
||||
if(!$this->doesCalendarExist($calendarURI, $userId)) {
|
||||
$msg = 'Backend\Contact::findCalendar(): ';
|
||||
$msg .= '"' . $calendarURI . '" doesn\'t exist';
|
||||
throw new DoesNotExistException($msg);
|
||||
}
|
||||
|
@ -78,12 +78,20 @@ class Anniversary extends Backend {
|
|||
$calendar->setUserId($userId);
|
||||
$calendar->setOwnerId($userId);
|
||||
$calendar->setBackend($this->backend);
|
||||
$calendar->setUri($this->calendarURI);
|
||||
$calendar->setDisplayname('Anniversary'); //TODO - use translation
|
||||
$calendar->setUri($calendarURI);
|
||||
$calendar->setComponents(ObjectType::EVENT);
|
||||
$calendar->setCtag(1); //sum of all addressbook ctags
|
||||
$calendar->setTimezone(new TimeZone('UTC'));
|
||||
$calendar->setCruds(Permissions::READ + Permissions::SHARE);
|
||||
$calendar->setColor('#ffffff');
|
||||
$calendar->setOrder(0);
|
||||
$calendar->setEnabled(true);
|
||||
|
||||
if($calendarURI === 'anniversary') {
|
||||
$calendar->setDisplayname('Anniversary'); //TODO - use translation
|
||||
} elseif($calendarURI === 'birthday') {
|
||||
$calendar->setDisplayname('Birthday'); //TODO - use translation
|
||||
}
|
||||
|
||||
return $calendar;
|
||||
}
|
||||
|
@ -98,7 +106,13 @@ class Anniversary extends Backend {
|
|||
* This method is mandatory!
|
||||
*/
|
||||
public function findCalendars($userId, $limit=null, $offset=null) {
|
||||
return new CalendarCollection($this->findCalendar($this->calendarURI, $userId));
|
||||
$calendars = new CalendarCollection();
|
||||
|
||||
foreach($this->calendarURIs as $uri) {
|
||||
$calendars->add($this->findCalendar($uri, $userId));
|
||||
}
|
||||
|
||||
return $calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +137,7 @@ class Anniversary extends Backend {
|
|||
* This method is mandatory!
|
||||
*/
|
||||
public function doesCalendarExist($calendarURI, $userId) {
|
||||
if($calendarURI === $this->calendarURI) {
|
||||
if(in_array($calendarURI, $this->calendarURIs)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
|
@ -33,18 +33,12 @@ class Local extends Backend {
|
|||
private $calTableName;
|
||||
private $objTableName;
|
||||
|
||||
private $typeMapper = array(
|
||||
private static $typeMapper = array(
|
||||
ObjectType::EVENT => 'VEVENT',
|
||||
ObjectType::JOURNAL => 'VJOURNAL',
|
||||
ObjectType::TODO => 'VTODO',
|
||||
);
|
||||
|
||||
private $reverseTypeMapper = array(
|
||||
'VEVENT' => ObjectType::EVENT,
|
||||
'VJOURNAL' => ObjectType::JOURNAL,
|
||||
'VTODO' => ObjectType::TODO,
|
||||
);
|
||||
|
||||
public function __construct(IAppContainer $api,
|
||||
array $parameters){
|
||||
|
||||
|
@ -77,8 +71,13 @@ class Local extends Backend {
|
|||
* @return Calendar
|
||||
*/
|
||||
public function findCalendar($calendarURI, $userId) {
|
||||
$sql = 'SELECT * FROM `'. $this->calTableName . '` WHERE `uri` = ? AND `userid` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array($calendarURI, $userId));
|
||||
$sql = 'SELECT * FROM `?` ';
|
||||
$sql .= 'WHERE `uri` = ? AND `userid` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendarURI,
|
||||
$userId
|
||||
));
|
||||
$row = $result->fetchRow();
|
||||
|
||||
if($row === false || $row === null){
|
||||
|
@ -106,8 +105,12 @@ class Local extends Backend {
|
|||
* @return CalendarCollection
|
||||
*/
|
||||
public function findCalendars($userId, $limit, $offset) {
|
||||
$sql = 'SELECT * FROM `' . $this->calTableName . '` WHERE `userid` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array($userId)); //add limit offset thingy
|
||||
$sql = 'SELECT * FROM `?` ';
|
||||
$sql .= 'WHERE `userid` = ? ORDER BY `calendarorder`';
|
||||
$result = \OCP\DB::prepare($sql, $limit, $offset)->execute(array(
|
||||
$this->calTableName,
|
||||
$userId
|
||||
));
|
||||
|
||||
$calendarCollection = new CalendarCollection();
|
||||
while($row = $result->fetchRow()){
|
||||
|
@ -131,10 +134,11 @@ class Local extends Backend {
|
|||
* @return integer
|
||||
*/
|
||||
public function countCalendars($userId) {
|
||||
$sql = 'SELECT COUNT(*) FROM `' . $this->calTableName . '`';
|
||||
$sql .= ' WHERE `userid` = ?';
|
||||
$sql = 'SELECT COUNT(*) FROM `?` ';
|
||||
$sql .= 'WHERE `userid` = ?';
|
||||
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$userId
|
||||
));
|
||||
$count = $result->fetchOne();
|
||||
|
@ -153,10 +157,11 @@ class Local extends Backend {
|
|||
* @return boolean
|
||||
*/
|
||||
public function doesCalendarExist($calendarURI, $userId) {
|
||||
$sql = 'SELECT COUNT(*) FROM `' . $this->calTableName . '`';
|
||||
$sql .= ' WHERE `uri` = ? AND `userid` = ?';
|
||||
$sql = 'SELECT COUNT(*) FROM `?` ';
|
||||
$sql .= 'WHERE `uri` = ? AND `userid` = ?';
|
||||
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendarURI,
|
||||
$userId
|
||||
));
|
||||
|
@ -180,10 +185,11 @@ class Local extends Backend {
|
|||
* @return integer
|
||||
*/
|
||||
public function getCalendarsCTag($calendarURI, $userId) {
|
||||
$sql = 'SELECT `ctag` FROM `' . $this->calTableName . '`';
|
||||
$sql .= ' WHERE `uri` = ? AND `userid` = ?';
|
||||
$sql = 'SELECT `ctag` FROM `?` ';
|
||||
$sql .= 'WHERE `uri` = ? AND `userid` = ?';
|
||||
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendarURI,
|
||||
$userId
|
||||
));
|
||||
|
@ -212,11 +218,12 @@ class Local extends Backend {
|
|||
throw new CacheOutDatedException($msg);
|
||||
}
|
||||
|
||||
$sql = 'INSERT INTO `' . $this->calTableName . '` ';
|
||||
$sql = 'INSERT INTO `?` ';
|
||||
$sql .= '(`userid`, `displayname`, `uri`, `active`, `ctag`, `calendarorder`, ';
|
||||
$sql .= '`calendarcolor`, `timezone`, `components`) ';
|
||||
$sql .= 'VALUES(?,?,?,?,?,?,?,?,?)';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendar->getUserId(),
|
||||
$calendar->getDisplayname(),
|
||||
$calendar->getUri(),
|
||||
|
@ -239,18 +246,19 @@ class Local extends Backend {
|
|||
* @throws CacheOutDatedException if calendar does not exist
|
||||
* @return Calendar
|
||||
*/
|
||||
public function updateCalendar(Calendar &$calendar, $oldCalendarURI, $oldUserId) {
|
||||
public function updateCalendar(Calendar &$calendar) {
|
||||
if($this->doesCalendarExist($oldCalendarURI, $oldUserId) === false) {
|
||||
$msg = 'Backend\Local::updateCalendar(): Internal Error: ';
|
||||
$msg .= 'Calendar with uri and userid combination not found!';
|
||||
throw new CacheOutDatedException($msg);
|
||||
}
|
||||
|
||||
$sql = 'UPDATE `' . $this->calTableName . '` SET ';
|
||||
$sql = 'UPDATE `?` SET ';
|
||||
$sql .= '`userid` = ?, `displayname` = ?, `uri` = ?, `active` = ?, `ctag` = ?, ';
|
||||
$sql .= '`calendarorder` = ?, `calendarcolor` = ?, `timezone` = ?, `components` = ? ';
|
||||
$sql .= 'WHERE `userid` = ? AND `uri` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendar->getUserId(),
|
||||
$calendar->getDisplayname(),
|
||||
$calendar->getUri(),
|
||||
|
@ -274,9 +282,10 @@ class Local extends Backend {
|
|||
* @return boolean
|
||||
*/
|
||||
public function deleteCalendar($calendarURI, $userId) {
|
||||
$sql = 'DELETE FROM `' . $this->calTableName . '` ';
|
||||
$sql = 'DELETE FROM `?` ';
|
||||
$sql .= '`uri` = ? AND `userid` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array(
|
||||
$this->calTableName,
|
||||
$calendarURI,
|
||||
$userId
|
||||
));
|
||||
|
@ -300,6 +309,10 @@ class Local extends Backend {
|
|||
//$this->deleteCalendar($oldCalendarURI, $oldUserId);
|
||||
}
|
||||
|
||||
public function moveCalendar(Calendar &$calendar, $oldCalendarURI, $oldUserId) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* find object
|
||||
* @param Calendar $calendar
|
||||
|
@ -350,7 +363,10 @@ class Local extends Backend {
|
|||
$sql = 'SELECT `' . $this->objTableName . '`.* FROM `' . $this->objTableName . '`, `' . $this->calTableName . '` ';
|
||||
$sql .= 'WHERE `' . $this->objTableName . '`.`calendarid`=`' . $this->calTableName . '`.`id` ';
|
||||
$sql .= 'AND `' . $this->calTableName . '`.`uri` = ? AND `' . $this->calTableName . '`.`userid` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array($calendarURI, $userId)); //add limit offset thingy
|
||||
$result = \OCP\DB::prepare($sql, $limit, $offset)->execute(array(
|
||||
$calendarURI,
|
||||
$userId
|
||||
)); //add limit offset thingy
|
||||
|
||||
$objectCollection = new ObjectCollection();
|
||||
while($row = $result->fetchRow()){
|
||||
|
@ -422,10 +438,15 @@ class Local extends Backend {
|
|||
* @return ObjectCollection
|
||||
*/
|
||||
public function findObjectsByType(Calendar $calendar, $type, $limit, $offset) {
|
||||
$calendarURI = $calendar->getUri();
|
||||
$userId = $calendar->getUserId();
|
||||
$type = static::$typeMapper[$type];
|
||||
|
||||
|
||||
$sql = 'SELECT `' . $this->objTableName . '`.* FROM `' . $this->objTableName . '`, `' . $this->calTableName . '` ';
|
||||
$sql .= 'WHERE `' . $this->objTableName . '`.`calendarid`=`' . $this->calTableName . '`.`id` ';
|
||||
$sql .= 'AND `' . $this->calTableName . '`.`uri` = ? and `' . $this->calTableName . '`.`userid` = ? AND `' . $this->objTableName . '`.`objecttype` = ?';
|
||||
$result = \OCP\DB::prepare($sql)->execute(array($calendarId, $userId, $type));
|
||||
$result = \OCP\DB::prepare($sql)->execute(array($calendarURI, $userId, $type));
|
||||
|
||||
$objectCollection = new ObjectCollection();
|
||||
while($row = $result->fetchRow()){
|
||||
|
@ -753,14 +774,56 @@ class Local extends Backend {
|
|||
//return new Timezone($row['timezone');
|
||||
}
|
||||
|
||||
private function createObjectFromRow(&$row) {
|
||||
private function createObjectFromRow(&$row, $calendar) {
|
||||
$object = new Object();
|
||||
$object->setCalendar($calendar);
|
||||
$object->setObjectURI($row['uri']);
|
||||
$object->setRuds(Permissions::ALL);
|
||||
$object->setCalendarData($row['calendardata']);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function getType($type=null) {
|
||||
$typeMapper = static::$typeMapper;
|
||||
if(is_string($type)) {
|
||||
$typeMapper = array_flip($typeMapper);
|
||||
}
|
||||
if(array_key_exists($type, $typeMapper)) {
|
||||
return $typeMapper[$type];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTypes($type=null) {
|
||||
if(is_string($type)) {
|
||||
if(substr_count($type, ', ')) {
|
||||
$list = explode(', ', $type);
|
||||
}
|
||||
if(substr_count($type, ',')) {
|
||||
$list = explode(',', $type);
|
||||
}
|
||||
if(substr_count($type, ' ')) {
|
||||
$list = explode($type, ' ');
|
||||
}
|
||||
} elseif(is_int($type)) {
|
||||
$newType = array();
|
||||
if(ObjectType::EVENT & $type) {
|
||||
$newType[] = static::$typeMapper[ObjectType::EVENT];
|
||||
}
|
||||
if(ObjectType::JOURNAL & $type) {
|
||||
$newType[] = static::$typeMapper[ObjectType::EVENT];
|
||||
}
|
||||
if(ObjectType::TODO & $type) {
|
||||
$newType[] = static::$typeMapper[ObjectType::EVENT];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function fetchCalendarPropertiesFromRemote() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,22 +11,30 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Backend;
|
||||
|
||||
use \OCA\Calendar\AppFramework\Core\API;
|
||||
use \OCA\Calendar\AppFramework\Db\Mapper;
|
||||
use \OCA\Calendar\AppFramework\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use \OCP\AppFramework\IAppContainer;
|
||||
|
||||
use \OCA\Calendar\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\Db\MultipleObjectsReturnedException;
|
||||
|
||||
use \OCA\Calendar\Db\Calendar;
|
||||
use \OCA\Calendar\Db\Object;
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
use \OCA\Calendar\Db\CalendarCollection;
|
||||
|
||||
use \OCA\Calendar\Db\Object;
|
||||
use \OCA\Calendar\Db\ObjectCollection;
|
||||
|
||||
use \OCA\Calendar\Db\Timezone;
|
||||
use \OCA\Calendar\Db\TimezoneCollection;
|
||||
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
use \DateTime;
|
||||
|
||||
class Sharing extends Backend {
|
||||
|
||||
private $backend;
|
||||
|
||||
private $crudsMapper = array(
|
||||
private static $crudsMapper = array(
|
||||
\OCP\PERMISSION_CREATE => Permissions::CREATE,
|
||||
\OCP\PERMISSION_READ => Permissions::READ,
|
||||
\OCP\PERMISSION_UPDATE => Permissions::UPDATE,
|
||||
|
@ -35,15 +43,6 @@ class Sharing extends Backend {
|
|||
\OCP\PERMISSION_ALL => Permissions::ALL,
|
||||
);
|
||||
|
||||
private $reverseCrudsMapper = array(
|
||||
Permissions::CREATE => \OCP\PERMISSION_CREATE,
|
||||
Permissions::READ => \OCP\PERMISSION_READ,
|
||||
Permissions::UPDATE => \OCP\PERMISSION_UPDATE,
|
||||
Permissions::DELETE => \OCP\PERMISSION_DELETE,
|
||||
Permissions::SHARE => \OCP\PERMISSION_SHARE,
|
||||
Permissions::ALL => \OCP\PERMISSION_ALL,
|
||||
);
|
||||
|
||||
public function __construct($api, $parameters, &$backendBusinessLayer){
|
||||
parent::__construct($api, 'sharing');
|
||||
$this->backend = $backendBusinessLayer;
|
||||
|
|
|
@ -27,6 +27,8 @@ abstract class BusinessLayer {
|
|||
*/
|
||||
protected $app;
|
||||
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* app container for dependency injection
|
||||
* @var \OCA\Calendar\BusinessLayer\BackendBusinessLayer
|
||||
|
@ -46,6 +48,7 @@ abstract class BusinessLayer {
|
|||
*/
|
||||
public function __construct(IAppContainer $app, BackendMapper $backendMapper){
|
||||
$this->app = $app;
|
||||
$this->api = $app->getCoreApi();
|
||||
$this->bmp = $backendMapper;
|
||||
|
||||
$this->setupBackends();
|
||||
|
|
|
@ -7,9 +7,16 @@
|
|||
*/
|
||||
namespace OCA\Calendar\BusinessLayer;
|
||||
|
||||
use \OCP\AppFramework\Http;
|
||||
|
||||
class BusinessLayerException extends \Exception {
|
||||
const FORBIDDEN = 403;
|
||||
const NOTFOUND = 404;
|
||||
const CONFLICT = 409;
|
||||
const INTERNAL = 500;
|
||||
|
||||
public function __construct($message=null, $code=null, \Exception $previous=null) {
|
||||
if($code === null) {
|
||||
$code = Http::STATUS_BAD_REQUEST;
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -8,6 +8,7 @@
|
|||
namespace OCA\Calendar\BusinessLayer;
|
||||
|
||||
use \OCP\AppFramework\IAppContainer;
|
||||
use \OCP\AppFramework\Http;
|
||||
|
||||
use \OCA\Calendar\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\Db\MultipleObjectsReturnedException;
|
||||
|
@ -92,6 +93,7 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the number how many calendars a user has
|
||||
* @param Calendar &$calendar Calendar object
|
||||
|
@ -228,6 +230,8 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
throw new BusinessLayerException($msg);
|
||||
}
|
||||
|
||||
$api = &$this->backends->find($backend)->api;
|
||||
|
||||
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
|
||||
if($cacheObjects === true) {
|
||||
$objects = $this->omp->findAllByType($calendar, $type, $limit, $offset);
|
||||
|
@ -398,7 +402,7 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
* @throws BusinessLayerException
|
||||
* @return array containing all items
|
||||
*/
|
||||
public function create(Object $object) {
|
||||
public function create(Object &$object) {
|
||||
try {
|
||||
$backend = $object->calendar->getBackend();
|
||||
$calendarURI = $object->calendar->getUri();
|
||||
|
@ -450,6 +454,10 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
}
|
||||
}
|
||||
|
||||
public function createFromRequest(Object &$object) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* updates an object
|
||||
* @param Object $object
|
||||
|
@ -459,7 +467,7 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
* @throws BusinessLayerException
|
||||
* @return array containing all items
|
||||
*/
|
||||
public function update(Object $object, Calendar $calendar, $objectURI, $userId) {
|
||||
public function update(Object &$object, Calendar &$calendar, $objectURI) {
|
||||
try {
|
||||
if(is_array($calendarId)) {
|
||||
$backend = $calendarId[0];
|
||||
|
@ -502,6 +510,19 @@ class ObjectBusinessLayer extends BusinessLayer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public function updateFromRequest(Object $object, Calendar &$calendar, $objectURI, $etag) {
|
||||
$oldObject = $this->find($calendar, $objectURI);
|
||||
|
||||
if($oldObject->getEtag() !== $etag) {
|
||||
$msg = 'ObjectBusinessLayer::updateFromRequest(): User Error: ';
|
||||
$msg .= 'If-Match failed; etags are not equal!';
|
||||
throw new BusinessLayerException($msg, Http::STATUS_PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
return $this->update($object, $calendar, $objectURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete an object from a calendar
|
||||
* @param string $calendarId global uri of calendar e.g. local-work
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Controller;
|
||||
|
||||
use \OCP\AppFramework\Http\Http;
|
||||
use \OCP\AppFramework\Http;
|
||||
|
||||
use \OCA\Calendar\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\BusinessLayer\BusinessLayerException;
|
||||
|
@ -15,192 +15,164 @@ use \OCA\Calendar\BusinessLayer\BusinessLayerException;
|
|||
use \OCA\Calendar\Db\Calendar;
|
||||
use \OCA\Calendar\Db\CalendarCollection;
|
||||
|
||||
use \OCA\Calendar\Http\JSONResponse;
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
use \OCA\Calendar\Db\Permission;
|
||||
|
||||
use \OCA\Calendar\Http\ICS\ICSCalendar;
|
||||
use \OCA\Calendar\Http\ICS\ICSCalendarCollection;
|
||||
use \OCA\Calendar\Http\ICS\ICSCalendarReader;
|
||||
use \OCA\Calendar\Http\Response;
|
||||
|
||||
use \OCA\Calendar\Http\JSON\JSONCalendar;
|
||||
use \OCA\Calendar\Http\JSON\JSONCalendarCollection;
|
||||
use \OCA\Calendar\Http\JSON\JSONCalendarReader;
|
||||
use \OCA\Calendar\Http\Reader;
|
||||
use \OCA\Calendar\Http\Serializer;
|
||||
use \OCA\Calendar\Http\ReaderExpcetion;
|
||||
use \OCA\Calendar\Http\SerializerException;
|
||||
|
||||
class CalendarController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function index() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$limit = $this->header('X-OC-CAL-LIMIT', 'integer');
|
||||
$offset = $this->header('X-OC-CAL-OFFSET', 'integer');
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
|
||||
$calendarCollection = $this->calendarBusinessLayer->findAll($userId, $limit, $offset);
|
||||
if($doesAcceptRawICS === true) {
|
||||
$serializer = new ICSCalendarCollection($calendarCollection);
|
||||
$nolimit = $this->params('nolimit', false);
|
||||
if($nolimit) {
|
||||
$limit = $offset = null;
|
||||
} else {
|
||||
$serializer = new JSONCalendarCollection($calendarCollection);
|
||||
$limit = $this->params('limit', 25);
|
||||
$offset = $this->params('offset', 0);
|
||||
}
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
$calendarCollection = $this->calendarBusinessLayer->findAll($userId, $limit, $offset);
|
||||
|
||||
$serializer = new Serializer(Serializer::CalendarCollection, $calendarCollection, $this->accept());
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function show() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
$calendarId = $this->request->getParam('calendarId');
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if($doesAcceptRawICS === true) {
|
||||
$serializer = new ICSCalendar($calendar);
|
||||
} else {
|
||||
$serializer = new JSONCalendar($calendar);
|
||||
}
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
$serializer = new Serializer(Serializer::Calendar, $calendar, $this->accept());
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function create() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$data = $this->request->params;
|
||||
|
||||
$didSendRawICS = $this->didClientSendRawICS();
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
$reader = new Reader(Reader::Calendar, $data, $this->contentType());
|
||||
|
||||
if($didSendRawICS === true) {
|
||||
$reader = new ICSCalendarReader($data);
|
||||
$calendar = $reader->sanitize()->getObject();
|
||||
|
||||
if($calendar instanceof Calendar) {
|
||||
$calendar = $this->calendarBusinessLayer->createFromRequest($calendar);
|
||||
$serializer = new Serializer(Serializer::Calendar, $calendar, $this->accept());
|
||||
} elseif($calendar instanceof CalendarCollection) {
|
||||
$calendar = $this->calendarBusinessLayer->createCollectionFromRequest($calendar);
|
||||
$serializer = new serializer(Serializer::CalendarCollection, $calendar, $this->accept());
|
||||
} else {
|
||||
$reader = new JSONCalendarReader($data);
|
||||
throw new ReaderException('Reader returned unrecognised format.');
|
||||
}
|
||||
|
||||
var_dump($reader->sanitize()->getObject());
|
||||
exit;
|
||||
|
||||
$calendar = $reader->sanitize()->getCalendar();
|
||||
$calendar->setUser($userId)->setOwner($userId);
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->create($calendar);
|
||||
|
||||
if($doesAcceptRawICS === true) {
|
||||
$serializer = new ICSCalendar($calendar);
|
||||
} else {
|
||||
$serializer = new JSONCalendar($calendar);
|
||||
}
|
||||
|
||||
return new JSONResponse($serializer, HTTP::STATUS_CREATED);
|
||||
$serializer = new Serializer(Serializer::Calendar, $calendar, $this->accept());
|
||||
return new Response($serializer, Http::STATUS_CREATED);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch(ReaderException $ex) {
|
||||
return new Response(array('message' => $ex->getMessage()), Http::STATUS_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function update() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
$ctag = $this->header('if-match');
|
||||
$data = $this->request->params;
|
||||
|
||||
$didSendRawICS = $this->didClientSendRawICS();
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
$reader = new Reader(Reader::Calendar, $data, $this->contentType());
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
if($didSendRawICS === true) {
|
||||
$reader = new ICSCalendarReader($data);
|
||||
$calendar = $reader->sanitize()->getObject();
|
||||
if($calendar instanceof Calendar) {
|
||||
$calendar = $this->calendarBusinessLayer->updateFromRequest($calendar, $calendarId, $userId, $ctag);
|
||||
} elseif($calendar instanceof CalendarCollection) {
|
||||
throw new ReaderException('Updates can only be applied to a single resource.', Http::STATUS_BAD_REQUEST);
|
||||
} else {
|
||||
$reader = new JSONCalendarReader($data);
|
||||
throw new ReaderException('Reader returned unrecognised format.');
|
||||
}
|
||||
|
||||
$calendar = $reader->sanitize()->getCalendar();
|
||||
$calendar->setUser($userId);
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->update($calendar, $calendarId, $userId);
|
||||
|
||||
if($doesAcceptRawICS === true) {
|
||||
$serializer = new ICSCalendar($calendar);
|
||||
} else {
|
||||
$serializer = new JSONCalendar($calendar);
|
||||
}
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
$serializer = new Serializer(Serializer::Calendar, $calendar, $this->accept());
|
||||
return new Response($serializer);
|
||||
} catch(BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch(ReaderException $ex) {
|
||||
return new Response(array('message' => $ex->getMessage()), Http::STATUS_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function destroy() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
$this->calendarBusinessLayer->delete($calendar);
|
||||
|
||||
$this->calendarBusinessLayer->delete($calendarId, $userId);
|
||||
|
||||
return new JSONResponse();
|
||||
return new Response();
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function forceUpdate() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$this->calendarBusinessLayer->updateCacheForAllFromRemote($userId);
|
||||
return new JSONResponse();
|
||||
return new Response();
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
$this->app->log($ex->getMessage(), 'debug');
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,18 +22,21 @@ abstract class Controller extends \OCP\AppFramework\Controller {
|
|||
*/
|
||||
protected $calendarBusinessLayer;
|
||||
|
||||
|
||||
/**
|
||||
* object business layer
|
||||
* @var \OCA\Calendar\BusinessLayer\ObjectBusinessLayer
|
||||
*/
|
||||
protected $objectBusinessLayer;
|
||||
|
||||
|
||||
/**
|
||||
* core api
|
||||
* @var \OCP\AppFramework\IApi
|
||||
*/
|
||||
protected $api;
|
||||
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param IAppContainer $app interface to the app
|
||||
|
@ -46,6 +49,7 @@ abstract class Controller extends \OCP\AppFramework\Controller {
|
|||
|
||||
parent::__construct($app, $request);
|
||||
|
||||
$this->app = $app;
|
||||
$this->api = $app->getCoreApi();
|
||||
|
||||
if($calendarBusinessLayer instanceof CalendarBusinessLayer) {
|
||||
|
@ -56,6 +60,22 @@ abstract class Controller extends \OCP\AppFramework\Controller {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get a param
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed $value
|
||||
*/
|
||||
public function params($key, $default=null){
|
||||
$value = parent::params($key, $default);
|
||||
if($default !== null) {
|
||||
settype($value, gettype($default));
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lets you access http request header
|
||||
* @param string $key the key which you want to access in the http request header
|
||||
|
@ -65,6 +85,8 @@ abstract class Controller extends \OCP\AppFramework\Controller {
|
|||
protected function header($key, $type='string', $default=null){
|
||||
$key = 'HTTP_' . strtoupper($key);
|
||||
|
||||
$key = str_replace('-', '_', $key);
|
||||
|
||||
if(isset($this->request->server[$key]) === false) {
|
||||
return $default;
|
||||
} else {
|
||||
|
@ -78,62 +100,28 @@ abstract class Controller extends \OCP\AppFramework\Controller {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* did user request raw ics instead of json
|
||||
* @param boolean
|
||||
*/
|
||||
protected function doesClientAcceptRawICS() {
|
||||
|
||||
protected function accept() {
|
||||
$accept = $this->header('accept');
|
||||
|
||||
//check if text/calendar is in the text
|
||||
//if not, return false
|
||||
$textCalendarPosition = stripos($accept, 'text/calendar');
|
||||
if($textCalendarPosition === false) {
|
||||
return false;
|
||||
if(substr_count($accept, ',')) {
|
||||
list($accept) = explode(',', $accept);
|
||||
}
|
||||
if(substr_count($accept, ';')) {
|
||||
list($accept) = explode(';', $accept);
|
||||
}
|
||||
|
||||
//get posistion of application/json and application/calendar+json
|
||||
$applicationJSONPosition = stripos($accept, 'application/json');
|
||||
$applicationCalendarJSONPosition = stripos($accept, 'application/calendar+json');
|
||||
|
||||
if($applicationJSONPosition === false && $applicationCalendarJSONPosition === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$firstApplicationPosition = min($applicationJSONPosition, $applicationCalendarJSONPosition);
|
||||
|
||||
return ($firstApplicationPosition < $textCalendarPosition) ? false : true;
|
||||
return $accept;
|
||||
}
|
||||
|
||||
/**
|
||||
* did user request raw ics instead of json
|
||||
* @param boolean
|
||||
*/
|
||||
protected function didClientSendRawICS() {
|
||||
$contentType = $this->header('content-type');
|
||||
|
||||
//check if there is some charset info
|
||||
if(stripos($contentType, ';')) {
|
||||
$explodeContentType = explode(';', $contentType);
|
||||
$contentType = $explodeContentType[0];
|
||||
protected function contentType() {
|
||||
$contentType = $this->header('content-type');
|
||||
|
||||
if(substr_count($contentType, ';')) {
|
||||
list($contentType) = explode(';', $contentType);
|
||||
}
|
||||
|
||||
$didClientSendRawICS = false;
|
||||
switch($contentType) {
|
||||
case 'text/calendar':
|
||||
$didClientSendRawICS = true;
|
||||
break;
|
||||
|
||||
case 'application/json':
|
||||
case 'application/calendar+json':
|
||||
$didClientSendRawICS = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
$didClientSendRawICS = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return $didClientSendRawICS;
|
||||
return $contentType;
|
||||
}
|
||||
}
|
|
@ -17,132 +17,124 @@ use \OCA\Calendar\Db\ObjectCollection;
|
|||
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
use \OCA\Calendar\Http\JSONResponse;
|
||||
use \OCA\Calendar\Http\Response;
|
||||
|
||||
use \OCA\Calendar\Http\ICS\ICSObject;
|
||||
use \OCA\Calendar\Http\ICS\ICSObjectCollection;
|
||||
use \OCA\Calendar\Http\ICS\ICSObjectReader;
|
||||
|
||||
use \OCA\Calendar\Http\JSON\JSONObject;
|
||||
use \OCA\Calendar\Http\JSON\JSONObjectCollection;
|
||||
use \OCA\Calendar\Http\JSON\JSONObjectReader;
|
||||
use \OCA\Calendar\Http\Reader;
|
||||
use \OCA\Calendar\Http\Serializer;
|
||||
use \OCA\Calendar\Http\ReaderExpcetion;
|
||||
use \OCA\Calendar\Http\SerializerException;
|
||||
|
||||
class ObjectController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
* @API
|
||||
*/
|
||||
public function index() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
$limit = $this->header('X-OC-CAL-LIMIT', 'integer');
|
||||
$offset = $this->header('X-OC-CAL-OFFSET', 'integer');
|
||||
$expand = $this->params('expand', false);
|
||||
|
||||
$expand = $this->header('X-OC-CAL-EXPAND', 'boolean');
|
||||
$start = $this->header('X-OC-CAL-START', 'DateTime');
|
||||
$end = $this->header('X-OC-CAL-END', 'DateTime');
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to read calendar, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
if($start === null || $end === null) {
|
||||
$objectCollection =
|
||||
$this->objectBusinessLayer
|
||||
->findAll($calendarId, $userId,
|
||||
$limit, $offset);
|
||||
$nolimit = $this->params('nolimit', false);
|
||||
if($nolimit) {
|
||||
$limit = $offset = null;
|
||||
} else {
|
||||
$objectCollection =
|
||||
$this->objectBusinessLayer
|
||||
->findAllInPeriod($calendarId, $start,
|
||||
$end, $userId,
|
||||
$limit, $offset);
|
||||
$limit = $this->params('limit', 25);
|
||||
$offset = $this->params('offset', 0);
|
||||
}
|
||||
|
||||
if($expand === true) {
|
||||
$objectCollection->expand($start, $end);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObjectCollection($objectCollection) :
|
||||
new JSONObjectCollection($objectCollection);
|
||||
$objectCollection = $this->objectBusinessLayer->findAll($calendar, $expand,
|
||||
$limit, $offset);
|
||||
|
||||
return new JSONResponse($serializer, Http::STATUS_OK);
|
||||
$serializer = new Serializer(Serializer::ObjectCollection, $objectCollection, $this->accept());
|
||||
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch (SerializerException $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
*
|
||||
* @brief returns $object specified by it's UID
|
||||
* @return an instance of a Response implementation
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function indexInPeriod() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
$nolimit = $this->params('nolimit', false);
|
||||
if($nolimit) {
|
||||
$limit = $offset = null;
|
||||
} else {
|
||||
$limit = $this->params('limit', 25);
|
||||
$offset = $this->params('offset', 0);
|
||||
}
|
||||
|
||||
$expand = $this->params('expand', false);
|
||||
$start = $this->params('start', new DateTime(date('Y-m-01')));
|
||||
$end = $this->params('end', new DateTime(date('Y-m-t')));
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$objectCollection = $this->objectBusinessLayer->findAllInPeriod($calendar, $start, $end,
|
||||
$expand, $limit, $offset);
|
||||
|
||||
$serializer = new Serializer(Serializer::ObjectCollection, $objectCollection, $this->accept());
|
||||
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch (SerializerException $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function show() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
$objectURI = $this->params('objectId');
|
||||
|
||||
$expand = $this->header('X-OC-CAL-EXPAND', 'boolean');
|
||||
$start = $this->header('X-OC-CAL-START', 'DateTime');
|
||||
$end = $this->header('X-OC-CAL-END', 'DateTime');
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
|
||||
//check if calendar and object exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false ||
|
||||
$this->objectBusinessLayer->doesExist($calendarId, $objectURI, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to read calendar, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$object = $this->objectBusinessLayer->find($calendarId, $objectURI, $userId);
|
||||
$object = $this->objectBusinessLayer->find($calendar, $objectURI);
|
||||
|
||||
if($expand === true) {
|
||||
$objectCollection = $object->expand($start, $end);
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObjectCollection($objectCollection) :
|
||||
new JSONObjectCollection($objectCollection);
|
||||
} else {
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObject($object) :
|
||||
new JSONObject($object);
|
||||
}
|
||||
$serializer = new Serializer(Serializer::Object, $object, $this->accept());
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, Http::STATUS_NOT_FOUND);
|
||||
} catch (JSONException $ex) {
|
||||
//do smth
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch (SerializerException $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function create() {
|
||||
try {
|
||||
|
@ -150,104 +142,80 @@ class ObjectController extends Controller {
|
|||
$calendarId = $this->params('calendarId');
|
||||
$data = $this->request->params;
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to create objects, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(PERMISSIONS::CREATE, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::CREATE)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$didSendRawICS = $this->didClientSendRawICS();
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
$reader = new Reader(Reader::Object, $data, $this->contentType());
|
||||
$object = $reader->sanitize()->getObject()->setCalendar($calendar);
|
||||
|
||||
if($didSendRawICS === true) {
|
||||
$reader = new ICSObjectReader($data);
|
||||
if($object instanceof Object) {
|
||||
$object = $this->objectBusinessLayer->createFromRequest($object);
|
||||
$serializer = new Serializer(Serializer::$object, $object, $this->accept());
|
||||
} elseif($object instanceof ObjectCollection) {
|
||||
$object = $this->objectBusinessLayer->createCollectionFromRequest($object);
|
||||
$serializer = new serializer(Serializer::ObjectCollection, $object, $this->accept());
|
||||
} else {
|
||||
$reader = new JSONObjectReader($data);
|
||||
throw new ReaderException('Reader returned unrecognised format.');
|
||||
}
|
||||
|
||||
$object = $reader->getObject();
|
||||
$type = $object->getType();
|
||||
|
||||
//check if calendar supports type
|
||||
|
||||
$object = $this->objectBusinessLayer->create($object, $calendarid, $userId);
|
||||
|
||||
//return no content if user is not allowed to read
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, Http::STATUS_NO_CONTENT);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_NO_CONTENT);
|
||||
}
|
||||
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObject($object) :
|
||||
new JSONObject($object);
|
||||
|
||||
return new JSONResponse($serializer, Http::STATUS_CREATED);
|
||||
return new Response($serializer, Http::STATUS_CREATED);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(null, HTTP::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function update() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
$objectURI = $this->params('objectId');
|
||||
$etag = $this->header('if-match');
|
||||
|
||||
$data = $this->request->params;
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false ||
|
||||
$this->objectBusinessLayer->doesExist($calendarId, $objectURI, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to update objects, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(PERMISSIONS::UPDATE, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::UPDATE)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$didSendRawICS = $this->didClientSendRawICS();
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
$reader = new Reader(Reader::Object, $data, $this->contentType());
|
||||
|
||||
if($didSendRawICS === true) {
|
||||
$reader = new ICSObjectReader($data);
|
||||
$object = $reader->sanitize()->getObject()->setCalendar($calendar);
|
||||
if($object instanceof Object) {
|
||||
$object = $this->objectBusinessLayer->updateFromRequest($object, $calendar, $objectURI, $etag);
|
||||
} elseif($object instanceof ObjectCollection) {
|
||||
throw new ReaderException('Updates can only be applied to a single resource.', Http::STATUS_BAD_REQUEST);
|
||||
} else {
|
||||
$reader = new JSONObjectReader($data);
|
||||
throw new ReaderException('Reader returned unrecognised format.');
|
||||
}
|
||||
|
||||
$object = $reader->getObject();
|
||||
|
||||
$object = $this->objectBusinessLayer->update($object, $objectURI, $calendarId, $userId);
|
||||
|
||||
//return no content if user is not allowed to read
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, Http::STATUS_NO_CONTENT);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_NO_CONTENT);
|
||||
}
|
||||
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObject($object) :
|
||||
new JSONObject($object);
|
||||
$serializer = new Serializer(Serializer::Object, $object, $this->accept());
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
return new Response($serializer);
|
||||
} catch(BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(null, HTTP::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function destroy() {
|
||||
try {
|
||||
|
@ -255,12 +223,18 @@ class ObjectController extends Controller {
|
|||
$calendarId = $this->params('calendarId');
|
||||
$objectURI = $this->params('objectId');
|
||||
|
||||
$this->objectBusinessLayer->delete($calendarId, $objectURI, $userId);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::DELETE)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
return new JSONResponse(null, HTTP::STATUS_NO_CONTENT);
|
||||
$object = $this->find($calendar, $objectURI);
|
||||
$this->objectBusinessLayer->delete($object);
|
||||
|
||||
return new Response(null, HTTP::STATUS_NO_CONTENT);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
return new Response(null, HTTP::STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,18 +19,17 @@ use \OCA\Calendar\Db\Object;
|
|||
use \OCA\Calendar\Db\ObjectCollection;
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
use \OCA\Calendar\BusinessLayer\CalendarBusinessLayer;
|
||||
use \OCA\Calendar\BusinessLayer\ObjectBusinessLayer;
|
||||
|
||||
use \OCA\Calendar\Http\JSONResponse;
|
||||
use \OCA\Calendar\Http\Response;
|
||||
|
||||
use \OCA\Calendar\Http\ICS\ICSObject;
|
||||
use \OCA\Calendar\Http\ICS\ICSObjectCollection;
|
||||
use \OCA\Calendar\Http\ICS\ICSObjectReader;
|
||||
|
||||
use \OCA\Calendar\Http\JSON\JSONObject;
|
||||
use \OCA\Calendar\Http\JSON\JSONObjectCollection;
|
||||
use \OCA\Calendar\Http\JSON\JSONObjectReader;
|
||||
use \OCA\Calendar\Http\Reader;
|
||||
use \OCA\Calendar\Http\Serializer;
|
||||
use \OCA\Calendar\Http\ReaderExpcetion;
|
||||
use \OCA\Calendar\Http\SerializerException;
|
||||
|
||||
abstract class ObjectTypeController extends ObjectController {
|
||||
|
||||
|
@ -61,65 +60,39 @@ abstract class ObjectTypeController extends ObjectController {
|
|||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function index() {
|
||||
try {
|
||||
var_dump('index called');
|
||||
exit;
|
||||
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
$limit = $this->header('X-OC-CAL-LIMIT', 'integer');
|
||||
$offset = $this->header('X-OC-CAL-OFFSET', 'integer');
|
||||
|
||||
$expand = $this->header('X-OC-CAL-EXPAND', 'boolean');
|
||||
$start = $this->header('X-OC-CAL-START', 'DateTime');
|
||||
$end = $this->header('X-OC-CAL-END', 'DateTime');
|
||||
|
||||
var_dump($doesAcceptRawICS);
|
||||
exit;
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
|
||||
var_dump($doesAcceptRawICS);
|
||||
exit;
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to read calendar, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
if($start === null || $end === null) {
|
||||
$objectCollection =
|
||||
$this->objectBusinessLayer
|
||||
->findAllByType($calendarId, $this->objectType,
|
||||
$userId, $limit, $offset);
|
||||
$nolimit = $this->params('nolimit', false);
|
||||
if($nolimit) {
|
||||
$limit = $offset = null;
|
||||
} else {
|
||||
$objectCollection =
|
||||
$this->objectBusinessLayer
|
||||
->findAllByTypeInPeriod($calendarId, $this->objectType,
|
||||
$start, $end,
|
||||
$userId, $limit, $offset);
|
||||
$limit = $this->params('limit', 25);
|
||||
$offset = $this->params('offset', 0);
|
||||
}
|
||||
|
||||
if($expand === true) {
|
||||
$objectCollection->expand($start, $end);
|
||||
$expand = $this->params('expand', false);
|
||||
$start = $this->params('start');
|
||||
$end = $this->params('end');
|
||||
|
||||
$type = $this->objectType;
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if($calendar->doesAllow(Permissions::READ) === false) {
|
||||
throw new ForbiddenExpcetion();
|
||||
}
|
||||
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObjectCollection($objectCollection) :
|
||||
new JSONObjectCollection($objectCollection);
|
||||
$objectCollection = $this->objectBusinessLayer->findAllByType($calendar, $type, $expand,
|
||||
$limit, $offset);
|
||||
|
||||
return new JSONResponse($serializer, Http::STATUS_OK);
|
||||
$serializer = new Serializer(Serializer::ObjectCollection, $objectCollection, $this->accept());
|
||||
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, Http::STATUS_BAD_REQUEST);
|
||||
|
@ -127,49 +100,69 @@ abstract class ObjectTypeController extends ObjectController {
|
|||
}
|
||||
|
||||
/**
|
||||
* @IsAdminExemption
|
||||
* @IsSubAdminExemption
|
||||
* @CSRFExemption
|
||||
* @API
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function indexInPeriod() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
|
||||
$nolimit = $this->params('nolimit', false);
|
||||
if($nolimit) {
|
||||
$limit = $offset = null;
|
||||
} else {
|
||||
$limit = $this->params('limit', 25);
|
||||
$offset = $this->params('offset', 0);
|
||||
}
|
||||
|
||||
$expand = $this->params('expand', false);
|
||||
$start = $this->params('start', new DateTime(date('Y-m-01')));
|
||||
$end = $this->params('end', new DateTime(date('Y-m-t')));
|
||||
|
||||
$type = $this->objectType;
|
||||
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$objectCollection = $this->objectBusinessLayer->findAllByTypeInPeriod($calendar, $type, $start, $end,
|
||||
$expand, $limit, $offset);
|
||||
|
||||
$serializer = new Serializer(Serializer::ObjectCollection, $objectCollection, $this->accept());
|
||||
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new Response(array('message' => $ex->getMessage()), $ex->getCode());
|
||||
} catch (SerializerException $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function show() {
|
||||
try {
|
||||
$userId = $this->api->getUserId();
|
||||
$calendarId = $this->params('calendarId');
|
||||
$objectId = $this->getObjectId();
|
||||
$objectURI = $this->params('objectId');
|
||||
|
||||
$expand = $this->header('X-OC-CAL-EXPAND', 'boolean');
|
||||
$start = $this->header('X-OC-CAL-START', 'DateTime');
|
||||
$end = $this->header('X-OC-CAL-END', 'DateTime');
|
||||
$type = $this->objectType;
|
||||
|
||||
$doesAcceptRawICS = $this->doesClientAcceptRawICS();
|
||||
|
||||
//check if calendar exists, if not return 404
|
||||
if($this->calendarBusinessLayer->doesExist($calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_NOT_FOUND);
|
||||
}
|
||||
//check if user is allowed to read calendar, if not return 403
|
||||
if($this->calendarBusinessLayer->doesAllow(Permissions::READ, $calendarId, $userId) === false) {
|
||||
return new JSONResponse(null, HTTP::STATUS_FORBIDDEN);
|
||||
$calendar = $this->calendarBusinessLayer->find($calendarId, $userId);
|
||||
if(!$calendar->doesAllow(Permissions::READ)) {
|
||||
return new Response(null, HTTP::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$object =
|
||||
$this->objectBusinessLayer
|
||||
->findByType($calendarId, $objectId,
|
||||
$this->objecttype, $userId);
|
||||
$object = $this->objectBusinessLayer->find($calendar, $objectURI, $type);
|
||||
|
||||
if($expand === true) {
|
||||
$objectCollection = $object->expand($start, $end);
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObjectCollection($objectCollection) :
|
||||
new JSONObjectCollection($objectCollection);
|
||||
} else {
|
||||
$serializer = ($doesAcceptRawICS === true) ?
|
||||
new ICSObject($object) :
|
||||
new JSONObject($object);
|
||||
}
|
||||
$serializer = new Serializer(Serializer::Object, $object, $this->accept());
|
||||
|
||||
return new JSONResponse($serializer);
|
||||
return new Response($serializer);
|
||||
} catch (BusinessLayerException $ex) {
|
||||
$this->app->log($ex->getMessage(), 'warn');
|
||||
return new JSONResponse(null, HTTP::STATUS_BAD_REQUEST);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Controller;
|
||||
|
||||
use \OCP\AppFramework\Http;
|
||||
|
||||
use \OCA\Calendar\Db\DoesNotExistException;
|
||||
use \OCA\Calendar\BusinessLayer\BusinessLayerException;
|
||||
|
||||
use \OCA\Calendar\Http\Response;
|
||||
|
||||
use \OCA\Calendar\Http\Reader;
|
||||
use \OCA\Calendar\Http\Serializer;
|
||||
use \OCA\Calendar\Http\ReaderExpcetion;
|
||||
use \OCA\Calendar\Http\SerializerException;
|
||||
|
||||
class SubscriptionController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function index() {}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function show() {}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function create() {}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function update() {}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function destroy() {}
|
||||
}
|
|
@ -45,6 +45,13 @@ class Calendar extends Entity {
|
|||
$this->addType('enabled', 'boolean');
|
||||
$this->addType('cruds', 'integer');
|
||||
|
||||
//fillup default values
|
||||
$this->setCtag(0);
|
||||
$this->setTimezone(new Timezone('UTC'));
|
||||
$this->setColor('#FFFFFF');
|
||||
$this->setOrder(0);
|
||||
$this->setEnabled(true);
|
||||
|
||||
//create from array
|
||||
if(is_array($createFrom)){
|
||||
$this->fromRow($createFrom);
|
||||
|
@ -260,4 +267,12 @@ class Calendar extends Entity {
|
|||
public function __toString() {
|
||||
return $this->userId . '::' . $this->getCalendarId();
|
||||
}
|
||||
|
||||
public function doesAllow($cruds) {
|
||||
return ($this->cruds & $cruds);
|
||||
}
|
||||
|
||||
public function doesSupport($components) {
|
||||
return ($this->components & $components);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,16 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Db;
|
||||
|
||||
use \OCA\Calendar\Sabre\VObject\Component\VCalendar;
|
||||
use \OCA\Calendar\Sabre\VObject\Reader;
|
||||
use \OCA\Calendar\Sabre\VObject\ParseException;
|
||||
use \OCA\Calendar\Sabre\VObject\EofException;
|
||||
|
||||
use \OCA\Calendar\Sabre\VObject\Component\VTimezone;
|
||||
use \OCA\Calendar\Sabre\VObject\Component\VEvent;
|
||||
use \OCA\Calendar\Sabre\VObject\Component\VJournal;
|
||||
use \OCA\Calendar\Sabre\VObject\Component\VTodo;
|
||||
|
||||
abstract class Collection {
|
||||
|
||||
protected $objects;
|
||||
|
@ -239,13 +249,18 @@ abstract class Collection {
|
|||
|
||||
foreach($this->objects as &$object) {
|
||||
$vElement = $object->getVObject();
|
||||
$children = $vElement->getChildren();
|
||||
$children = $vElement->children();
|
||||
foreach($children as $child) {
|
||||
$vObject->add($child);
|
||||
if($child instanceof VEvent ||
|
||||
$child instanceof VJournal ||
|
||||
$child instanceof VTodo ||
|
||||
$child instanceof VTimezone) {
|
||||
$vObject->add($child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $vobject;
|
||||
return $vObject;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,7 +25,7 @@ abstract class Mapper {
|
|||
* queries without using sql
|
||||
*/
|
||||
public function __construct(IAppContainer $api, $tableName){
|
||||
$this->api = $api;
|
||||
$this->app = $app;
|
||||
$this->tableName = '*PREFIX*' . $tableName;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ use \OCA\Calendar\Utility\ObjectUtility;
|
|||
use \OCA\Calendar\Utility\SabreUtility;
|
||||
use \OCA\Calendar\Utility\Utility;
|
||||
|
||||
use \OCA\Calendar\Sabre\VObject\Property\Text as TextProperty;
|
||||
use \OCA\Calendar\Sabre\VObject\Property\Integer as IntegerProperty;
|
||||
|
||||
class Object extends Entity {
|
||||
|
||||
public $id;
|
||||
|
@ -38,7 +41,7 @@ class Object extends Entity {
|
|||
* @brief init Object object with data from db row
|
||||
* @param array $fromRow
|
||||
*/
|
||||
public function __construct($fromRow=null){
|
||||
public function __construct($fromRow=null) {
|
||||
$this->addType('objectURI', 'string');
|
||||
$this->addType('etag', 'string');
|
||||
$this->addType('ruds', 'integer');
|
||||
|
@ -56,7 +59,7 @@ class Object extends Entity {
|
|||
* @param array $row the row to map onto the entity
|
||||
*/
|
||||
public function fromRow(array $row) {
|
||||
foreach($row as $key => $value){
|
||||
foreach($row as $key => $value) {
|
||||
$prop = $this->columnToProperty($key);
|
||||
if(property_exists($this, $prop)) {
|
||||
if($value !== null && array_key_exists($prop, $this->fieldTypes)){
|
||||
|
@ -80,9 +83,11 @@ class Object extends Entity {
|
|||
*/
|
||||
public function setCalendarData($data) {
|
||||
try {
|
||||
$this->vobject = Reader::read($data);
|
||||
$this->objectName = SabreUtility::getObjectName($this->vobject);
|
||||
} catch(/* some */Exception $ex) {
|
||||
$vobject = Reader::read($data);
|
||||
$this->fromVObject($vobject);
|
||||
} catch(ParseException $ex) {
|
||||
|
||||
} catch(EofException $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +129,7 @@ class Object extends Entity {
|
|||
throw new MultipleObjectsReturnedException($msg);
|
||||
}
|
||||
|
||||
|
||||
$this->vobject = $vcalendar;
|
||||
$this->objectName = SabreUtility::getObjectName($vcalendar);
|
||||
}
|
||||
|
@ -133,6 +139,23 @@ class Object extends Entity {
|
|||
* @return \Sabre\VObject\Component\VCalendar object
|
||||
*/
|
||||
public function getVObject() {
|
||||
$objectName = $this->objectName;
|
||||
if(!isset($this->vobject->{$objectName}->{'X-OC-URI'})) {
|
||||
$uri = new TextProperty($this->vobject, 'X-OC-URI', $this->objectURI);
|
||||
$this->vobject->{$objectName}->add($uri);
|
||||
}
|
||||
if(!isset($this->vobject->{$objectName}->{'X-OC-ETAG'})) {
|
||||
if($this->etag === null) {
|
||||
$this->generateEtag();
|
||||
}
|
||||
$etag = new TextProperty($this->vobject, 'X-OC-ETAG', $this->etag);
|
||||
$this->vobject->{$objectName}->add($etag);
|
||||
}
|
||||
if(!isset($this->vobject->{$objectName}->{'X-OC-RUDS'})) {
|
||||
$ruds = new IntegerProperty($this->vobject, 'X-OC-RUDS', $this->ruds);
|
||||
$this->vobject->{$objectName}->add($ruds);
|
||||
}
|
||||
|
||||
return $this->vobject;
|
||||
}
|
||||
|
||||
|
@ -165,8 +188,7 @@ class Object extends Entity {
|
|||
* @brief update Etag
|
||||
*/
|
||||
public function generateEtag() {
|
||||
$etag = $this->getCalendarId();
|
||||
$etag .= $this->getObjectURI();
|
||||
$etag = $this->getObjectURI();
|
||||
$etag .= $this->getCalendarData();
|
||||
|
||||
$this->etag = md5($etag);
|
||||
|
@ -185,19 +207,8 @@ class Object extends Entity {
|
|||
* @return DateTime
|
||||
*/
|
||||
public function getStartDate() {
|
||||
//TODO - USE UTILITY!!
|
||||
//If recurrenceId is set, that's the actual start
|
||||
//DTSTART has the value of the first object of recurring events
|
||||
//This doesn't make any sense, but that's how it is in the standard
|
||||
if(isset($this->vobject->{$objectName}->{'RECURRENCE-ID'})) {
|
||||
return $this->vobject->{$objectName}->{'RECURRENCE-ID'}->getDateTime();
|
||||
}
|
||||
|
||||
if(isset($this->vobject->{$objectName}->{'DTSTART'})) {
|
||||
return $this->vobject->{$objectName}->{'DTSTART'}->getDateTime();
|
||||
}
|
||||
|
||||
return null;
|
||||
$objectName = $this->objectName;
|
||||
return SabreUtility::getDTStart($this->vobject->{$objectName});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,15 +217,7 @@ class Object extends Entity {
|
|||
*/
|
||||
public function getEndDate() {
|
||||
$objectName = $this->objectName;
|
||||
|
||||
if(isset($this->vobject->{$objectName}->{'DTEND'})) {
|
||||
return $this->vobject->{$objectName}->{'DTEND'}->getDateTime();
|
||||
} elseif(isset($this->vobject->{$objectName}->{'DURATION'})) {
|
||||
$dtend = SabreUtility::getDTEnd($this->vobject->{$objectName});
|
||||
return $dtend->getDateTime();
|
||||
} else {
|
||||
return $this->getStartDate();
|
||||
}
|
||||
return SabreUtility::getDTEnd($this->vobject->{$objectName});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -293,8 +296,8 @@ class Object extends Entity {
|
|||
} else {
|
||||
if($this->calendar instanceof Calendar) {
|
||||
$cruds = $this->calendar->getCruds();
|
||||
if($cruds & Permission::CREATE) {
|
||||
$cruds -= Permission::CREATE;
|
||||
if($cruds & Permissions::CREATE) {
|
||||
$cruds -= Permissions::CREATE;
|
||||
}
|
||||
return $cruds;
|
||||
}
|
||||
|
@ -302,6 +305,14 @@ class Object extends Entity {
|
|||
}
|
||||
}
|
||||
|
||||
public function setRuds($ruds) {
|
||||
if($ruds & Permissions::CREATE) {
|
||||
$ruds -= Permissions::CREATE;
|
||||
}
|
||||
|
||||
$this->ruds = $ruds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get last modified of object
|
||||
* @return DateTime
|
||||
|
@ -343,4 +354,8 @@ class Object extends Entity {
|
|||
$isVObjectValid = $this->vobject->validate();
|
||||
//TODO - finish implementation
|
||||
}
|
||||
|
||||
private function iterateOverObjects() {
|
||||
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@ class ObjectMapper extends Mapper {
|
|||
/**
|
||||
* @param API $api: Instance of the API abstraction layer
|
||||
*/
|
||||
public function __construct($api, $tablename = 'clndr_objcache'){
|
||||
parent::__construct($api, $tablename);
|
||||
public function __construct($app, $tablename = 'clndr_objcache'){
|
||||
parent::__construct($app, $tablename);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,4 +14,7 @@ class Permissions {
|
|||
const DELETE = 8;
|
||||
const SHARE = 16;
|
||||
const ALL = 31;
|
||||
|
||||
const ALL_CALENDAR = 31;
|
||||
const ALL_OBJECT = 27;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
interface IReader {
|
||||
|
||||
/**
|
||||
* @brief get object
|
||||
* @return mixed (\OCA\Calendar\Db\Entity|\OCA\Calendar\Db\Collection)
|
||||
*/
|
||||
public function getObject();
|
||||
|
||||
/**
|
||||
* @brief is object a collection
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCollection();
|
||||
|
||||
/**
|
||||
* @brief parse data
|
||||
*/
|
||||
public function parse();
|
||||
|
||||
/**
|
||||
* @brief set data
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function setData($data);
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
interface IResponse {
|
||||
|
||||
public function getMimeType();
|
||||
|
||||
public function serialize();
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
interface ISerializer {
|
||||
|
||||
/**
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders();
|
||||
|
||||
/**
|
||||
* @brief get serialized data
|
||||
* @return string
|
||||
*/
|
||||
public function serialize($convenience);
|
||||
|
||||
/**
|
||||
* @brief set object
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function setObject($object);
|
||||
|
||||
}
|
|
@ -4,45 +4,11 @@
|
|||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
* Example output:
|
||||
* ```json
|
||||
* {
|
||||
* "displayname" : "Work",
|
||||
* "calendarURI" : "local-work",
|
||||
* "owner" : {
|
||||
* "userid" : "developer42",
|
||||
* "displayname" : "developer42"
|
||||
* },
|
||||
* "ctag" : 0,
|
||||
* "url" : "https://owncloud/index.php/apps/calendar/calendars/local-work",
|
||||
* "color" : "#000000",
|
||||
* "order" : 0,
|
||||
* "enabled" : true,
|
||||
* "components" : {
|
||||
* "vevent" : true,
|
||||
* "vjournal" : false,
|
||||
* "vtodo" : true
|
||||
* },
|
||||
* "timezone" : {}, //see JSONTIMEZONE
|
||||
* "user" : {
|
||||
* "userid" : "developer42",
|
||||
* "displayname" : "developer42"
|
||||
* },
|
||||
* "cruds" : {
|
||||
* "create" : true,
|
||||
* "update" : true,
|
||||
* "delete" : true,
|
||||
* "code" : 31,
|
||||
* "read" : true,
|
||||
* "share" : true
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
use \OCA\Calendar\Db\Calendar;
|
||||
|
||||
use \OCA\Calendar\Db\ObjectType;
|
||||
use \OCA\Calendar\Db\Permissions;
|
||||
|
||||
|
@ -54,13 +20,22 @@ class JSONCalendar extends JSON {
|
|||
private $jsonArray;
|
||||
|
||||
/**
|
||||
* @brief get mimetype of serialized output
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getMimeType() {
|
||||
return 'application/json';
|
||||
public function getHeaders() {
|
||||
return array_merge(
|
||||
parent::getHeaders(),
|
||||
array(
|
||||
'Content-type' => 'application/json; charset=utf-8',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief get json-encoded string containing all information
|
||||
* @return array
|
||||
*/
|
||||
public function serialize($convenience=true) {
|
||||
$this->jsonArray = array();
|
||||
|
||||
|
@ -75,6 +50,8 @@ class JSONCalendar extends JSON {
|
|||
case 'color':
|
||||
case 'displayname':
|
||||
case 'timezone':
|
||||
case 'backend':
|
||||
case 'uri':
|
||||
$this->jsonArray[$key] = (string) $value;
|
||||
break;
|
||||
|
||||
|
@ -103,8 +80,6 @@ class JSONCalendar extends JSON {
|
|||
|
||||
//blacklist
|
||||
case 'id':
|
||||
case 'backend':
|
||||
case 'uri':
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -114,34 +89,26 @@ class JSONCalendar extends JSON {
|
|||
}
|
||||
}
|
||||
|
||||
$this->setCalendarURI();
|
||||
$this->setCalendarURL();
|
||||
$this->setCalDAVURL();
|
||||
|
||||
return $this->jsonArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set public calendar uri
|
||||
*/
|
||||
private function setCalendarURI() {
|
||||
$backend = $this->object->getBackend();
|
||||
$calendarURI = $this->object->getUri();
|
||||
|
||||
$calendarURI = CalendarUtility::getURI($backend, $calendarURI);
|
||||
|
||||
$this->jsonArray['calendarURI'] = $calendarURI;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set api url to calendar
|
||||
*/
|
||||
private function setCalendarURL() {
|
||||
$calendarURI = $this->jsonArray['calendarURI'];
|
||||
|
||||
//TODO - fix me
|
||||
//$calendarURL = JSONUtility::getURL($calendarURI);
|
||||
$calendarURL = '';
|
||||
$calendarURI = CalendarUtility::getURI($this->object->getBackend(), $this->object->getUri());
|
||||
|
||||
$calendarURL = JSONUtility::getURL($calendarURI);
|
||||
$this->jsonArray['url'] = $calendarURL;
|
||||
}
|
||||
|
||||
private function setCalDAVURL() {
|
||||
$calendarURI = CalendarUtility::getURI($this->object->getBackend(), $this->object->getUri());
|
||||
|
||||
$calDAVURL = JSONUtility::getCalDAV($calendarURI);
|
||||
$this->jsonArray['caldav'] = $calDAVURL;
|
||||
}
|
||||
}
|
|
@ -12,27 +12,34 @@ use \OCA\Calendar\Db\Calendar;
|
|||
class JSONCalendarCollection extends JSONCollection {
|
||||
|
||||
/**
|
||||
* @brief get mimetype of serialized output
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getMimeType() {
|
||||
return 'application/json';
|
||||
public function getHeaders() {
|
||||
return array_merge(
|
||||
parent::getHeaders(),
|
||||
array(
|
||||
'Content-type' => 'application/json; charset=utf-8',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief get json-encoded string containing all information
|
||||
* @return array
|
||||
*/
|
||||
public function serialize() {
|
||||
public function serialize($convenience=true) {
|
||||
$jsonArray = array();
|
||||
|
||||
$this->object->iterate(function(&$object) use (&$jsonArray) {
|
||||
$this->object->iterate(function(&$object) use (&$jsonArray, $convenience) {
|
||||
try {
|
||||
if($object instanceof Calendar) {
|
||||
$jsonCalendar = new JSONCalendar($object);
|
||||
$jsonArray[] = $jsonCalendar->serialize();
|
||||
$jsonCalendar = new JSONCalendar();
|
||||
$jsonCalendar->setObject($object);
|
||||
$jsonArray[] = $jsonCalendar->serialize($convenience);
|
||||
}
|
||||
if($object instanceof JSONCalendar) {
|
||||
$jsonArray[] = $object->serialize();
|
||||
$jsonArray[] = $object->serialize($convenience);
|
||||
}
|
||||
} catch (JSONException $ex) {
|
||||
//TODO - log error msg
|
||||
|
|
|
@ -20,48 +20,42 @@ class JSONCalendarReader extends JSONReader{
|
|||
* @brief parse jsoncalendar
|
||||
*/
|
||||
public function parse() {
|
||||
try{
|
||||
$data = $this->getData();
|
||||
$isCollection = false;
|
||||
$data = $this->getData();
|
||||
$isCollection = $this->isDataACollection();
|
||||
|
||||
if(array_key_exists(0, $data) === true && is_array($data[0]) === true) {
|
||||
$isCollection = true;
|
||||
}
|
||||
if($isCollection) {
|
||||
$collection = new CalendarCollection();
|
||||
|
||||
if($isCollection === false) {
|
||||
foreach($data as $singleEntity) {
|
||||
try {
|
||||
$object = $this->parseSingleEntry($data);
|
||||
$this->setObject($object);
|
||||
} catch(/* some */Exception $ex) {
|
||||
//TODO - log error msg
|
||||
return;
|
||||
$calendar = $this->parseJSONCalendar($singleEntity);
|
||||
$collection->add($calendar);
|
||||
} catch(JSONReaderException $ex) {
|
||||
//TODO - log error message
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$collection = new CalendarCollection();
|
||||
|
||||
foreach($data as $entry) {
|
||||
try {
|
||||
$object = $this->parseSingleEntry($data);
|
||||
$collection->add($object);
|
||||
} catch(/* some */Exception $ex) {
|
||||
//TODO - log some error msg
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setObject($collection);
|
||||
}
|
||||
} catch(Exception $ex /* What exception is being thrown??? */) {
|
||||
throw new JSONCalendarReaderException($ex->getMessage());
|
||||
|
||||
$this->setObject($collection);
|
||||
} else {
|
||||
try {
|
||||
$calendar = $this->parseJSONCalendar($data);
|
||||
$this->setObject($calendar);
|
||||
} catch(JSONReaderException $ex) {
|
||||
//TODO - log error message
|
||||
return;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief overwrite values that should not be set by user with null
|
||||
*/
|
||||
public function sanitize() {
|
||||
//make sure object exists
|
||||
$this->getObject();
|
||||
if($this->object === null) {
|
||||
$this->parse();
|
||||
}
|
||||
|
||||
$sanitize = array(
|
||||
'userId',
|
||||
|
@ -74,45 +68,70 @@ class JSONCalendarReader extends JSONReader{
|
|||
return $this;
|
||||
}
|
||||
|
||||
private function parseSingleEntry($data) {
|
||||
/**
|
||||
* @brief check if $this->data is a collection
|
||||
* @return boolean
|
||||
*/
|
||||
private function isDataACollection() {
|
||||
$data = $this->data;
|
||||
|
||||
if(array_key_exists(0, $data) && is_array($data[0])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parse a single json calendar
|
||||
* @return \OCA\Calendar\Db\Calendar
|
||||
*/
|
||||
private function parseJSONCalendar($data) {
|
||||
$calendar = new Calendar();
|
||||
|
||||
foreach($data as $key => $value) {
|
||||
$propertySetter = 'set' . ucfirst($key);
|
||||
$setter = 'set' . ucfirst($key);
|
||||
|
||||
switch($key) {
|
||||
case 'color':
|
||||
case 'displayname':
|
||||
case 'timezone':
|
||||
$calendar->{$propertySetter}((string) $value);
|
||||
case 'backend':
|
||||
case 'uri':
|
||||
//case 'timezone':
|
||||
$value = strval($value);
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'ctag':
|
||||
case 'order':
|
||||
$calendar->{$propertySetter}((int) $value);
|
||||
$value = intval($value);
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'enabled':
|
||||
$calendar->{$propertySetter}((bool) $value);
|
||||
//$value = boolval($value); boolval is PHP >= 5.5 only
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'components':
|
||||
$calendar->{$propertySetter}(JSONUtility::parseComponents($value));
|
||||
$value = JSONUtility::parseComponents($value);
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'cruds':
|
||||
$calendar->{$propertySetter}(JSONUtility::parseCruds($value));
|
||||
$value = JSONUtility::parseCruds($value);
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'owner':
|
||||
case 'user':
|
||||
$propertySetter .= 'Id';
|
||||
$calendar->{$propertySetter}(JSONUtility::parseUserInformation($value));
|
||||
$value = JSONUtility::parseUserInformation($value);
|
||||
$calendar->$setter($value);
|
||||
break;
|
||||
|
||||
case 'calendarURI':
|
||||
$calendar->setBackend(JSONUtility::parseCalendarURIForBackend($value));
|
||||
$calendar->setUri(JSONUtility::parseCalendarURIForURI($value));
|
||||
$this->setCalendarURI($value);
|
||||
break;
|
||||
|
||||
//blacklist:
|
||||
case 'url':
|
||||
|
@ -125,6 +144,8 @@ class JSONCalendarReader extends JSONReader{
|
|||
|
||||
return $calendar;
|
||||
}
|
||||
}
|
||||
|
||||
class JSONCalendarReaderException extends \Exception{}
|
||||
private function setCalendarURI($calendarURI) {
|
||||
//Todo - check
|
||||
}
|
||||
}
|
|
@ -8,43 +8,45 @@
|
|||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
use \OCA\Calendar\Db\Entity;
|
||||
use \OCA\Calendar\Http\IResponse;
|
||||
|
||||
abstract class JSON implements IResponse {
|
||||
use \OCA\Calendar\Http\Serializer;
|
||||
use \OCA\Calendar\Http\ISerializer;
|
||||
|
||||
abstract class JSON implements ISerializer {
|
||||
|
||||
protected $object;
|
||||
protected $vobject;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
public function __construct(Entity $object) {
|
||||
$this->object = $object;
|
||||
try {
|
||||
$this->vobject = $object->getVObject();
|
||||
} catch(/* some */Exception $ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get object JSONObject was initialized with.
|
||||
*/
|
||||
protected function getObject() {
|
||||
public function getObject() {
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get mimetype of serialized output
|
||||
* @brief set object
|
||||
* @param Entity $object
|
||||
*/
|
||||
public function getMimeType() {
|
||||
return 'application/calendar+json';
|
||||
public function setObject($object) {
|
||||
if($object instanceof Entity) {
|
||||
$this->object = $object;
|
||||
return $this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return array(
|
||||
'X-Content-Type-Options' => 'nosniff',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get json-encoded string containing all information
|
||||
*/
|
||||
abstract public function serialize();
|
||||
}
|
||||
|
||||
class JSONException extends \Exception {}
|
||||
abstract public function serialize($convenience=true);
|
||||
}
|
|
@ -13,9 +13,14 @@ use \OCA\Calendar\Http\IResponse;
|
|||
abstract class JSONCollection extends JSON {
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @brief set object
|
||||
* @param Collection $object
|
||||
*/
|
||||
public function __construct(Collection $object) {
|
||||
$this->object = $object;
|
||||
public function setObject($object) {
|
||||
if($object instanceof Collection) {
|
||||
$this->object = $object;
|
||||
return $this;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -7,9 +7,12 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
use \OCA\Calendar\Db\Entity;
|
||||
use \OCA\Calendar\Db\Collection;
|
||||
|
||||
abstract class JSONReader {
|
||||
use \OCA\Calendar\Http\IReader;
|
||||
|
||||
abstract class JSONReader implements IReader {
|
||||
|
||||
protected $data;
|
||||
protected $object;
|
||||
|
@ -35,6 +38,7 @@ abstract class JSONReader {
|
|||
* @brief set data
|
||||
*/
|
||||
public function setData($json) {
|
||||
//reset object
|
||||
$this->object = null;
|
||||
|
||||
if(is_array($json)) {
|
||||
|
@ -129,4 +133,4 @@ abstract class JSONReader {
|
|||
abstract public function parse();
|
||||
}
|
||||
|
||||
class JSONReaderException extends Exception {}
|
||||
class JSONReaderException extends \Exception {}
|
|
@ -7,10 +7,26 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
use \OCA\Calendar\Utility\JSONUtility;
|
||||
|
||||
class JSONObject extends JSON {
|
||||
|
||||
/**
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return array_merge(
|
||||
parent::getHeaders(),
|
||||
array(
|
||||
'Content-type' => 'application/calendar+json; charset=utf-8',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get json-encoded string containing all information
|
||||
* @return array
|
||||
*/
|
||||
public function serialize($convenience=true) {
|
||||
$vcalendar = $this->object->getVObject();
|
||||
|
|
|
@ -7,9 +7,38 @@
|
|||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
class JSONObjectCollection extends JSONObject {
|
||||
class JSONObjectCollection extends JSONCollection {
|
||||
|
||||
public function extend(\DateTime $start, \DateTime $end) {
|
||||
$this->vobject->extend($start, $end);
|
||||
/**
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return array_merge(
|
||||
parent::getHeaders(),
|
||||
array(
|
||||
'Content-type' => 'application/calendar+json; charset=utf-8',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get json-encoded string containing all information
|
||||
* @return mixed (null|array)
|
||||
*/
|
||||
public function serialize($convenience=true) {
|
||||
//if the collection does not contain any object,
|
||||
//return the http 204 no content status code
|
||||
if($this->object->count() === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$vcalendar = $this->object->getVObject();
|
||||
|
||||
if($convenience === true) {
|
||||
//JSONUtility::addConvenience($vcalendar);
|
||||
}
|
||||
|
||||
return $vcalendar->jsonSerialize();
|
||||
}
|
||||
}
|
|
@ -14,49 +14,28 @@ use OCA\Calendar\VObject\Splitter\ICalendar;
|
|||
|
||||
class JSONObjectReader {
|
||||
|
||||
/**
|
||||
* @brief parse json object
|
||||
*/
|
||||
public function parse() {
|
||||
try {
|
||||
$this->fixData();
|
||||
$data = $this->getData();
|
||||
|
||||
$stream = fopen('php://memory','r+');
|
||||
fwrite($stream, $this->getData());
|
||||
rewind($stream);
|
||||
$vcalendar = Reader::readJson($data);
|
||||
$uniqueUIDs = SabreUtility::countUniqueUIDs($vcalendar);
|
||||
$isCollection = ($uniqueUIDs !== 1);
|
||||
|
||||
//TODO - does the vobject splitter support json-encoded calendar data???????
|
||||
$vcalendar = new ICalendar($stream);
|
||||
|
||||
$objectCollection = new ObjectCollection();
|
||||
|
||||
while($vobject = $vcalendar->next()) {
|
||||
$object = new Object();
|
||||
$object->fromVObject($vcalendar);
|
||||
$objectCollection->add($object);
|
||||
}
|
||||
|
||||
if($objectCollection->count() === 1) {
|
||||
$this->setObject($objectCollection->reset()->current());
|
||||
if($isCollection) {
|
||||
$singleObjects = SabreUtility::splitByUID($vcalendar);
|
||||
$collection = new ObjectCollection($singleObjects);
|
||||
$this->setObject($collection);
|
||||
} else {
|
||||
$this->setObject($objectCollection);
|
||||
$object = new Object($vcalendar);
|
||||
$this->setObject($object);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} catch(/* some */Exception $e) {
|
||||
throw new JSONObjectReaderException($ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function fixData() {
|
||||
$data = $this->getData();
|
||||
|
||||
//fix malformed timestamp in some google calendar events
|
||||
//originally contributed by nezzi@github
|
||||
//TODO - convert to json representation of created
|
||||
$data = str_replace('CREATED:00001231T000000Z', 'CREATED:19700101T000000Z', $data);
|
||||
|
||||
//add some more fixes over time
|
||||
|
||||
$this->setData($data);
|
||||
}
|
||||
}
|
||||
|
||||
class JSONObjectReaderException extends Exception{}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
class JSONTimezone extends JSONObject {}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
class JSONTimezoneCollection extends JSONTimezone {}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http\JSON;
|
||||
|
||||
use OCA\Calendar\Db\Object;
|
||||
use OCA\Calendar\Db\ObjectCollection;
|
||||
|
||||
class JSONTimezoneReader {
|
||||
|
||||
/**
|
||||
* @brief parse json object
|
||||
*/
|
||||
public function parse() {
|
||||
try {
|
||||
$data = $this->getData();
|
||||
|
||||
$vcalendar = Reader::readJson($data);
|
||||
$numberTimezones = SabreUtility::countTimezones($vcalendar);
|
||||
$isCollection = ($numberTimezones > 1);
|
||||
|
||||
if($isCollection) {
|
||||
$object = new TimezoneCollection($vcalendar);
|
||||
} else {
|
||||
$object = new Timezone($vcalendar);
|
||||
}
|
||||
|
||||
$this->setObject($object);
|
||||
|
||||
return $this;
|
||||
} catch(/* some */Exception $e) {
|
||||
throw new JSONObjectReaderException($ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
use \OCP\AppFramework\Http\Response;
|
||||
use \OCP\AppFramework\Http;
|
||||
use \OCA\Calendar\Http\IResponse;
|
||||
|
||||
class JSONResponse extends Response {
|
||||
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @param array|object $data the object or array that should be transformed
|
||||
* @param int $statusCode the Http status code, defaults to 200
|
||||
*/
|
||||
public function __construct(&$data=null, $statusCode=null) {
|
||||
$this->data = $data;
|
||||
|
||||
if($statusCode === null) {
|
||||
if($data instanceof IResponse) {
|
||||
$statusCode = Http::STATUS_OK;
|
||||
} else {
|
||||
$statusCode = Http::STATUS_NO_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setStatus($statusCode);
|
||||
$this->addHeader('X-Content-Type-Options', 'nosniff');
|
||||
$this->addHeader('Content-type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendered json
|
||||
* @return string the rendered json
|
||||
*/
|
||||
public function render(){
|
||||
if($this->data instanceof IResponse) {
|
||||
$data = $this->data->serialize();
|
||||
|
||||
if(is_array($data)) {
|
||||
return json_encode($data);
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
abstract class Manager {
|
||||
|
||||
protected static $all=array();
|
||||
private static $fallback=array();
|
||||
|
||||
/**
|
||||
* @brief get
|
||||
* @param integer $type
|
||||
* @param string $requestedMimeType
|
||||
* @return mixed (boolean|string)
|
||||
*/
|
||||
public static function get($type, $requestedMimeType) {
|
||||
if(!array_key_exists($type, self::$all)) {
|
||||
return false;
|
||||
}
|
||||
if(!array_key_exists($requestedMimeType, self::$all[$type])) {
|
||||
return false;
|
||||
}
|
||||
return self::$all[$type][$requestedMimeType];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set
|
||||
* @param integer $type
|
||||
* @param string $class
|
||||
* @param string $requestedMimeType
|
||||
* @param boolean $overwrite
|
||||
* @return boolean
|
||||
*/
|
||||
public static function set($type, $class, $requestedMimeType, $overwrite=false) {
|
||||
if($overwrite === false && self::get($type, $requestedMimeType) !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self::$all[$type][$requestedMimeType] = $class;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief getFallback
|
||||
* @param integer $type
|
||||
* @return mixed (boolean|string)
|
||||
*/
|
||||
public static function getFallback($type) {
|
||||
if(!array_key_exists($type, self::$fallback)) {
|
||||
return false;
|
||||
}
|
||||
return self::$fallback[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setFallback
|
||||
* @param integer $type
|
||||
* @param string $class
|
||||
* @return mixed (boolean|string)
|
||||
*/
|
||||
public static function setFallback($type, $class) {
|
||||
self::$fallback[$type] = $class;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
class Reader extends Manager implements IReader {
|
||||
|
||||
const Calendar = 7;
|
||||
const Object = 8;
|
||||
const Timezone = 9;
|
||||
|
||||
private $reader;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param integer $type
|
||||
* @param mixed $data
|
||||
* @param string $requestedMimeType
|
||||
*/
|
||||
public function __construct($type, $data, $requestedMimeType) {
|
||||
$class = self::get($type, $requestedMimeType);
|
||||
if(!$class) {
|
||||
throw new \Exception('No reader found.');
|
||||
}
|
||||
|
||||
$this->reader = new $class();
|
||||
$this->reader->setData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get object
|
||||
* @return mixed (\OCA\Calendar\Db\Entity|\OCA\Calendar\Db\Collection)
|
||||
*/
|
||||
public function getObject() {
|
||||
return $this->reader->getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief is object a collection
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCollection() {
|
||||
return $this->reader->isCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parse data
|
||||
*/
|
||||
public function parse() {
|
||||
$this->reader->parse();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set data
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function setData($data) {
|
||||
$this->reader->setData($data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function sanitize() {
|
||||
$this->reader->sanitize();
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
Reader::set(Reader::Calendar, 'OCA\\Calendar\\Http\\JSON\\JSONCalendarReader', 'application/json');
|
||||
Reader::set(Reader::Calendar, 'OCA\\Calendar\\Http\\JSON\\JSONCalendarReader', 'application/calendar+json');
|
||||
Reader::set(Reader::Object, 'OCA\\Calendar\\Http\\JSON\\JSONObjectReader', 'application/json');
|
||||
Reader::set(Reader::Object, 'OCA\\Calendar\\Http\\JSON\\JSONObjectReader', 'application/calendar+json');
|
||||
Reader::set(Reader::Timezone, 'OCA\\Calendar\\Http\\JSON\\JSONTimezoneReader', 'application/json');
|
||||
Reader::set(Reader::Timezone, 'OCA\\Calendar\\Http\\JSON\\JSONTimezoneReader', 'application/calendar+json');
|
||||
|
||||
Reader::set(Reader::Calendar, 'OCA\\Calendar\\Http\\ICS\\ICSCalendarReader', 'text/calendar');
|
||||
Reader::set(Reader::Object, 'OCA\\Calendar\\Http\\ICS\\ICSObjectReader', 'text/calendar');
|
||||
Reader::set(Reader::Timezone, 'OCA\\Calendar\\Http\\ICS\\ICSTimezoneReader', 'text/calendar');
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
use \OCP\AppFramework\Http\Response as CoreResponse;
|
||||
use \OCP\AppFramework\Http;
|
||||
use \OCA\Calendar\Http\ISerializer;
|
||||
|
||||
class Response extends CoreResponse {
|
||||
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @param int $statusCode
|
||||
*/
|
||||
public function __construct($data=null, $statusCode=null) {
|
||||
$this->data = $data;
|
||||
|
||||
if($statusCode === null) {
|
||||
if($data === null) {
|
||||
$statusCode = Http::STATUS_NO_CONTENT;
|
||||
} else {
|
||||
$statusCode = Http::STATUS_OK;
|
||||
}
|
||||
}
|
||||
$this->setStatus($statusCode);
|
||||
|
||||
if($data instanceof ISerializer) {
|
||||
$headers = $data->getHeaders();
|
||||
foreach($headers as $key => $value) {
|
||||
$this->addHeader($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendered data
|
||||
* @return string the rendered data
|
||||
*/
|
||||
public function render(){
|
||||
if(is_string($this->data)) {
|
||||
return $this->data;
|
||||
} elseif(is_array($this->data)) {
|
||||
return json_encode($this->data);
|
||||
} elseif($this->data instanceof ISerializer) {
|
||||
$data = $this->data->serialize();
|
||||
|
||||
if(is_null($data)) {
|
||||
$this->setStatus(Http::STATUS_NO_CONTENT);
|
||||
return '';
|
||||
}else if(is_array($data)) {
|
||||
return json_encode($data);
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Georg Ehrke <oc.list@georgehrke.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
namespace OCA\Calendar\Http;
|
||||
|
||||
class Serializer extends Manager implements ISerializer {
|
||||
|
||||
const Calendar = 1;
|
||||
const CalendarCollection = 2;
|
||||
const Object = 3;
|
||||
const ObjectCollection = 4;
|
||||
const Timezone = 5;
|
||||
const TimezoneCollection = 6;
|
||||
|
||||
private $serializer;
|
||||
|
||||
public function __construct($type, $data, $requestedMimeType) {
|
||||
$class = self::get($type, $requestedMimeType);
|
||||
if(!$class) {
|
||||
$class = self::getFallback($type);
|
||||
}
|
||||
if(!$class) {
|
||||
throw new Exception('No serializer found.');
|
||||
}
|
||||
|
||||
$this->serializer = new $class();
|
||||
$this->serializer->setObject($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get headers for response
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
return $this->serializer->getHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get serialized data
|
||||
* @return string
|
||||
*/
|
||||
public function serialize($convenience=true) {
|
||||
return $this->serializer->serialize($convenience);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set object
|
||||
* @param mixed $object
|
||||
*/
|
||||
public function setObject($object) {
|
||||
$this->serializer->setObject($object);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
Serializer::set(Serializer::Calendar, 'OCA\\Calendar\\Http\\JSON\\JSONCalendar', 'application/json');
|
||||
Serializer::set(Serializer::Calendar, 'OCA\\Calendar\\Http\\JSON\\JSONCalendar', 'application/calendar+json');
|
||||
Serializer::set(Serializer::CalendarCollection, 'OCA\\Calendar\\Http\\JSON\\JSONCalendarCollection', 'application/json');
|
||||
Serializer::set(Serializer::CalendarCollection, 'OCA\\Calendar\\Http\\JSON\\JSONCalendarCollection', 'application/calendar+json');
|
||||
Serializer::set(Serializer::Object, 'OCA\\Calendar\\Http\\JSON\\JSONObject', 'application/json');
|
||||
Serializer::set(Serializer::Object, 'OCA\\Calendar\\Http\\JSON\\JSONObject', 'application/calendar+json');
|
||||
Serializer::set(Serializer::ObjectCollection, 'OCA\\Calendar\\Http\\JSON\\JSONObjectCollection', 'application/json');
|
||||
Serializer::set(Serializer::ObjectCollection, 'OCA\\Calendar\\Http\\JSON\\JSONObjectCollection', 'application/calendar+json');
|
||||
Serializer::set(Serializer::Timezone, 'OCA\\Calendar\\Http\\JSON\\JSONTimezone', 'application/json');
|
||||
Serializer::set(Serializer::Timezone, 'OCA\\Calendar\\Http\\JSON\\JSONTimezone', 'application/calendar+json');
|
||||
Serializer::set(Serializer::TimezoneCollection, 'OCA\\Calendar\\Http\\JSON\\JSONTimezoneCollection', 'application/json');
|
||||
Serializer::set(Serializer::TimezoneCollection, 'OCA\\Calendar\\Http\\JSON\\JSONTimezoneCollection', 'application/calendar+json');
|
||||
|
||||
Serializer::set(Serializer::Calendar, 'OCA\\Calendar\\Http\\ICS\\ICSCalendar', 'text/calendar');
|
||||
Serializer::set(Serializer::CalendarCollection, 'OCA\\Calendar\\Http\\ICS\\ICSCalendarCollection', 'text/calendar');
|
||||
Serializer::set(Serializer::Object, 'OCA\\Calendar\\Http\\ICS\\ICSObject', 'text/calendar');
|
||||
Serializer::set(Serializer::ObjectCollection, 'OCA\\Calendar\\Http\\ICS\\ICSObjectCollection', 'text/calendar');
|
||||
Serializer::set(Serializer::Timezone, 'OCA\\Calendar\\Http\\ICS\\ICSTimezone', 'text/calendar');
|
||||
Serializer::set(Serializer::TimezoneCollection, 'OCA\\Calendar\\Http\\ICS\\ICSTimezoneCollection', 'text/calendar');
|
||||
|
||||
Serializer::setFallback(Serializer::Calendar, 'OCA\\Calendar\\Http\\JSON\\JSONCalendar');
|
||||
Serializer::setFallback(Serializer::CalendarCollection, 'OCA\\Calendar\\Http\\JSON\\JSONCalendarCollection');
|
||||
Serializer::setFallback(Serializer::Object, 'OCA\\Calendar\\Http\\JSON\\JSONObject');
|
||||
Serializer::setFallback(Serializer::ObjectCollection, 'OCA\\Calendar\\Http\\JSON\\JSONObjectCollection');
|
||||
Serializer::setFallback(Serializer::Timezone, 'OCA\\Calendar\\Http\\JSON\\JSONTimezone');
|
||||
Serializer::setFallback(Serializer::TimezoneCollection, 'OCA\\Calendar\\Http\\JSON\\JSONTimezoneCollection');
|
44
lib/app.php
44
lib/app.php
|
@ -21,16 +21,20 @@ use \OCA\Calendar\BusinessLayer\ObjectBusinessLayer;
|
|||
|
||||
use \OCA\Calendar\Controller\BackendController;
|
||||
use \OCA\Calendar\Controller\CalendarController;
|
||||
use \OCA\Calendar\Controller\SubscriptionController;
|
||||
use \OCA\Calendar\Controller\ObjectController;
|
||||
use \OCA\Calendar\Controller\EventController;
|
||||
use \OCA\Calendar\Controller\JournalController;
|
||||
use \OCA\Calendar\Controller\TodoController;
|
||||
use \OCA\Calendar\Controller\TimezoneController;
|
||||
use \OCA\Calendar\Controller\SettingsController;
|
||||
use \OCA\Calendar\Controller\ViewController;
|
||||
|
||||
use \OCA\Calendar\Db\BackendMapper;
|
||||
use \OCA\Calendar\Db\CalendarMapper;
|
||||
use \OCA\Calendar\Db\SubscriptionMapper;
|
||||
use \OCA\Calendar\Db\ObjectMapper;
|
||||
use \OCA\Calendar\Db\TimezoneMapper;
|
||||
|
||||
use \OCA\Calendar\Fetcher\Fetcher;
|
||||
use \OCA\Calendar\Fetcher\CalDAVFetcher;
|
||||
|
@ -54,6 +58,14 @@ class App extends \OCP\AppFramework\App {
|
|||
return new CalendarController($c, $req, $cbl, $obl);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('SubscriptionController', function(IAppContainer $c) {
|
||||
$req = $c->query('Request');
|
||||
$smp = $c->query('SubscriptionMapper');
|
||||
|
||||
return new ViewController($c, $req, $smp);
|
||||
});
|
||||
|
||||
|
||||
$this->getContainer()->registerService('ObjectController', function(IAppContainer $c) {
|
||||
$req = $c->query('Request');
|
||||
$cbl = $c->query('CalendarBusinessLayer');
|
||||
|
@ -86,6 +98,20 @@ class App extends \OCP\AppFramework\App {
|
|||
return new TodoController($c, $req, $cbl, $obl);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('TimezoneController', function(IAppContainer $c) {
|
||||
$req = $c->query('Request');
|
||||
$tmp = $c->query('TimezoneMapper');
|
||||
|
||||
return new ViewController($c, $req, $tmp);
|
||||
});
|
||||
|
||||
|
||||
$this->getContainer()->registerService('SettingsController', function(IAppContainer $c) {
|
||||
$req = $c->query('Request');
|
||||
|
||||
return new SettingsController($c, $req);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('ViewController', function(IAppContainer $c) {
|
||||
$req = $c->query('Request');
|
||||
|
||||
|
@ -121,10 +147,18 @@ class App extends \OCP\AppFramework\App {
|
|||
return new CalendarMapper($c);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('SubscriptionMapper', function(IAppContainer $c) {
|
||||
return new SubscriptionMapper($c);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('ObjectMapper', function(IAppContainer $c) {
|
||||
return new ObjectMapper($c);
|
||||
});
|
||||
|
||||
$this->getContainer()->registerService('TimezoneMapper', function(IAppContainer $c) {
|
||||
return new TimezoneMapper($c);
|
||||
});
|
||||
|
||||
/**
|
||||
* External API
|
||||
*/
|
||||
|
@ -173,14 +207,8 @@ class App extends \OCP\AppFramework\App {
|
|||
'enabled' => true,
|
||||
),
|
||||
array (
|
||||
'backend' => 'birthday',
|
||||
'classname' => '\\OCA\\Calendar\\Backend\\Birthday',
|
||||
'arguments' => array(),
|
||||
'enabled' => true,
|
||||
),
|
||||
array (
|
||||
'backend' => 'anniversary',
|
||||
'classname' => '\\OCA\\Calendar\\Backend\\Anniversary',
|
||||
'backend' => 'contact',
|
||||
'classname' => '\\OCA\\Calendar\\Backend\\Contact',
|
||||
'arguments' => array(),
|
||||
'enabled' => true,
|
||||
),
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
*/
|
||||
namespace OCA\Calendar\SabreProperty;
|
||||
|
||||
class DateTime extends \OCA\Calendar\Sabre\VObject\Property\DateTime {
|
||||
use \OCA\Calendar\Sabre\VObject\Property;
|
||||
use \OCA\Calendar\Sabre\VObject\Parameter;
|
||||
|
||||
public function getJsonValue() {
|
||||
$array = parent::getJsonValue();
|
||||
class DateTime extends \OCA\Calendar\Sabre\VObject\Property\ICalendar\DateTime {
|
||||
|
||||
//do smth
|
||||
|
||||
return $array;
|
||||
}
|
||||
public function jsonSerialize() {
|
||||
$dateTime = $this->getDateTime();
|
||||
$this->add('X-OC-RFC8601', $dateTime->format(\DateTime::ISO8601));
|
||||
return parent::jsonSerialize();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"displayname" : "",
|
||||
"calendarURI" : "",
|
||||
"color" : "#FFFFFF",
|
||||
"order" : 0,
|
||||
"enabled" : false,
|
||||
"components" : {
|
||||
"vevent" : false,
|
||||
"vjournal" : false,
|
||||
"vtodo" : false
|
||||
'displayname' : '',
|
||||
'backend' : '',
|
||||
'uri' : '',
|
||||
'color' : '#FFFFFF',
|
||||
'order' : 0,
|
||||
'enabled' : false,
|
||||
'components' : {
|
||||
'vevent' : false,
|
||||
'vjournal' : false,
|
||||
'vtodo' : false
|
||||
},
|
||||
"timezone" : ""
|
||||
'timezone' : 'UTC'
|
||||
}
|
|
@ -9,11 +9,11 @@ namespace OCA\Calendar\Utility;
|
|||
|
||||
class CalendarUtility extends Utility{
|
||||
|
||||
const SEPERATOR = '-';
|
||||
const SEPERATOR = '::';
|
||||
|
||||
public static function suggestURI($calendarURI) {
|
||||
if(substr_count($calendarURI, '-') === 0) {
|
||||
$calendarURI . '-1';
|
||||
$calendarURI .= '-1';
|
||||
} else {
|
||||
$positionLastDash = strrpos($calendarURI, '-');
|
||||
$firstPart = substr($calendarURI, 0, strlen($calendarURI) - $positionLastDash);
|
||||
|
@ -24,16 +24,18 @@ class CalendarUtility extends Utility{
|
|||
$lastPart++;
|
||||
$calendarURI = $firstPart . '-' . $lastPart;
|
||||
} else {
|
||||
$calendarURI . '-1';
|
||||
$calendarURI .= '-1';
|
||||
}
|
||||
}
|
||||
return $calendarURI;
|
||||
}
|
||||
|
||||
public static function splitURI($publicURI) {
|
||||
if ( $publicURI === false || $publicURI === null || $publicURI === '' ) {
|
||||
if ($publicURI === false || $publicURI === null || $publicURI === '') {
|
||||
return array(false, false);
|
||||
}
|
||||
if ( substr_count($publicURI, self::SEPERATOR) === 0 ){
|
||||
|
||||
if (substr_count($publicURI, self::SEPERATOR) === 0){
|
||||
return array(false, false);
|
||||
}
|
||||
|
||||
|
@ -42,8 +44,17 @@ class CalendarUtility extends Utility{
|
|||
return array($backend, $realCalendarURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get uri from backend and calendarURI
|
||||
* @param string $backend
|
||||
* @param string $calendarURI
|
||||
* @return string uri
|
||||
*/
|
||||
public static function getURI($backend, $calendarURI) {
|
||||
return $backend . self::SEPERATOR . $calendarURI;
|
||||
return implode(self::SEPERATOR, array(
|
||||
$backend,
|
||||
$calendarURI,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -150,33 +150,37 @@ class JSONUtility extends Utility{
|
|||
'calendarId' => $calendarURI,
|
||||
);
|
||||
|
||||
$url = \OCP\Util::linkToRoute('calendar.calendars.show', $properties);
|
||||
$this->url = \OCP\Util::linkToAbsolute('', substr($url, 1));
|
||||
$url = \OCP\Util::linkToRoute('calendar.calendar.show', $properties);
|
||||
return \OCP\Util::linkToAbsolute('', substr($url, 1));
|
||||
}
|
||||
|
||||
public static function getCalDAV($calendarURI, $user) {
|
||||
$url = \OCP\Util::linkToRemote('caldav');
|
||||
$url .= urlencode($user) . '/';
|
||||
$url .= $calendarURI . '/';
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function addConvenience(&$vobject) {
|
||||
$dtstart = SabreUtility::getDTStart($vobject);
|
||||
if($dtstart !== null) {
|
||||
$vobject->{'X-OC-DTSTART'} = $dtstart->getDateTime()->format(\DateTime::ISO8601);
|
||||
}
|
||||
/*foreach($vobject as &$child) {
|
||||
if(!($child instanceof VEvent) &&
|
||||
!($child instanceof VJournal) &&
|
||||
!($child instanceof VTodo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dtend = SabreUtility::getDTEnd($vobject);
|
||||
if($dtend !== null) {
|
||||
$vobject->{'X-OC-DTEND'} = $dtend->getDateTime()->format(\DateTime::ISO8601);
|
||||
}
|
||||
|
||||
//extending SabreDAV's date and datetime jsonSerialize method would probably be easier
|
||||
//iterate over all VALARMs
|
||||
//iterate over all VTIMEZONEs
|
||||
//iterate over all FREEBUSY
|
||||
//DTSTART
|
||||
//DTEND
|
||||
//CREATED
|
||||
//DTSTAMP
|
||||
//LAST-MODIFIED
|
||||
//DUE
|
||||
//COMPLETED
|
||||
//RECCURENCE-ID
|
||||
if(isset($child->{'DTSTART'})) {
|
||||
$dtstart = SabreUtility::getDTStart($vobject);
|
||||
if($dtstart !== null) {
|
||||
$vobject->{'X-OC-DTSTART'} = $dtstart->getDateTime()->format(\DateTime::ISO8601);
|
||||
}
|
||||
|
||||
$dtend = SabreUtility::getDTEnd($vobject);
|
||||
if($dtend !== null) {
|
||||
$vobject->{'X-OC-DTEND'} = $dtend->getDateTime()->format(\DateTime::ISO8601);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public static function dropAttachements(&$vobject) {
|
||||
|
|
Loading…
Reference in New Issue