[Pkg-owncloud-commits] [php-sabredav] 18/220: Working towards implementing sharing in default backends.
David Prévot
taffit at moszumanska.debian.org
Thu May 12 01:21:02 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository php-sabredav.
commit 11bdb03155ed63f4439c0223c12ef2315d2f38d5
Author: Evert Pot <me at evertpot.com>
Date: Sat Oct 17 19:22:24 2015 -0400
Working towards implementing sharing in default backends.
Very broken at the moment.
---
bin/migrateto31.php | 257 ++++++++++++++++++++++++++++++
examples/sql/mysql.calendars.sql | 12 +-
examples/sql/sqlite.calendars.sql | 10 +-
lib/CalDAV/Backend/PDO.php | 58 +++++--
lib/CalDAV/Backend/SharingSupport.php | 34 +---
lib/CalDAV/Backend/SimplePDO.php | 287 ++++++++++++++++++++++++++++++++++
lib/DAV/Sharing/Plugin.php | 7 +-
7 files changed, 617 insertions(+), 48 deletions(-)
diff --git a/bin/migrateto31.php b/bin/migrateto31.php
new file mode 100755
index 0000000..0052c6d
--- /dev/null
+++ b/bin/migrateto31.php
@@ -0,0 +1,257 @@
+#!/usr/bin/env php
+<?php
+
+echo "SabreDAV migrate script for version 3.1\n";
+
+if ($argc<2) {
+
+ echo <<<HELLO
+
+This script help you migrate from a 3.0 database to 3.1 and later
+
+Changes:
+* Created a new calendar_instances table to support calendar sharing.
+* Remove a lot of columns from calendars.
+
+Keep in mind that ALTER TABLE commands will be executed. If you have a large
+dataset this may mean that this process takes a while.
+
+Make a back-up first. This script has been tested, but the amount of
+potential variants are extremely high, so it's impossible to deal with every
+possible situation.
+
+In the worst case, you will lose all your data. This is not an overstatement.
+
+Lastly, if you are upgrading from an older version than 3.0, make sure you run
+the earlier migration script first. Migration scripts must be ran in order.
+
+Usage:
+
+php {$argv[0]} [pdo-dsn] [username] [password]
+
+For example:
+
+php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
+php {$argv[0]} sqlite:data/sabredav.db
+
+HELLO;
+
+ exit();
+
+}
+
+// There's a bunch of places where the autoloader could be, so we'll try all of
+// them.
+$paths = [
+ __DIR__ . '/../vendor/autoload.php',
+ __DIR__ . '/../../../autoload.php',
+];
+
+foreach($paths as $path) {
+ if (file_exists($path)) {
+ include $path;
+ break;
+ }
+}
+
+$dsn = $argv[1];
+$user = isset($argv[2])?$argv[2]:null;
+$pass = isset($argv[3])?$argv[3]:null;
+
+$backupPostfix = time();
+
+echo "Connecting to database: " . $dsn . "\n";
+
+$pdo = new PDO($dsn, $user, $pass);
+$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+
+$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
+
+switch($driver) {
+
+ case 'mysql' :
+ echo "Detected MySQL.\n";
+ break;
+ case 'sqlite' :
+ echo "Detected SQLite.\n";
+ break;
+ default :
+ echo "Error: unsupported driver: " . $driver . "\n";
+ die(-1);
+}
+
+echo "Creating 'calendar_instances'\n";
+$addValueType = false;
+try {
+ $result = $pdo->query('SELECT * FROM calendar_instances LIMIT 1');
+ $result->fetch(\PDO::FETCH_ASSOC);
+ echo "calendar_instances exists. Assuming this part of the migration has already been done.\n";
+} catch (Exception $e) {
+ echo "calendar_instances does not yet exist. Creating table and migrating data.\n";
+
+ switch($driver) {
+ case 'mysql' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendar_instances (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ calendarid INTEGER UNSIGNED NOT NULL,
+ principaluri VARBINARY(100),
+ access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = readwrite, 3 = read',
+ displayname VARCHAR(100),
+ uri VARBINARY(200),
+ description TEXT,
+ calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ calendarcolor VARBINARY(10),
+ timezone TEXT,
+ transparent TINYINT(1) NOT NULL DEFAULT '0',
+ UNIQUE(principaluri, uri)
+);
+SQL
+ );
+ $pdo->exec("
+INSERT INTO calendar_instances
+ (
+ calendarid,
+ principaluri,
+ access,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+ )
+SELECT
+ id,
+ principaluri,
+ 1,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+FROM calendars
+");
+ break;
+ case 'sqlite' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendar_instances (
+ id integer primary key asc,
+ calendarid integer,
+ principaluri text,
+ access integer COMMENT '1 = owner, 2 = readwrite, 3 = read',
+ displayname text,
+ uri text,
+ description text,
+ calendarorder integer,
+ calendarcolor text,
+ timezone text,
+ transparent bool
+);
+SQL
+ );
+ $pdo->exec("
+INSERT INTO calendar_instances
+ (
+ calendarid,
+ principaluri,
+ access,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+ )
+SELECT
+ id,
+ principaluri,
+ 1,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+FROM calendars
+");
+ break;
+ }
+
+}
+try {
+ $result = $pdo->query('SELECT * FROM calendars LIMIT 1');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+
+ if (!$row) {
+ echo "Source table is empty.\n";
+ $migrateCalendars = true;
+ }
+
+ $columnCount = count($row);
+ if ($columnCount === 3) {
+ echo "The calendars table has 3 columns already. Assuming this part of the migration was already done.\n";
+ $migrateCalendars = false;
+ } else {
+ echo "The calendars table has " . $columnCount . " columns.\n";
+ $migrateCalendars = true;
+ }
+
+} catch (Exception $e) {
+ echo "calendars table does not exist. This is a major problem. Exiting.\n";
+ exit(-1);
+}
+
+if ($migrateCalendars) {
+
+ $calendarBackup = 'calendars_3_0_' . $backupPostfix;
+ echo "Backing up 'calendars' to '", $calendarBackup, "'\n";
+
+ switch($driver) {
+ case 'mysql' :
+ $pdo->exec('RENAME TABLE calendars TO ' . $calendarBackup);
+ break;
+ case 'sqlite' :
+ $pdo->exec('ALTER TABLE calendars RENAME TO ' . $calendarBackup);
+ break;
+
+ }
+
+ echo "Creating new calendars table.\n";
+ switch($driver) {
+ case 'mysql' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendars (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
+ components VARBINARY(20)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SQL
+);
+ break;
+ case 'sqlite' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendars (
+ id integer primary key asc,
+ synctoken integer,
+ components text
+);
+SQL
+ );
+ break;
+
+ }
+
+ echo "Migrating data from old to new table\n";
+
+ $pdo->exec(<<<SQL
+INSERT INTO calendars (id, synctoken, components) SELECT id, synctoken, components FROM $calendarBackup
+SQL
+ );
+
+}
+
+
+echo "Upgrade to 3.1 schema completed.\n";
diff --git a/examples/sql/mysql.calendars.sql b/examples/sql/mysql.calendars.sql
index 55d3b48..04775c5 100644
--- a/examples/sql/mysql.calendars.sql
+++ b/examples/sql/mysql.calendars.sql
@@ -15,18 +15,24 @@ CREATE TABLE calendarobjects (
CREATE TABLE calendars (
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
+ components VARBINARY(20)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+CREATE TABLE calendar_instances (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ calendarid INTEGER UNSIGNED NOT NULL,
principaluri VARBINARY(100),
+ access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = readwrite, 3 = read',
displayname VARCHAR(100),
uri VARBINARY(200),
- synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
description TEXT,
calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
calendarcolor VARBINARY(10),
timezone TEXT,
- components VARBINARY(20),
transparent TINYINT(1) NOT NULL DEFAULT '0',
UNIQUE(principaluri, uri)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+);
CREATE TABLE calendarchanges (
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
diff --git a/examples/sql/sqlite.calendars.sql b/examples/sql/sqlite.calendars.sql
index 4a17f0d..87e5270 100644
--- a/examples/sql/sqlite.calendars.sql
+++ b/examples/sql/sqlite.calendars.sql
@@ -14,15 +14,21 @@ CREATE TABLE calendarobjects (
CREATE TABLE calendars (
id integer primary key asc,
+ synctoken integer,
+ components text
+);
+
+CREATE TABLE calendar_instances (
+ id integer primary key asc,
+ calendarid integer,
principaluri text,
+ access integer COMMENT '1 = owner, 2 = readwrite, 3 = read',
displayname text,
uri text,
- synctoken integer,
description text,
calendarorder integer,
calendarcolor text,
timezone text,
- components text,
transparent bool
);
diff --git a/lib/CalDAV/Backend/PDO.php b/lib/CalDAV/Backend/PDO.php
index c35ffe2..97c90c0 100644
--- a/lib/CalDAV/Backend/PDO.php
+++ b/lib/CalDAV/Backend/PDO.php
@@ -17,7 +17,13 @@ use Sabre\DAV\Exception\Forbidden;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport {
+class PDO extends AbstractBackend
+ implements
+ SyncSupport,
+ SubscriptionSupport,
+ SchedulingSupport,
+ SharingSupport
+ {
/**
* We need to specify a max date, because we need to stop *somewhere*
@@ -44,6 +50,16 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
public $calendarTableName = 'calendars';
/**
+ * The table name that will be used for calendars instances.
+ *
+ * A single calendar can have multiple instances, if the calendar is
+ * shared.
+ *
+ * @var string
+ */
+ public $calendarTableName = 'calendar_instances';
+
+ /**
* The table name that will be used for calendar objects
*
* @var string
@@ -140,16 +156,23 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
function getCalendarsForUser($principalUri) {
$fields = array_values($this->propertyMap);
- $fields[] = 'id';
+ $fields[] = 'calendarid';
$fields[] = 'uri';
$fields[] = 'synctoken';
$fields[] = 'components';
$fields[] = 'principaluri';
$fields[] = 'transparent';
+ $fields[] = 'access';
// Making fields a comma-delimited list
$fields = implode(', ', $fields);
- $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM " . $this->calendarTableName . " WHERE principaluri = ? ORDER BY calendarorder ASC");
+ $stmt = $this->pdo->prepare(<<<SQL
+SELECT $fields FROM {$this->calendarInstancesTableName}
+ LEFT JOIN {$this->calendarTableName} ON
+ {$this->calendarInstancesTableName}.calendarid = {$this->calendarTableName}.id
+WHERE principaluri = ? ORDER BY calendarorder ASC
+SQL
+ );
$stmt->execute([$principalUri]);
$calendars = [];
@@ -170,6 +193,16 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
'{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
];
+ // 1 = owner, 2 = readonly, 3 = readwrite
+ if ($row['access'] > 1) {
+ // We need to find more information about the original owner.
+ $stmt2 = $this->pdo->prepare('SELECT principaluri FROM ' . $this->calendarInstancesTableName . ' WHERE access = 1 AND id = ?');
+ $stmt2->execute([$row['id']]);
+
+ $calendar['owner_principal'] = $stmt2->fetchColumn();
+ $calendar['read-only'] = $row['access']===3;
+ }
+
foreach ($this->propertyMap as $xmlName => $dbName) {
$calendar[$xmlName] = $row[$dbName];
@@ -199,31 +232,34 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$fieldNames = [
'principaluri',
'uri',
- 'synctoken',
'transparent',
+ 'calendarid',
];
$values = [
':principaluri' => $principalUri,
':uri' => $calendarUri,
- ':synctoken' => 1,
':transparent' => 0,
];
- // Default value
+
$sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
- $fieldNames[] = 'components';
if (!isset($properties[$sccs])) {
- $values[':components'] = 'VEVENT,VTODO';
+ // Default value
+ $components = 'VEVENT,VTODO';
} else {
if (!($properties[$sccs] instanceof CalDAV\Xml\Property\SupportedCalendarComponentSet)) {
throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet');
}
- $values[':components'] = implode(',', $properties[$sccs]->getValue());
+ $components = implode(',', $properties[$sccs]->getValue());
}
$transp = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp';
if (isset($properties[$transp])) {
$values[':transparent'] = $properties[$transp]->getValue() === 'transparent';
}
+ $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (synctoken, components) VALUES (1, ?)");
+ $stmt->execute([$components]);
+
+ $values[':calendarid'] = $this->pdo->lastInsertId()
foreach ($this->propertyMap as $xmlName => $dbName) {
if (isset($properties[$xmlName])) {
@@ -233,7 +269,7 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
}
}
- $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
+ $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarInstancesTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
$stmt->execute($values);
return $this->pdo->lastInsertId();
@@ -282,7 +318,7 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$valuesSql[] = $fieldName . ' = ?';
}
- $stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?");
+ $stmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?");
$newValues['id'] = $calendarId;
$stmt->execute(array_values($newValues));
diff --git a/lib/CalDAV/Backend/SharingSupport.php b/lib/CalDAV/Backend/SharingSupport.php
index 2aed39f..a837607 100644
--- a/lib/CalDAV/Backend/SharingSupport.php
+++ b/lib/CalDAV/Backend/SharingSupport.php
@@ -8,24 +8,6 @@ namespace Sabre\CalDAV\Backend;
* Note: This feature is experimental, and may change in between different
* SabreDAV versions.
*
- * Early warning: Currently SabreDAV provides no implementation for this. This
- * is, because in it's current state there is no elegant way to do this.
- * The problem lies in the fact that a real CalDAV server with sharing support
- * would first need email support (with invite notifications), and really also
- * a browser-frontend that allows people to accept or reject these shares.
- *
- * In addition, the CalDAV backends are currently kept as independent as
- * possible, and should not be aware of principals, email addresses or
- * accounts.
- *
- * Adding an implementation for Sharing to standard-sabredav would contradict
- * these goals, so for this reason this is currently not implemented, although
- * it may very well in the future; but probably not before SabreDAV 2.0.
- *
- * The interface works however, so if you implement all this, and do it
- * correctly sharing _will_ work. It's not particularly easy, and I _urge you_
- * to make yourself acquainted with the following document first:
- *
* https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
*
* An overview
@@ -65,12 +47,12 @@ namespace Sabre\CalDAV\Backend;
* change.
* This notification is always represented by:
*
- * Sabre\CalDAV\Notifications\Notification\Invite
+ * Sabre\CalDAV\Xml\Notification\Invite
*
* In the case of an invite, the sharee may reply with an 'accept' or
* 'decline'. These are always represented by:
*
- * Sabre\CalDAV\Notifications\Notification\InviteReply
+ * Sabre\CalDAV\Xml\Notification\InviteReply
*
*
* Calendar access by sharees
@@ -81,16 +63,12 @@ namespace Sabre\CalDAV\Backend;
*
* The following properties must be specified:
*
- * 1. {http://calendarserver.org/ns/}shared-url
- *
- * This property MUST contain the url to the original calendar, that is.. the
- * path to the calendar from the owner.
- *
- * 2. {http://sabredav.org/ns}owner-principal
+ * 1. owner-principal
*
- * This is a url to to the principal who is sharing the calendar.
+ * If the calendar is shared, and the current user is not the owner, then this
+ * property MUST contain information to identify the real owner.
*
- * 3. {http://sabredav.org/ns}read-only
+ * 2. read-only
*
* This should be either 0 or 1, depending on if the user has read-only or
* read-write access to the calendar.
diff --git a/lib/CalDAV/Backend/SimplePDO.php b/lib/CalDAV/Backend/SimplePDO.php
new file mode 100644
index 0000000..fc009ec
--- /dev/null
+++ b/lib/CalDAV/Backend/SimplePDO.php
@@ -0,0 +1,287 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+use Sabre\VObject;
+use Sabre\CalDAV;
+use Sabre\DAV;
+use Sabre\DAV\Exception\Forbidden;
+
+/**
+ * Simple PDO CalDAV backend.
+ *
+ * This backend class serves as a demononstration on how to create a very
+ * simple CalDAV backend.
+ *
+ * Unlike the 'PDO' class, this class only has the most basic features.
+ *
+ * To make this class work, you absolutely need to have the PropertyStorage
+ * plugin enabled.
+ *
+ * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class SimplePDO extends AbstractBackend {
+
+ /**
+ * pdo
+ *
+ * @var \PDO
+ */
+ protected $pdo;
+
+ /**
+ * Creates the backend
+ *
+ * @param \PDO $pdo
+ */
+ function __construct(\PDO $pdo) {
+
+ $this->pdo = $pdo;
+
+ }
+
+ /**
+ * Returns a list of calendars for a principal.
+ *
+ * Every project is an array with the following keys:
+ * * id, a unique id that will be used by other functions to modify the
+ * calendar. This can be the same as the uri or a database key.
+ * * uri. This is just the 'base uri' or 'filename' of the calendar.
+ * * principaluri. The owner of the calendar. Almost always the same as
+ * principalUri passed to this method.
+ *
+ * Furthermore it can contain webdav properties in clark notation. A very
+ * common one is '{DAV:}displayname'.
+ *
+ * Many clients also require:
+ * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
+ * For this property, you can just return an instance of
+ * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
+ *
+ * If you return {http://sabredav.org/ns}read-only and set the value to 1,
+ * ACL will automatically be put in read-only mode.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ function getCalendarsForUser($principalUri) {
+
+ // Making fields a comma-delimited list
+ $stmt = $this->pdo->prepare("SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY calendarorder ASC");
+ $stmt->execute([$principalUri]);
+
+ $calendars = [];
+ while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+
+ $calendars[] = [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'principaluri' => $principalUri,
+ ];
+
+ }
+
+ return $calendars;
+
+ }
+
+ /**
+ * Creates a new calendar for a principal.
+ *
+ * If the creation was a success, an id must be returned that can be used
+ * to reference this calendar in other methods, such as updateCalendar.
+ *
+ * @param string $principalUri
+ * @param string $calendarUri
+ * @param array $properties
+ * @return string
+ */
+ function createCalendar($principalUri, $calendarUri, array $properties) {
+
+ $stmt = $this->pdo->prepare("INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)");
+ $stmt->execute($principalUri, $calendarUri);
+
+ return $this->pdo->lastInsertId();
+
+ }
+
+ /**
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
+ * @return void
+ */
+ function deleteCalendar($calendarId) {
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?');
+ $stmt->execute([$calendarId]);
+
+ }
+
+ /**
+ * Returns all calendar objects within a calendar.
+ *
+ * Every item contains an array with the following keys:
+ * * calendardata - The iCalendar-compatible calendar data
+ * * uri - a unique key which will be used to construct the uri. This can
+ * be any arbitrary string, but making sure it ends with '.ics' is a
+ * good idea. This is only the basename, or filename, not the full
+ * path.
+ * * lastmodified - a timestamp of the last modification time
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * ' "abcdef"')
+ * * size - The size of the calendar objects, in bytes.
+ * * component - optional, a string containing the type of object, such
+ * as 'vevent' or 'vtodo'. If specified, this will be used to populate
+ * the Content-Type header.
+ *
+ * Note that the etag is optional, but it's highly encouraged to return for
+ * speed reasons.
+ *
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
+ * calendardata.
+ *
+ * If neither etag or size are specified, the calendardata will be
+ * used/fetched to determine these numbers. If both are specified the
+ * amount of times this is needed is reduced by a great degree.
+ *
+ * @param string $calendarId
+ * @return array
+ */
+ function getCalendarObjects($calendarId) {
+
+ $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $result = [];
+ foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
+ $result[] = [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'etag' => '"' . md5($row['calendardata']) . '"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($row['calendardata']),
+ 'calendardata' => $row['calendardata'],
+ ];
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Returns information from a single calendar object, based on it's object
+ * uri.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
+ * for getCalendarObjects.
+ *
+ * This method must return null if the object did not exist.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array|null
+ */
+ function getCalendarObject($calendarId, $objectUri) {
+
+ $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarId, $objectUri]);
+ $row = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+ if (!$row) return null;
+
+ return [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'etag' => '"' . md5($row['calendardata']) . '"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($row['calendardata']),
+ 'calendardata' => $row['calendardata'],
+ ];
+
+ }
+
+ /**
+ * Creates a new calendar object.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * It is possible return an etag from this function, which will be used in
+ * the response to this PUT request. Note that the ETag must be surrounded
+ * by double-quotes.
+ *
+ * However, you should only really return this ETag if you don't mangle the
+ * calendar-data. If the result of a subsequent GET to this object is not
+ * the exact same as this request body, you should omit the ETag.
+ *
+ * @param mixed $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return string|null
+ */
+ function createCalendarObject($calendarId, $objectUri, $calendarData) {
+
+ $stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
+ $stmt->execute([
+ $calendarId,
+ $objectUri,
+ $calendarData
+ ]);
+
+ return '"' . md5($calendarData) . '"';
+
+ }
+
+ /**
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * It is possible return an etag from this function, which will be used in
+ * the response to this PUT request. Note that the ETag must be surrounded
+ * by double-quotes.
+ *
+ * However, you should only really return this ETag if you don't mangle the
+ * calendar-data. If the result of a subsequent GET to this object is not
+ * the exact same as this request body, you should omit the ETag.
+ *
+ * @param mixed $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return string|null
+ */
+ function updateCalendarObject($calendarId, $objectUri, $calendarData) {
+
+ $stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarData, $calendarId, $objectUri]);
+
+ return '"' . md5($calendarData) . '"';
+
+ }
+
+ /**
+ * Deletes an existing calendar object.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return void
+ */
+ function deleteCalendarObject($calendarId, $objectUri) {
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarId, $objectUri]);
+
+ }
+
+}
diff --git a/lib/DAV/Sharing/Plugin.php b/lib/DAV/Sharing/Plugin.php
index 11432ae..b7327aa 100644
--- a/lib/DAV/Sharing/Plugin.php
+++ b/lib/DAV/Sharing/Plugin.php
@@ -147,13 +147,13 @@ class Plugin extends ServerPlugin {
*/
function propFind(PropFind $propFind, INode $node) {
- $propFind->handle('{DAV:}share-mode', function() {
+ $propFind->handle('{DAV:}share-mode', function() use ($node) {
- if (INode instanceof ISharedNode) {
+ if ($node instanceof ISharedNode) {
return new Property\ShareMode(Property\ShareMode::SHARED);
- } elseif (INode instanceof IShareableNode) {
+ } elseif ($node instanceof IShareableNode) {
return new Property\ShareMode(Property\ShareMode::SHAREDOWNER);
@@ -207,7 +207,6 @@ class Plugin extends ServerPlugin {
}
-
/**
* Returns a bunch of meta-data about the plugin.
*
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-php/php-sabredav.git
More information about the Pkg-owncloud-commits
mailing list