creating objects via jsonapi works now

This commit is contained in:
Georg Ehrke 2014-04-24 21:43:14 +02:00
parent 78eccf09e5
commit f799f0f044
7 changed files with 218 additions and 73 deletions

View File

@ -38,12 +38,14 @@ abstract class Backend implements IBackend {
*/
protected $app;
/**
* backend name
* @var string
*/
protected $backend;
/**
* maps action-constants to method names
* @var arrray
@ -63,6 +65,7 @@ abstract class Backend implements IBackend {
SEARCH_BY_PROPERTIES => 'searchByProperties',
);
/**
* Constructor
* @param \OCP\AppFramework\IAppContainer $api
@ -78,6 +81,7 @@ abstract class Backend implements IBackend {
$this->backend = strtolower($backend);
}
/**
* @brief get integer that represents supported actions
* @returns integer
@ -96,6 +100,7 @@ abstract class Backend implements IBackend {
return $actions;
}
/**
* @brief Check if backend implements actions
* @param string $actions
@ -110,6 +115,7 @@ abstract class Backend implements IBackend {
return (bool)($this->getSupportedActions() & $actions);
}
/**
* @brief returns whether or not a backend can be enabled
* @returns boolean
@ -121,6 +127,7 @@ abstract class Backend implements IBackend {
return true;
}
/**
* @brief returns whether or not calendar objects should be cached
* @param string $calendarURI
@ -134,6 +141,7 @@ abstract class Backend implements IBackend {
return true;
}
/**
* @brief returns information about calendar $calendarURI of the user $userId
* @param string $calendarURI
@ -146,6 +154,7 @@ abstract class Backend implements IBackend {
*/
abstract public function findCalendar($calendarURI, $userId);
/**
* @brief returns all calendars of the user $userId
* @param string $userId
@ -157,6 +166,7 @@ abstract class Backend implements IBackend {
*/
abstract public function findCalendars($userId, $limit, $offset);
/**
* @brief returns number of calendar
* @param string $userid
@ -169,6 +179,7 @@ abstract class Backend implements IBackend {
return $this->findCalendars($userId)->count();
}
/**
* @brief returns whether or not a calendar exists
* @param string $calendarURI
@ -187,6 +198,7 @@ abstract class Backend implements IBackend {
}
}
/**
* @brief returns ctag of a calendar
* @param string $calendarURI
@ -201,6 +213,7 @@ abstract class Backend implements IBackend {
$calendar = $this->findCalendar($calendarURI, $userId)->getCTag();
}
/**
* @brief returns information about the object (event/journal/todo) with the uid $objectURI in the calendar $calendarURI of the user $userId
* @param string $calendarURI
@ -215,6 +228,7 @@ abstract class Backend implements IBackend {
*/
abstract public function findObject(Calendar &$calendar, $objectURI);
/**
* @brief returns all objects in the calendar $calendarURI of the user $userId
* @param string $calendarURI
@ -227,6 +241,7 @@ abstract class Backend implements IBackend {
*/
abstract public function findObjects(Calendar &$calendar, $limit, $offset);
/**
* @brief returns number of objects in calendar
* @param string $calendarURI
@ -241,6 +256,7 @@ abstract class Backend implements IBackend {
return $this->findObjects($calendarURI, $userId)->count();
}
/**
* @brief returns whether or not an object exists
* @param string $calendarURI
@ -253,13 +269,26 @@ abstract class Backend implements IBackend {
*/
public function doesObjectExist(Calendar $calendar, $objectURI) {
try {
$this->findObject($calendarURI, $objectURI, $userId);
$this->findObject($calendar, $objectURI);
return true;
} catch (Exception $ex) {
return false;
}
}
/**
* check if object allows a certain action
* @param integer $cruds
* @param Calendar $calendar
* @param string $objectURI
* @return boolean
*/
public function doesObjectAllow($cruds, Calendar $calendar, $objectURI) {
return ($cruds & $this->findObject($calendar, $objectURI)->getRuds());
}
/**
* @brief returns etag of an object
* @param string $calendarURI
@ -273,9 +302,10 @@ abstract class Backend implements IBackend {
* This method is mandatory!
*/
public function getObjectsETag(Calendar $calendar, $objectURI) {
return $this->find($calendarURI, $objectURI, $userId)->getEtag();
return $this->find($calendar, $objectURI)->getEtag();
}
/**
* @brief returns whether or not a backend can store a calendar's color
* @returns boolean
@ -287,6 +317,7 @@ abstract class Backend implements IBackend {
return false;
}
/**
* @brief returns whether or not a backend can store a calendar's supported components
* @returns boolean
@ -298,6 +329,7 @@ abstract class Backend implements IBackend {
return false;
}
/**
* @brief returns whether or not a backend can store a calendar's displayname
* @returns boolean
@ -309,6 +341,7 @@ abstract class Backend implements IBackend {
return false;
}
/**
* @brief returns whether or not a backend can store if a calendar is enabled
* @returns boolean
@ -320,6 +353,7 @@ abstract class Backend implements IBackend {
return false;
}
/**
* @brief returns whether or not a backend can store a calendar's order
* @returns boolean

View File

@ -680,14 +680,16 @@ class Local extends Backend {
$objtbl = $this->objTableName;
$caltbl = $this->calTableName;
$sql = 'SELECT COUNT(objtbl.*) FROM `' . $objtbl . '` AS objtbl, ';
$sql = 'SELECT COUNT(objtbl.`id`) FROM `' . $objtbl . '` AS objtbl, ';
$sql .= '`' . $caltbl . '` AS caltbl ';
$sql .= 'WHERE objtbl.`calendarid` = caltbl.`id` ';
$sql .= 'AND caltbl.`uri` = ? AND caltbl.`userid` = ?';
$sql .= 'AND caltbl.`uri` = ? AND caltbl.`userid` = ? ';
$sql .= 'AND objtbl.`uri` = ?';
$result = \OCP\DB::prepare($sql)->execute(array(
$calendarURI,
$userId
$userId,
$objectURI
));
$count = $result->fetchOne();
@ -703,6 +705,18 @@ class Local extends Backend {
}
/**
* check if object allows a certain action
* @param integer $cruds
* @param Calendar $calendar
* @param string $objectURI
* @return boolean
*/
public function doesObjectAllow($cruds, Calendar $calendar, $objectURI) {
return ($cruds & Permissions::ALL);
}
/**
* get etag of an object
* @param Calendar $calendar
@ -742,19 +756,19 @@ class Local extends Backend {
$sql = 'INSERT INTO `' . $objtbl . '` ';
$sql .= '(`calendarid`,`objecttype`,`startdate`,`enddate`,';
$sql .= '`repeating`,`summary`,`calendardata`,`uri`,`lastmodified`) ';
$sql .= 'SELECT clndr.`id`, ?, ?, ?, ?, ?, ?, ?, ? ';
$sql .= 'SELECT caltbl.`id`, ?, ?, ?, ?, ?, ?, ?, ? ';
$sql .= 'FROM `' . $caltbl . '` AS caltbl ';
$sql .= 'WHERE caltbl.`userid` = ? AND caltbl.`uri` = ?';
$result = \OCP\DB::prepare($sql)->execute(array(
$object->getType(),
$object->getStartDate(),
$object->getEndDate(),
$this->getType($object->getType()),
$this->getUTCforMDB($object->getStartDate()->getDateTime()),
$this->getUTCforMDB($object->getEndDate()->getDateTime()),
$object->getRepeating(),
$object->getSummary(),
$object->getCalendarData(),
$object->getObjectURI(),
$object->getLastModified(),
$this->getUTCforMDB($object->getLastModified()),
$userId,
$calendarURI,
));

View File

@ -28,6 +28,8 @@ use \OCA\Calendar\Db\TimezoneCollection;
use \OCA\Calendar\Backend\BackendException;
use \OCA\Calendar\Backend\DoesNotImplementException;
use \OCA\Calendar\Utility\ObjectUtility;
class ObjectBusinessLayer extends BusinessLayer {
private $omp;
@ -70,7 +72,6 @@ class ObjectBusinessLayer extends BusinessLayer {
}
$api = &$this->backends->find($backend)->api;
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
if ($cacheObjects === true) {
$objects = $this->omp->findAll($calendar, $limit, $offset);
@ -113,13 +114,11 @@ class ObjectBusinessLayer extends BusinessLayer {
}
$api = &$this->backends->find($backend)->api;
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
//TODO implement
if ($cacheObjects === true) {
$number = 0;
$number = $cacheObjects->countObjects($calendar);
} else {
$number = 0;
$number = $this->omp->count($calendar);
}
//check if number is an integer, if not throw an exception
@ -135,6 +134,7 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* Find the object $objectURI of calendar $calendarId of user $userId
* @param string $calendarId global uri of calendar e.g. local-work
@ -155,7 +155,6 @@ class ObjectBusinessLayer extends BusinessLayer {
}
$api = &$this->backends->find($backend)->api;
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
if ($cacheObjects === true) {
$object = $this->omp->find($calendar, $objectURI);
@ -179,6 +178,7 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* Find the object $objectURI of type $type of calendar $calendarId of user $userId
* @param string $calendarId global uri of calendar e.g. local-work
@ -208,6 +208,7 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* Finds all objects of type $type of calendar $calendarId of user $userId
* @param string $calendarId global uri of calendar e.g. local-work
@ -266,6 +267,7 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* Finds all objects in timespan from $start to $end of calendar $calendarId of user $userId
* @param string $calendarId global uri of calendar e.g. local-work
@ -329,6 +331,7 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* Finds all objects of type $type in timeframe from $start to $end of calendar $calendarId of user $userId
* @param string $calendarId global uri of calendar e.g. local-work
@ -396,6 +399,69 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* checks if a calendar exists
* @param string $calendarId
* @param string $userId
* @param boolean $checkRemote
* @return boolean
*/
public function doesExist(Calendar &$calendar, $objectURI, $checkRemote=false) {
try {
$backend = $calendar->getBackend();
$calendarURI = $calendar->getUri();
$userId = $calendar->getUserId();
$api = &$this->backends->find($backend)->api;
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
if ($cacheObjects === true) {
$doesExist = $this->omp->doesExist($calendar, $objectURI);
if(!$checkRemote) {
return $doesExist;
}
return $api->doesObjectExist($calendar, $objectURI);
} else {
return $api->doesObjectExist($calendar, $objectURI);
}
} catch(BackendException $ex) {
throw new BusinessLayerException($ex->getMessage());
} catch(DoesNotExistException $ex) {
throw new BusinessLayerException($ex->getMessage());
}
}
/**
* checks if a calendar allows a certain action
* @param integer $cruds
* @param string $calendarId
* @param string $userId
* @return boolean
*/
public function doesAllow($cruds, Calendar &$calendar, $objectURI) {
try {
$backend = $calendar->getBackend();
$calendarURI = $calendar->getUri();
$userId = $calendar->getUserId();
$api = &$this->backends->find($backend)->api;
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
if ($cacheObjects === true) {
return $this->omp->doesAllow($cruds, $calendar, $objectURI);
} else {
return $api->doesObjectAllow($cruds, $calendar, $objectURI);
}
} catch(BackendException $ex) {
throw new BusinessLayerException($ex->getMessage());
} catch(DoesNotExistException $ex) {
throw new BusinessLayerException($ex->getMessage());
}
}
/**
* creates a new object
* @param Object $object
@ -404,8 +470,10 @@ class ObjectBusinessLayer extends BusinessLayer {
*/
public function create(Object &$object) {
try {
$backend = $object->calendar->getBackend();
$calendarURI = $object->calendar->getUri();
$calendar = $object->getCalendar();
$backend = $calendar->getBackend();
$calendarURI = $calendar->getUri();
$userId = $calendar->getUserId();
$objectURI = $object->getObjectURI();
if ($this->isBackendEnabled($backend) !== true) {
@ -414,7 +482,7 @@ class ObjectBusinessLayer extends BusinessLayer {
throw new BusinessLayerException($msg);
}
//validate that calendar exists
if ($this->doesObjectExist($calendarId, $objectURI, $userId) !== false) {
if ($this->doesExist($calendar, $objectURI) !== false) {
$msg = 'ObjectBusinessLayer::create(): User Error: ';
$msg .= 'Object already exists!';
throw new BusinessLayerException($msg);
@ -426,26 +494,19 @@ class ObjectBusinessLayer extends BusinessLayer {
}
if ($object->isValid() !== true) {
//try to fix the object
$object->fix();
//check again
if ($object->isValid() !== true) {
$msg = 'ObjectBusinessLayer::create(): User Error: ';
$msg .= 'Given object data is not valid and not fixable';
throw new BusinessLayerException($msg);
}
$msg = 'ObjectBusinessLayer::create(): User Error: ';
$msg .= 'Given object data is not valid and not fixable';
throw new BusinessLayerException($msg);
}
$api->createObject($object, $calendarURI, $objectURI, $userId);
$api = &$this->backends->find($backend)->api;
$api->createObject($object);
$cacheObjects = $api->cacheObjects($calendarURI, $userId);
if ($cacheObjects === true) {
$this->omp->insert($object, $calendarURI, $objectURI, $userId);
}
$this->calendarBusinessLayer->touch($calendarId, $userId);
return $object;
} catch(DoesNotImplementException $ex) {
throw new BusinessLayerException($ex->getMessage());
@ -454,14 +515,27 @@ class ObjectBusinessLayer extends BusinessLayer {
}
}
/**
* creates a new object from request
* @param Object $object
* @throws BusinessLayerException
* @return array containing all items
*/
public function createFromRequest(Object &$object) {
if($object->getObjectURI() === null) {
$randomURI = ObjectUtility::randomURI();
$object->setObjectURI($randomURI);
}
return $this->create($object);
}
/**
* updates an object
* @param Object $object
* @param string $calendarId global uri of calendar e.g. local-work
* @param Calendar $calendar
* @param string $objectURI UID of the object
* @param string $userId
* @throws BusinessLayerException
@ -500,8 +574,6 @@ class ObjectBusinessLayer extends BusinessLayer {
$this->omp->update($object, $calendarURI, $objectURI, $userId);
}
$this->calendarBusinessLayer->touch($calendarId, $userId);
return $object;
} catch(DoesNotImplementException $ex) {
throw new BusinessLayerException($ex->getMessage());
@ -511,6 +583,15 @@ class ObjectBusinessLayer extends BusinessLayer {
}
/**
* updates an object from request
* @param Object $object
* @param Calendar $calendar
* @param string $objectURI UID of the object
* @param string $etag
* @throws BusinessLayerException
* @return array containing all items
*/
public function updateFromRequest(Object $object, Calendar &$calendar, $objectURI, $etag) {
$oldObject = $this->find($calendar, $objectURI);
@ -523,6 +604,7 @@ class ObjectBusinessLayer extends BusinessLayer {
return $this->update($object, $calendar, $objectURI);
}
/**
* delete an object from a calendar
* @param string $calendarId global uri of calendar e.g. local-work

View File

@ -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;
@ -148,7 +148,7 @@ class ObjectController extends Controller {
if ($object instanceof Object) {
$object = $this->objectBusinessLayer->createFromRequest($object);
$serializer = new Serializer(Serializer::$object, $object, $this->accept());
$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());

View File

@ -141,23 +141,23 @@ class Object extends Entity {
*/
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-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 (!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);
$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);
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;
return $this->vObject;
}
/**
@ -168,7 +168,7 @@ class Object extends Entity {
*/
public function expand(DateTime $start, DateTime $end) {
try {
$this->vobject->expand($start, $end);
$this->vObject->expand($start, $end);
} catch(/* some */Exception $ex) {
//log debug msg;
}
@ -181,7 +181,7 @@ class Object extends Entity {
*/
public function touch() {
$now = new DateTime();
$this->vobject->{$objectName}->{'LAST-MODIFIED'}->setDateTime($now);
$this->vObject->{$objectName}->{'LAST-MODIFIED'}->setDateTime($now);
$this->generateEtag();
}
@ -209,7 +209,7 @@ class Object extends Entity {
*/
public function getStartDate() {
$objectName = $this->objectName;
return SabreUtility::getDTStart($this->vobject->{$objectName});
return SabreUtility::getDTStart($this->vObject->{$objectName});
}
/**
@ -218,7 +218,7 @@ class Object extends Entity {
*/
public function getEndDate() {
$objectName = $this->objectName;
return SabreUtility::getDTEnd($this->vobject->{$objectName});
return SabreUtility::getDTEnd($this->vObject->{$objectName});
}
/**
@ -228,9 +228,9 @@ class Object extends Entity {
public function getRepeating() {
$objectName = $this->objectName;
if (isset($this->vobject->{$objectName}->{'RRULE'}) ||
isset($this->vobject->{$objectName}->{'RDATE'}) ||
isset($this->vobject->{$objectName}->{'RECURRENCE-ID'})) {
if (isset($this->vObject->{$objectName}->{'RRULE'}) ||
isset($this->vObject->{$objectName}->{'RDATE'}) ||
isset($this->vObject->{$objectName}->{'RECURRENCE-ID'})) {
return true;
}
@ -250,8 +250,8 @@ class Object extends Entity {
$lastOccurences = array();
if (isset($this->vobject->{$objectName}->{'RRULE'})) {
$rrule = $this->vobject->{$objectName}->{'RRULE'};
if (isset($this->vObject->{$objectName}->{'RRULE'})) {
$rrule = $this->vObject->{$objectName}->{'RRULE'};
//https://github.com/fruux/sabre-vobject/wiki/Sabre-VObject-Property-Recur
$parts = $rrule->getParts();
if (!array_key_exists('COUNT', $parts) && array_key_exists('UNTIL', $parts)) {
@ -259,7 +259,7 @@ class Object extends Entity {
}
//$lastOccurences[] = DateTime of last occurence
}
if (isset($this->vobject->{$objectName}->{'RDATE'})) {
if (isset($this->vObject->{$objectName}->{'RDATE'})) {
//$lastOccurences[] = DateTime of last occurence
}
}
@ -271,8 +271,8 @@ class Object extends Entity {
public function getSummary() {
$objectName = $this->objectName;
if (isset($this->vobject->{$objectName}->{'SUMMARY'})) {
return $this->vobject->{$objectName}->{'SUMMARY'}->getValue();
if (isset($this->vObject->{$objectName}->{'SUMMARY'})) {
return $this->vObject->{$objectName}->{'SUMMARY'}->getValue();
}
return null;
@ -284,7 +284,7 @@ class Object extends Entity {
*/
public function getCalendarData() {
try {
return $this->vobject->serialize();
return $this->vObject->serialize();
} catch(/* some */Exception $ex) {
//log debug msg;
return null;
@ -321,8 +321,8 @@ class Object extends Entity {
public function getLastModified() {
$objectName = $this->objectName;
if (isset($this->vobject->{$objectName}->{'LAST-MODIFIED'})) {
return $this->vobject->{$objectName}->{'LAST-MODIFIED'}->getDateTime();
if (isset($this->vObject->{$objectName}->{'LAST-MODIFIED'})) {
return $this->vObject->{$objectName}->{'LAST-MODIFIED'}->getDateTime();
}
return null;
@ -334,10 +334,13 @@ class Object extends Entity {
*/
public function isValid() {
$strings = array(
$this->objectURI,
$this->etag,
$this->objectURI
);
if($this->etag !== null) {
$strings[] = $this->etag;
}
foreach($strings as $string) {
if (is_string($string) === false) {
return false;
@ -351,8 +354,8 @@ class Object extends Entity {
return false;
}
$isVObjectValid = $this->vobject->validate();
return true;
$isVObjectValid = $this->vObject->validate();
//TODO - finish implementation
}

View File

@ -7,12 +7,19 @@
*/
namespace OCA\Calendar\Http\JSON;
use OCA\Calendar\Db\Object;
use OCA\Calendar\Db\ObjectCollection;
require_once(__DIR__ . '/../../3rdparty/VObject/includes.php');
use OCA\Calendar\VObject\Splitter\ICalendar;
use \OCA\Calendar\Db\Object;
use \OCA\Calendar\Db\ObjectCollection;
class JSONObjectReader {
use \OCA\Calendar\VObject\Splitter\ICalendar;
use \OCA\Calendar\Sabre\VObject\Reader;
use \OCA\Calendar\Sabre\VObject\ParseException;
use \OCA\Calendar\Sabre\VObject\EofException;
use \OCA\Calendar\Utility\SabreUtility;
class JSONObjectReader extends JSONReader {
/**
* @brief parse json object
@ -38,4 +45,9 @@ class JSONObjectReader {
throw new JSONObjectReaderException($ex->getMessage());
}
}
public function sanitize(){
return $this;
}
}

View File

@ -20,10 +20,10 @@ class ObjectUtility extends Utility{
public static function randomURI() {
$random = rand().time().rand();
$md5 = md5($random);
$substr = substr($md5, rand(0,11),20);
$substr = substr($md5, rand(0,5),26);
$substr .= '.ics';
return $substr;
$uri = 'owncloud-' . $substr . '.ics';
return $uri;
}