feat: upgrade to sabre project with last version comptabile with php 7.1
This commit is contained in:
parent
0cc761dccd
commit
580f803f73
330 changed files with 12093 additions and 10531 deletions
2
htdocs/includes/sabre/sabre/dav/.gitignore
vendored
2
htdocs/includes/sabre/sabre/dav/.gitignore
vendored
|
|
@ -41,3 +41,5 @@ docs/wikidocs
|
|||
|
||||
# Mac
|
||||
.DS_Store
|
||||
|
||||
.php_cs.cache
|
||||
|
|
|
|||
12
htdocs/includes/sabre/sabre/dav/.php_cs.dist
Normal file
12
htdocs/includes/sabre/sabre/dav/.php_cs.dist
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
$config = PhpCsFixer\Config::create();
|
||||
$config->getFinder()
|
||||
->exclude('vendor')
|
||||
->in(__DIR__);
|
||||
$config->setRules([
|
||||
'@PSR1' => true,
|
||||
'@Symfony' =>true
|
||||
]);
|
||||
|
||||
return $config;
|
||||
|
|
@ -1,35 +1,51 @@
|
|||
language: php
|
||||
sudo: required
|
||||
php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
|
||||
- 7.2
|
||||
- 7.3
|
||||
|
||||
env:
|
||||
global:
|
||||
- SABRE_MYSQLUSER="root"
|
||||
- SABRE_MYSQLPASS=""
|
||||
- SABRE_MYSQLDSN="mysql:host=127.0.0.1;dbname=sabredav_test"
|
||||
- RUN_PHPSTAN="FALSE"
|
||||
matrix:
|
||||
- LOWEST_DEPS="" TEST_DEPS=""
|
||||
- LOWEST_DEPS="--prefer-lowest" TEST_DEPS="tests/Sabre/"
|
||||
- LOWEST_DEPS="" TEST_DEPS="" WITH_COVERAGE="--coverage-clover=coverage.xml"
|
||||
- LOWEST_DEPS="--prefer-lowest" TEST_DEPS="tests/Sabre/" $WITH_COVERAGE=""
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- name: 'PHPStan'
|
||||
php: 7.2
|
||||
env: RUN_PHPSTAN="TRUE"
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
|
||||
sudo: false
|
||||
install:
|
||||
- if [ $RUN_PHPSTAN == "TRUE" ]; then wget https://github.com/phpstan/phpstan/releases/download/0.11.8/phpstan.phar; fi
|
||||
|
||||
before_script:
|
||||
- mysql -e 'create database sabredav_test'
|
||||
# - mysql -u root -h 127.0.0.1 sabredav_test -e 'SELECT VERSION();'
|
||||
#- mysql -u root -h 127.0.0.1 -e 'create database sabredav_test'
|
||||
- psql -c "create database sabredav_test" -U postgres
|
||||
- psql -c "create user sabredav with PASSWORD 'sabredav';GRANT ALL PRIVILEGES ON DATABASE sabredav_test TO sabredav" -U postgres
|
||||
# - composer self-update
|
||||
- composer update --prefer-dist $LOWEST_DEPS
|
||||
|
||||
# addons:
|
||||
# postgresql: "9.5"
|
||||
addons:
|
||||
postgresql: "9.5"
|
||||
|
||||
script:
|
||||
- ./bin/phpunit --configuration tests/phpunit.xml.dist $TEST_DEPS
|
||||
- ./bin/sabre-cs-fixer fix . --dry-run --diff
|
||||
- if [ $RUN_PHPSTAN == "FALSE" ]; then ./bin/phpunit --verbose --configuration tests/phpunit.xml.dist $WITH_COVERAGE $TEST_DEPS; fi
|
||||
- if [ $RUN_PHPSTAN == "FALSE" ]; then rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini; fi
|
||||
- if [ $RUN_PHPSTAN == "TRUE" ]; then php phpstan.phar analyse -c phpstan.neon lib; fi
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
|
|
|||
2497
htdocs/includes/sabre/sabre/dav/CHANGELOG.md
Normal file
2497
htdocs/includes/sabre/sabre/dav/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -78,6 +78,28 @@ to accept the patch, but we'd still really like your contribution!
|
|||
To run the testsuite jump into the directory `cd tests` and trigger `phpunit`.
|
||||
Make sure you did a `composer install` beforehand.
|
||||
|
||||
Release process
|
||||
---------------
|
||||
|
||||
Generally, these are the steps taken to do releases.
|
||||
|
||||
1. Update the changelog. Every repo will have a `CHANGELOG.md` file. This file
|
||||
should have a new version, and contain all the changes since the last
|
||||
release. I generally run a `git diff` to figure out if I missed any changes.
|
||||
This file should also have the current date.
|
||||
2. If there were BC breaks, this usually now means a major version bump.
|
||||
3. Ensure that `lib/Version.php` or `lib/DAV/Version.php` also matches this
|
||||
version number.
|
||||
4. Tag the release (Example `git tag 3.0.1` and push the tag (`git push --tags`).
|
||||
5. (only for the sabre/dav project), create a zip distribution. Run
|
||||
`php bin/build.php`.
|
||||
6. For the relevant project, go to github and click the 'releases' tab. On this
|
||||
tab I create the release with the relevant version. I also set the
|
||||
description of the release to the same information of the changelog. In the
|
||||
case of the `sabre/dav` project I also upload the zip distribution here.
|
||||
7. Write a blog post on sabre.io. This also automatically updates twitter.
|
||||
|
||||
|
||||
[1]: http://www.php-fig.org/psr/psr-1/
|
||||
[2]: http://www.php-fig.org/psr/psr-4/
|
||||
[3]: http://www.php-fig.org/psr/psr-2/
|
||||
|
|
|
|||
27
htdocs/includes/sabre/sabre/dav/LICENSE
Normal file
27
htdocs/includes/sabre/sabre/dav/LICENSE
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (C) 2007-2016 fruux GmbH (https://fruux.com/).
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of SabreDAV nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
38
htdocs/includes/sabre/sabre/dav/README.md
Normal file
38
htdocs/includes/sabre/sabre/dav/README.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
 sabre/dav
|
||||
=======================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
sabre/dav is the most popular WebDAV framework for PHP. Use it to create WebDAV, CalDAV and CardDAV servers.
|
||||
|
||||
Full documentation can be found on the website:
|
||||
|
||||
http://sabre.io/
|
||||
|
||||
|
||||
Build status
|
||||
------------
|
||||
|
||||
| branch | status | minimum PHP version |
|
||||
| ------------ | ------ | ------------------- |
|
||||
| master | [](https://travis-ci.org/sabre-io/dav) | PHP 7.0 |
|
||||
| 3.1 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.5 |
|
||||
| 3.0 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.4 |
|
||||
| 2.1 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.4 |
|
||||
| 2.0 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.4 |
|
||||
| 1.8 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.3 |
|
||||
| 1.7 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.3 |
|
||||
| 1.6 | [](https://travis-ci.org/sabre-io/dav) | PHP 5.3 |
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
* [Introduction](http://sabre.io/dav/).
|
||||
* [Installation](http://sabre.io/dav/install/).
|
||||
|
||||
|
||||
Made at fruux
|
||||
-------------
|
||||
|
||||
SabreDAV is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support.
|
||||
88
htdocs/includes/sabre/sabre/dav/bin/build.php
Normal file → Executable file
88
htdocs/includes/sabre/sabre/dav/bin/build.php
Normal file → Executable file
|
|
@ -2,7 +2,6 @@
|
|||
<?php
|
||||
|
||||
$tasks = [
|
||||
|
||||
'buildzip' => [
|
||||
'init', 'test', 'clean',
|
||||
],
|
||||
|
|
@ -10,25 +9,29 @@ $tasks = [
|
|||
'init', 'test', 'clean',
|
||||
],
|
||||
'clean' => [],
|
||||
'test' => [
|
||||
'test' => [
|
||||
'composerupdate',
|
||||
],
|
||||
'init' => [],
|
||||
'init' => [],
|
||||
'composerupdate' => [],
|
||||
];
|
||||
|
||||
$default = 'buildzip';
|
||||
|
||||
$baseDir = __DIR__ . '/../';
|
||||
$baseDir = __DIR__.'/../';
|
||||
chdir($baseDir);
|
||||
|
||||
$currentTask = $default;
|
||||
if ($argc > 1) $currentTask = $argv[1];
|
||||
if ($argc > 1) {
|
||||
$currentTask = $argv[1];
|
||||
}
|
||||
$version = null;
|
||||
if ($argc > 2) $version = $argv[2];
|
||||
if ($argc > 2) {
|
||||
$version = $argv[2];
|
||||
}
|
||||
|
||||
if (!isset($tasks[$currentTask])) {
|
||||
echo "Task not found: ", $currentTask, "\n";
|
||||
echo 'Task not found: ', $currentTask, "\n";
|
||||
die(1);
|
||||
}
|
||||
|
||||
|
|
@ -37,11 +40,9 @@ $newTaskList = [];
|
|||
$oldTaskList = [$currentTask => true];
|
||||
|
||||
while (count($oldTaskList) > 0) {
|
||||
|
||||
foreach ($oldTaskList as $task => $foo) {
|
||||
|
||||
if (!isset($tasks[$task])) {
|
||||
echo "Dependency not found: " . $task, "\n";
|
||||
echo 'Dependency not found: '.$task, "\n";
|
||||
die(1);
|
||||
}
|
||||
$dependencies = $tasks[$task];
|
||||
|
|
@ -55,82 +56,74 @@ while (count($oldTaskList) > 0) {
|
|||
$oldTaskList[$dependency] = true;
|
||||
$fullFilled = false;
|
||||
}
|
||||
|
||||
}
|
||||
if ($fullFilled) {
|
||||
unset($oldTaskList[$task]);
|
||||
$newTaskList[$task] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (array_keys($newTaskList) as $task) {
|
||||
|
||||
echo "task: " . $task, "\n";
|
||||
echo 'task: '.$task, "\n";
|
||||
call_user_func($task);
|
||||
echo "\n";
|
||||
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
function init()
|
||||
{
|
||||
global $version;
|
||||
if (!$version) {
|
||||
include __DIR__ . '/../vendor/autoload.php';
|
||||
include __DIR__.'/../vendor/autoload.php';
|
||||
$version = Sabre\DAV\Version::VERSION;
|
||||
}
|
||||
|
||||
echo " Building sabre/dav " . $version, "\n";
|
||||
|
||||
echo ' Building sabre/dav '.$version, "\n";
|
||||
}
|
||||
|
||||
function clean() {
|
||||
|
||||
function clean()
|
||||
{
|
||||
global $baseDir;
|
||||
echo " Removing build files\n";
|
||||
$outputDir = $baseDir . '/build/SabreDAV';
|
||||
$outputDir = $baseDir.'/build/SabreDAV';
|
||||
if (is_dir($outputDir)) {
|
||||
system('rm -r ' . $baseDir . '/build/SabreDAV');
|
||||
system('rm -r '.$baseDir.'/build/SabreDAV');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function composerupdate() {
|
||||
|
||||
function composerupdate()
|
||||
{
|
||||
global $baseDir;
|
||||
echo " Updating composer packages to latest version\n\n";
|
||||
system('cd ' . $baseDir . '; composer update');
|
||||
system('cd '.$baseDir.'; composer update');
|
||||
}
|
||||
|
||||
function test() {
|
||||
|
||||
function test()
|
||||
{
|
||||
global $baseDir;
|
||||
|
||||
echo " Running all unittests.\n";
|
||||
echo " This may take a while.\n\n";
|
||||
system(__DIR__ . '/phpunit --configuration ' . $baseDir . '/tests/phpunit.xml.dist --stop-on-failure', $code);
|
||||
if ($code != 0) {
|
||||
system(__DIR__.'/phpunit --configuration '.$baseDir.'/tests/phpunit.xml.dist --stop-on-failure', $code);
|
||||
if (0 != $code) {
|
||||
echo "PHPUnit reported error code $code\n";
|
||||
die(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function buildzip() {
|
||||
|
||||
function buildzip()
|
||||
{
|
||||
global $baseDir, $version;
|
||||
echo " Generating composer.json\n";
|
||||
|
||||
$input = json_decode(file_get_contents(__DIR__ . '/../composer.json'), true);
|
||||
$input = json_decode(file_get_contents(__DIR__.'/../composer.json'), true);
|
||||
$newComposer = [
|
||||
"require" => $input['require'],
|
||||
"config" => [
|
||||
"bin-dir" => "./bin",
|
||||
'require' => $input['require'],
|
||||
'config' => [
|
||||
'bin-dir' => './bin',
|
||||
],
|
||||
"prefer-stable" => true,
|
||||
"minimum-stability" => "alpha",
|
||||
'prefer-stable' => true,
|
||||
'minimum-stability' => 'alpha',
|
||||
];
|
||||
unset(
|
||||
$newComposer['require']['sabre/vobject'],
|
||||
|
|
@ -143,8 +136,8 @@ function buildzip() {
|
|||
file_put_contents('build/SabreDAV/composer.json', json_encode($newComposer, JSON_PRETTY_PRINT));
|
||||
|
||||
echo " Downloading dependencies\n";
|
||||
system("cd build/SabreDAV; composer install -n", $code);
|
||||
if ($code !== 0) {
|
||||
system('cd build/SabreDAV; composer install -n', $code);
|
||||
if (0 !== $code) {
|
||||
echo "Composer reported error code $code\n";
|
||||
die(1);
|
||||
}
|
||||
|
|
@ -163,15 +156,14 @@ function buildzip() {
|
|||
];
|
||||
foreach ($fileNames as $fileName) {
|
||||
echo " $fileName\n";
|
||||
rename('build/SabreDAV/vendor/sabre/dav/' . $fileName, 'build/SabreDAV/' . $fileName);
|
||||
rename('build/SabreDAV/vendor/sabre/dav/'.$fileName, 'build/SabreDAV/'.$fileName);
|
||||
}
|
||||
|
||||
// <zip destfile="build/SabreDAV-${sabredav.version}.zip" basedir="build/SabreDAV" prefix="SabreDAV/" />
|
||||
|
||||
echo "\n";
|
||||
echo "Zipping the sabredav distribution\n\n";
|
||||
system('cd build; zip -qr sabredav-' . $version . '.zip SabreDAV');
|
||||
|
||||
echo "Done.";
|
||||
system('cd build; zip -qr sabredav-'.$version.'.zip SabreDAV');
|
||||
|
||||
echo 'Done.';
|
||||
}
|
||||
|
|
|
|||
0
htdocs/includes/sabre/sabre/dav/bin/googlecode_upload.py
Normal file → Executable file
0
htdocs/includes/sabre/sabre/dav/bin/googlecode_upload.py
Normal file → Executable file
152
htdocs/includes/sabre/sabre/dav/bin/migrateto20.php
Normal file → Executable file
152
htdocs/includes/sabre/sabre/dav/bin/migrateto20.php
Normal file → Executable file
|
|
@ -4,7 +4,6 @@
|
|||
echo "SabreDAV migrate script for version 2.0\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-2.0 database to 2.0 and later
|
||||
|
|
@ -36,14 +35,13 @@ 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',
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
|
@ -57,7 +55,7 @@ $dsn = $argv[1];
|
|||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo "Connecting to database: " . $dsn . "\n";
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
|
@ -66,23 +64,21 @@ $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default :
|
||||
echo "Error: unsupported driver: " . $driver . "\n";
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
die(-1);
|
||||
}
|
||||
|
||||
foreach (['calendar', 'addressbook'] as $itemType) {
|
||||
|
||||
$tableName = $itemType . 's';
|
||||
$tableNameOld = $tableName . '_old';
|
||||
$changesTable = $itemType . 'changes';
|
||||
$tableName = $itemType.'s';
|
||||
$tableNameOld = $tableName.'_old';
|
||||
$changesTable = $itemType.'changes';
|
||||
|
||||
echo "Upgrading '$tableName'\n";
|
||||
|
||||
|
|
@ -90,18 +86,16 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
$row = $pdo->query("SELECT * FROM $tableName LIMIT 1")->fetch();
|
||||
|
||||
if (!$row) {
|
||||
|
||||
echo "No records were found in the '$tableName' table.\n";
|
||||
echo "\n";
|
||||
echo "We're going to rename the old table to $tableNameOld (just in case).\n";
|
||||
echo "and re-create the new table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec("RENAME TABLE $tableName TO $tableNameOld");
|
||||
switch ($itemType) {
|
||||
case 'calendar' :
|
||||
case 'calendar':
|
||||
$pdo->exec("
|
||||
CREATE TABLE calendars (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -119,7 +113,7 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
");
|
||||
break;
|
||||
case 'addressbook' :
|
||||
case 'addressbook':
|
||||
$pdo->exec("
|
||||
CREATE TABLE addressbooks (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -135,13 +129,13 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
|
||||
$pdo->exec("ALTER TABLE $tableName RENAME TO $tableNameOld");
|
||||
|
||||
switch ($itemType) {
|
||||
case 'calendar' :
|
||||
$pdo->exec("
|
||||
case 'calendar':
|
||||
$pdo->exec('
|
||||
CREATE TABLE calendars (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
|
|
@ -155,10 +149,10 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
components text,
|
||||
transparent bool
|
||||
);
|
||||
");
|
||||
');
|
||||
break;
|
||||
case 'addressbook' :
|
||||
$pdo->exec("
|
||||
case 'addressbook':
|
||||
$pdo->exec('
|
||||
CREATE TABLE addressbooks (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
|
|
@ -167,45 +161,37 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
description text,
|
||||
synctoken integer
|
||||
);
|
||||
");
|
||||
');
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
echo "Creation of 2.0 $tableName table is complete\n";
|
||||
|
||||
} else {
|
||||
|
||||
// Checking if there's a synctoken field already.
|
||||
if (array_key_exists('synctoken', $row)) {
|
||||
echo "The 'synctoken' field already exists in the $tableName table.\n";
|
||||
echo "It's likely you already upgraded, so we're simply leaving\n";
|
||||
echo "the $tableName table alone\n";
|
||||
} else {
|
||||
|
||||
echo "1.8 table schema detected\n";
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec("ALTER TABLE $tableName ADD synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1'");
|
||||
$pdo->exec("ALTER TABLE $tableName DROP ctag");
|
||||
$pdo->exec("UPDATE $tableName SET synctoken = '1'");
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec("ALTER TABLE $tableName ADD synctoken integer");
|
||||
$pdo->exec("UPDATE $tableName SET synctoken = '1'");
|
||||
echo "Note: there's no easy way to remove fields in sqlite.\n";
|
||||
echo "The ctag field is no longer used, but it's kept in place\n";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
echo "Upgraded '$tableName' to 2.0 schema.\n";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -213,13 +199,11 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
|
||||
echo "'$changesTable' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Creating '$changesTable' table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec("
|
||||
CREATE TABLE $changesTable (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -232,7 +216,7 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
|
||||
");
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec("
|
||||
|
||||
CREATE TABLE $changesTable (
|
||||
|
|
@ -246,25 +230,20 @@ foreach (['calendar', 'addressbook'] as $itemType) {
|
|||
");
|
||||
$pdo->exec("CREATE INDEX {$itemType}id_synctoken ON $changesTable ({$itemType}id, synctoken);");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->query("SELECT * FROM calendarsubscriptions LIMIT 1");
|
||||
$pdo->query('SELECT * FROM calendarsubscriptions LIMIT 1');
|
||||
|
||||
echo "'calendarsubscriptions' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Creating calendarsubscriptions table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec("
|
||||
CREATE TABLE calendarsubscriptions (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -283,8 +262,8 @@ CREATE TABLE calendarsubscriptions (
|
|||
);
|
||||
");
|
||||
break;
|
||||
case 'sqlite' :
|
||||
$pdo->exec("
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
|
||||
CREATE TABLE calendarsubscriptions (
|
||||
id integer primary key asc,
|
||||
|
|
@ -300,64 +279,57 @@ CREATE TABLE calendarsubscriptions (
|
|||
stripattachments bool,
|
||||
lastmodified int
|
||||
);
|
||||
");
|
||||
');
|
||||
|
||||
$pdo->exec("CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);");
|
||||
$pdo->exec('CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->query("SELECT * FROM propertystorage LIMIT 1");
|
||||
$pdo->query('SELECT * FROM propertystorage LIMIT 1');
|
||||
|
||||
echo "'propertystorage' already exists. Assuming that this part of the\n";
|
||||
echo "upgrade was already completed.\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Creating propertystorage table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
$pdo->exec("
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
path VARBINARY(1024) NOT NULL,
|
||||
name VARBINARY(100) NOT NULL,
|
||||
value MEDIUMBLOB
|
||||
);
|
||||
");
|
||||
$pdo->exec("
|
||||
');
|
||||
$pdo->exec('
|
||||
CREATE UNIQUE INDEX path_property ON propertystorage (path(600), name(100));
|
||||
");
|
||||
');
|
||||
break;
|
||||
case 'sqlite' :
|
||||
$pdo->exec("
|
||||
case 'sqlite':
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id integer primary key asc,
|
||||
path TEXT,
|
||||
name TEXT,
|
||||
value TEXT
|
||||
);
|
||||
");
|
||||
$pdo->exec("
|
||||
');
|
||||
$pdo->exec('
|
||||
CREATE UNIQUE INDEX path_property ON propertystorage (path, name);
|
||||
");
|
||||
');
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
echo "Upgrading cards table to 2.0 schema\n";
|
||||
|
||||
try {
|
||||
|
||||
$create = false;
|
||||
$row = $pdo->query("SELECT * FROM cards LIMIT 1")->fetch();
|
||||
$row = $pdo->query('SELECT * FROM cards LIMIT 1')->fetch();
|
||||
if (!$row) {
|
||||
$random = mt_rand(1000, 9999);
|
||||
echo "There was no data in the cards table, so we're re-creating it\n";
|
||||
|
|
@ -366,28 +338,24 @@ try {
|
|||
$create = true;
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec("RENAME TABLE cards TO cards_old$random");
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec("ALTER TABLE cards RENAME TO cards_old$random");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
echo "Exception while checking cards table. Assuming that the table does not yet exist.\n";
|
||||
echo "Debug: ", $e->getMessage(), "\n";
|
||||
echo 'Debug: ', $e->getMessage(), "\n";
|
||||
$create = true;
|
||||
|
||||
}
|
||||
|
||||
if ($create) {
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
$pdo->exec("
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
CREATE TABLE cards (
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
addressbookid INT(11) UNSIGNED NOT NULL,
|
||||
|
|
@ -398,12 +366,12 @@ CREATE TABLE cards (
|
|||
size INT(11) UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
");
|
||||
');
|
||||
break;
|
||||
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
|
||||
$pdo->exec("
|
||||
$pdo->exec('
|
||||
CREATE TABLE cards (
|
||||
id integer primary key asc,
|
||||
addressbookid integer,
|
||||
|
|
@ -413,28 +381,26 @@ CREATE TABLE cards (
|
|||
etag text,
|
||||
size integer
|
||||
);
|
||||
");
|
||||
');
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
$pdo->exec("
|
||||
case 'mysql':
|
||||
$pdo->exec('
|
||||
ALTER TABLE cards
|
||||
ADD etag VARBINARY(32),
|
||||
ADD size INT(11) UNSIGNED NOT NULL;
|
||||
");
|
||||
');
|
||||
break;
|
||||
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
|
||||
$pdo->exec("
|
||||
$pdo->exec('
|
||||
ALTER TABLE cards ADD etag text;
|
||||
ALTER TABLE cards ADD size integer;
|
||||
");
|
||||
');
|
||||
break;
|
||||
|
||||
}
|
||||
echo "Reading all old vcards and populating etag and size fields.\n";
|
||||
$result = $pdo->query('SELECT id, carddata FROM cards');
|
||||
|
|
@ -443,11 +409,9 @@ CREATE TABLE cards (
|
|||
$stmt->execute([
|
||||
md5($row['carddata']),
|
||||
strlen($row['carddata']),
|
||||
$row['id']
|
||||
$row['id'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo "Upgrade to 2.0 schema completed.\n";
|
||||
|
|
|
|||
36
htdocs/includes/sabre/sabre/dav/bin/migrateto21.php
Normal file → Executable file
36
htdocs/includes/sabre/sabre/dav/bin/migrateto21.php
Normal file → Executable file
|
|
@ -4,7 +4,6 @@
|
|||
echo "SabreDAV migrate script for version 2.1\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-2.1 database to 2.1.
|
||||
|
|
@ -37,14 +36,13 @@ 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',
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
|
@ -58,7 +56,7 @@ $dsn = $argv[1];
|
|||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo "Connecting to database: " . $dsn . "\n";
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
|
@ -67,15 +65,14 @@ $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default :
|
||||
echo "Error: unsupported driver: " . $driver . "\n";
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
die(-1);
|
||||
}
|
||||
|
||||
|
|
@ -95,19 +92,17 @@ try {
|
|||
echo "2.0 schema detected.\n";
|
||||
$addUid = true;
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Could not find a calendarobjects table. Skipping this part of the\n";
|
||||
echo "upgrade.\n";
|
||||
}
|
||||
|
||||
if ($addUid) {
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec('ALTER TABLE calendarobjects ADD uid VARCHAR(200)');
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE calendarobjects ADD uid TEXT');
|
||||
break;
|
||||
}
|
||||
|
|
@ -117,7 +112,6 @@ if ($addUid) {
|
|||
$counter = 0;
|
||||
|
||||
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
try {
|
||||
$vobj = \Sabre\VObject\Reader::read($row['calendardata']);
|
||||
} catch (\Exception $e) {
|
||||
|
|
@ -130,19 +124,16 @@ if ($addUid) {
|
|||
echo "Warning! Item with id $item[id] does NOT have a UID property and this is required.\n";
|
||||
continue;
|
||||
}
|
||||
$uid = (string)$item->UID;
|
||||
$uid = (string) $item->UID;
|
||||
$stmt->execute([$uid, $row['id']]);
|
||||
$counter++;
|
||||
|
||||
++$counter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
echo "Creating 'schedulingobjects'\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects
|
||||
(
|
||||
id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -156,8 +147,7 @@ switch ($driver) {
|
|||
');
|
||||
break;
|
||||
|
||||
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects (
|
||||
id integer primary key asc,
|
||||
principaluri text,
|
||||
|
|
|
|||
44
htdocs/includes/sabre/sabre/dav/bin/migrateto30.php
Normal file → Executable file
44
htdocs/includes/sabre/sabre/dav/bin/migrateto30.php
Normal file → Executable file
|
|
@ -4,7 +4,6 @@
|
|||
echo "SabreDAV migrate script for version 3.0\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a pre-3.0 database to 3.0 and later
|
||||
|
|
@ -36,14 +35,13 @@ 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',
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
|
@ -57,7 +55,7 @@ $dsn = $argv[1];
|
|||
$user = isset($argv[2]) ? $argv[2] : null;
|
||||
$pass = isset($argv[3]) ? $argv[3] : null;
|
||||
|
||||
echo "Connecting to database: " . $dsn . "\n";
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
|
@ -66,15 +64,14 @@ $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default :
|
||||
echo "Error: unsupported driver: " . $driver . "\n";
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
die(-1);
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +87,8 @@ try {
|
|||
echo "Renaming propertystorage -> propertystorage_old$random and creating new table.\n";
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
$pdo->exec('RENAME TABLE propertystorage TO propertystorage_old' . $random);
|
||||
case 'mysql':
|
||||
$pdo->exec('RENAME TABLE propertystorage TO propertystorage_old'.$random);
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -102,10 +98,10 @@ try {
|
|||
value MEDIUMBLOB
|
||||
);
|
||||
');
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_' . $random . ' ON propertystorage (path(600), name(100));');
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path(600), name(100));');
|
||||
break;
|
||||
case 'sqlite' :
|
||||
$pdo->exec('ALTER TABLE propertystorage RENAME TO propertystorage_old' . $random);
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE propertystorage RENAME TO propertystorage_old'.$random);
|
||||
$pdo->exec('
|
||||
CREATE TABLE propertystorage (
|
||||
id integer primary key asc,
|
||||
|
|
@ -115,9 +111,8 @@ CREATE TABLE propertystorage (
|
|||
value blob
|
||||
);');
|
||||
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_' . $random . ' ON propertystorage (path, name);');
|
||||
$pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path, name);');
|
||||
break;
|
||||
|
||||
}
|
||||
} elseif (array_key_exists('valuetype', $row)) {
|
||||
echo "valuetype field exists. Assuming that this part of the migration has\n";
|
||||
|
|
@ -126,7 +121,6 @@ CREATE TABLE propertystorage (
|
|||
echo "2.1 schema detected. Going to perform upgrade.\n";
|
||||
$addValueType = true;
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "Could not find a propertystorage table. Skipping this part of the\n";
|
||||
echo "upgrade.\n";
|
||||
|
|
@ -134,19 +128,17 @@ CREATE TABLE propertystorage (
|
|||
}
|
||||
|
||||
if ($addValueType) {
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec('ALTER TABLE propertystorage ADD valuetype INT UNSIGNED');
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE propertystorage ADD valuetype INT');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$pdo->exec('UPDATE propertystorage SET valuetype = 1 WHERE valuetype IS NULL ');
|
||||
|
||||
}
|
||||
|
||||
echo "Migrating vcardurl\n";
|
||||
|
|
@ -155,16 +147,14 @@ $result = $pdo->query('SELECT id, uri, vcardurl FROM principals WHERE vcardurl I
|
|||
$stmt1 = $pdo->prepare('INSERT INTO propertystorage (path, name, valuetype, value) VALUES (?, ?, 3, ?)');
|
||||
|
||||
while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
// Inserting the new record
|
||||
$stmt1->execute([
|
||||
'addressbooks/' . basename($row['uri']),
|
||||
'addressbooks/'.basename($row['uri']),
|
||||
'{http://calendarserver.org/ns/}me-card',
|
||||
serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl']))
|
||||
serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl'])),
|
||||
]);
|
||||
|
||||
echo serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl']));
|
||||
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
|
|
|
|||
54
htdocs/includes/sabre/sabre/dav/bin/migrateto32.php
Normal file → Executable file
54
htdocs/includes/sabre/sabre/dav/bin/migrateto32.php
Normal file → Executable file
|
|
@ -4,7 +4,6 @@
|
|||
echo "SabreDAV migrate script for version 3.2\n";
|
||||
|
||||
if ($argc < 2) {
|
||||
|
||||
echo <<<HELLO
|
||||
|
||||
This script help you migrate from a 3.1 database to 3.2 and later
|
||||
|
|
@ -37,14 +36,13 @@ 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',
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
|
@ -60,7 +58,7 @@ $pass = isset($argv[3]) ? $argv[3] : null;
|
|||
|
||||
$backupPostfix = time();
|
||||
|
||||
echo "Connecting to database: " . $dsn . "\n";
|
||||
echo 'Connecting to database: '.$dsn."\n";
|
||||
|
||||
$pdo = new PDO($dsn, $user, $pass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
|
@ -69,15 +67,14 @@ $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|||
$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
switch ($driver) {
|
||||
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
echo "Detected MySQL.\n";
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
echo "Detected SQLite.\n";
|
||||
break;
|
||||
default :
|
||||
echo "Error: unsupported driver: " . $driver . "\n";
|
||||
default:
|
||||
echo 'Error: unsupported driver: '.$driver."\n";
|
||||
die(-1);
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +88,7 @@ try {
|
|||
echo "calendarinstances does not yet exist. Creating table and migrating data.\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendarinstances (
|
||||
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -114,7 +111,7 @@ CREATE TABLE calendarinstances (
|
|||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
SQL
|
||||
);
|
||||
$pdo->exec("
|
||||
$pdo->exec('
|
||||
INSERT INTO calendarinstances
|
||||
(
|
||||
calendarid,
|
||||
|
|
@ -138,9 +135,9 @@ SELECT
|
|||
calendarcolor,
|
||||
transparent
|
||||
FROM calendars
|
||||
");
|
||||
');
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendarinstances (
|
||||
id integer primary key asc NOT NULL,
|
||||
|
|
@ -163,7 +160,7 @@ CREATE TABLE calendarinstances (
|
|||
);
|
||||
SQL
|
||||
);
|
||||
$pdo->exec("
|
||||
$pdo->exec('
|
||||
INSERT INTO calendarinstances
|
||||
(
|
||||
calendarid,
|
||||
|
|
@ -187,10 +184,9 @@ SELECT
|
|||
calendarcolor,
|
||||
transparent
|
||||
FROM calendars
|
||||
");
|
||||
');
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
try {
|
||||
$result = $pdo->query('SELECT * FROM calendars LIMIT 1');
|
||||
|
|
@ -202,37 +198,34 @@ try {
|
|||
}
|
||||
|
||||
$columnCount = count($row);
|
||||
if ($columnCount === 3) {
|
||||
if (3 === $columnCount) {
|
||||
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";
|
||||
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_1_' . $backupPostfix;
|
||||
$calendarBackup = 'calendars_3_1_'.$backupPostfix;
|
||||
echo "Backing up 'calendars' to '", $calendarBackup, "'\n";
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
$pdo->exec('RENAME TABLE calendars TO ' . $calendarBackup);
|
||||
case 'mysql':
|
||||
$pdo->exec('RENAME TABLE calendars TO '.$calendarBackup);
|
||||
break;
|
||||
case 'sqlite' :
|
||||
$pdo->exec('ALTER TABLE calendars RENAME TO ' . $calendarBackup);
|
||||
case 'sqlite':
|
||||
$pdo->exec('ALTER TABLE calendars RENAME TO '.$calendarBackup);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
echo "Creating new calendars table.\n";
|
||||
switch ($driver) {
|
||||
case 'mysql' :
|
||||
case 'mysql':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendars (
|
||||
id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
|
|
@ -242,7 +235,7 @@ CREATE TABLE calendars (
|
|||
SQL
|
||||
);
|
||||
break;
|
||||
case 'sqlite' :
|
||||
case 'sqlite':
|
||||
$pdo->exec(<<<SQL
|
||||
CREATE TABLE calendars (
|
||||
id integer primary key asc NOT NULL,
|
||||
|
|
@ -252,7 +245,6 @@ CREATE TABLE calendars (
|
|||
SQL
|
||||
);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
echo "Migrating data from old to new table\n";
|
||||
|
|
@ -261,8 +253,6 @@ SQL
|
|||
INSERT INTO calendars (id, synctoken, components) SELECT id, synctoken, COALESCE(components,"VEVENT,VTODO,VJOURNAL") as components FROM $calendarBackup
|
||||
SQL
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
echo "Upgrade to 3.2 schema completed.\n";
|
||||
|
|
|
|||
0
htdocs/includes/sabre/sabre/dav/bin/naturalselection
Normal file → Executable file
0
htdocs/includes/sabre/sabre/dav/bin/naturalselection
Normal file → Executable file
0
htdocs/includes/sabre/sabre/dav/bin/sabredav
Normal file → Executable file
0
htdocs/includes/sabre/sabre/dav/bin/sabredav
Normal file → Executable file
26
htdocs/includes/sabre/sabre/dav/bin/sabredav.php
Normal file → Executable file
26
htdocs/includes/sabre/sabre/dav/bin/sabredav.php
Normal file → Executable file
|
|
@ -2,34 +2,32 @@
|
|||
|
||||
// SabreDAV test server.
|
||||
|
||||
class CliLog {
|
||||
|
||||
class CliLog
|
||||
{
|
||||
protected $stream;
|
||||
|
||||
function __construct() {
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->stream = fopen('php://stdout', 'w');
|
||||
|
||||
}
|
||||
|
||||
function log($msg) {
|
||||
fwrite($this->stream, $msg . "\n");
|
||||
public function log($msg)
|
||||
{
|
||||
fwrite($this->stream, $msg."\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$log = new CliLog();
|
||||
|
||||
if (php_sapi_name() !== 'cli-server') {
|
||||
die("This script is intended to run on the built-in php webserver");
|
||||
if ('cli-server' !== php_sapi_name()) {
|
||||
die('This script is intended to run on the built-in php webserver');
|
||||
}
|
||||
|
||||
// Finding composer
|
||||
|
||||
|
||||
$paths = [
|
||||
__DIR__ . '/../vendor/autoload.php',
|
||||
__DIR__ . '/../../../autoload.php',
|
||||
__DIR__.'/../vendor/autoload.php',
|
||||
__DIR__.'/../../../autoload.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
|
|
@ -41,7 +39,7 @@ foreach ($paths as $path) {
|
|||
|
||||
use Sabre\DAV;
|
||||
|
||||
// Root
|
||||
// Root
|
||||
$root = new DAV\FS\Directory(getcwd());
|
||||
|
||||
// Setting up server.
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@
|
|||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"php": ">=7.0.0",
|
||||
"sabre/vobject": "^4.2.2",
|
||||
"sabre/event" : ">=2.0.0, <4.0.0",
|
||||
"sabre/xml" : "^1.4.0",
|
||||
"sabre/http" : "^4.2.1",
|
||||
"sabre/uri" : "^1.0.1",
|
||||
"sabre/event" : "^5.0",
|
||||
"sabre/xml" : "^2.2.5",
|
||||
"sabre/http" : "^5.0.5",
|
||||
"sabre/uri" : "^2.2.3",
|
||||
"ext-dom": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-spl": "*",
|
||||
|
|
@ -29,17 +29,18 @@
|
|||
"ext-date" : "*",
|
||||
"ext-iconv" : "*",
|
||||
"lib-libxml" : ">=2.7.0",
|
||||
"psr/log": "^1.0"
|
||||
"psr/log": "^1.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "> 4.8, <6.0.0",
|
||||
"phpunit/phpunit" : "^6",
|
||||
"evert/phpdoc-md" : "~0.1.0",
|
||||
"sabre/cs" : "^1.0.0",
|
||||
"monolog/monolog": "^1.18"
|
||||
},
|
||||
"suggest" : {
|
||||
"ext-curl" : "*",
|
||||
"ext-pdo" : "*"
|
||||
"ext-pdo" : "*",
|
||||
"ext-imap": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4" : {
|
||||
|
|
@ -59,10 +60,5 @@
|
|||
],
|
||||
"config" : {
|
||||
"bin-dir" : "./bin"
|
||||
},
|
||||
"extra" : {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -14,8 +16,8 @@ use Sabre\VObject;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
abstract class AbstractBackend implements BackendInterface {
|
||||
|
||||
abstract class AbstractBackend implements BackendInterface
|
||||
{
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
*
|
||||
|
|
@ -28,12 +30,11 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param mixed $calendarId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
|
||||
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -46,14 +47,14 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* @param mixed $calendarId
|
||||
* @param array $uris
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleCalendarObjects($calendarId, array $uris) {
|
||||
|
||||
return array_map(function($uri) use ($calendarId) {
|
||||
public function getMultipleCalendarObjects($calendarId, array $uris)
|
||||
{
|
||||
return array_map(function ($uri) use ($calendarId) {
|
||||
return $this->getCalendarObject($calendarId, $uri);
|
||||
}, $uris);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,23 +104,21 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* @param mixed $calendarId
|
||||
* @param array $filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function calendarQuery($calendarId, array $filters) {
|
||||
|
||||
public function calendarQuery($calendarId, array $filters)
|
||||
{
|
||||
$result = [];
|
||||
$objects = $this->getCalendarObjects($calendarId);
|
||||
|
||||
foreach ($objects as $object) {
|
||||
|
||||
if ($this->validateFilterForObject($object, $filters)) {
|
||||
$result[] = $object['uri'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -128,10 +127,11 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* @param array $object
|
||||
* @param array $filters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFilterForObject(array $object, array $filters) {
|
||||
|
||||
protected function validateFilterForObject(array $object, array $filters)
|
||||
{
|
||||
// Unfortunately, setting the 'calendardata' here is optional. If
|
||||
// it was excluded, we actually need another call to get this as
|
||||
// well.
|
||||
|
|
@ -148,7 +148,6 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
$vObject->destroy();
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -168,14 +167,14 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getCalendarObjectByUID($principalUri, $uid) {
|
||||
|
||||
public function getCalendarObjectByUID($principalUri, $uid)
|
||||
{
|
||||
// Note: this is a super slow naive implementation of this method. You
|
||||
// are highly recommended to optimize it, if your backend allows it.
|
||||
foreach ($this->getCalendarsForUser($principalUri) as $calendar) {
|
||||
|
||||
// We must ignore calendars owned by other principals.
|
||||
if ($calendar['principaluri'] !== $principalUri) {
|
||||
continue;
|
||||
|
|
@ -189,38 +188,35 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
$results = $this->calendarQuery(
|
||||
$calendar['id'],
|
||||
[
|
||||
'name' => 'VCALENDAR',
|
||||
'name' => 'VCALENDAR',
|
||||
'prop-filters' => [],
|
||||
'comp-filters' => [
|
||||
[
|
||||
'name' => 'VEVENT',
|
||||
'name' => 'VEVENT',
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [
|
||||
'time-range' => null,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [
|
||||
[
|
||||
'name' => 'UID',
|
||||
'name' => 'UID',
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
'text-match' => [
|
||||
'value' => $uid,
|
||||
'time-range' => null,
|
||||
'text-match' => [
|
||||
'value' => $uid,
|
||||
'negate-condition' => false,
|
||||
'collation' => 'i;octet',
|
||||
'collation' => 'i;octet',
|
||||
],
|
||||
'param-filters' => [],
|
||||
],
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
if ($results) {
|
||||
// We have a match
|
||||
return $calendar['uri'] . '/' . $results[0];
|
||||
return $calendar['uri'].'/'.$results[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
|
|
@ -9,8 +11,8 @@ namespace Sabre\CalDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface BackendInterface {
|
||||
|
||||
interface BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of calendars for a principal.
|
||||
*
|
||||
|
|
@ -34,9 +36,10 @@ interface BackendInterface {
|
|||
* ACL will automatically be put in read-only mode.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarsForUser($principalUri);
|
||||
public function getCalendarsForUser($principalUri);
|
||||
|
||||
/**
|
||||
* Creates a new calendar for a principal.
|
||||
|
|
@ -48,10 +51,11 @@ interface BackendInterface {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
* @param array $properties
|
||||
* @param array $properties
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function createCalendar($principalUri, $calendarUri, array $properties);
|
||||
public function createCalendar($principalUri, $calendarUri, array $properties);
|
||||
|
||||
/**
|
||||
* Updates properties for a calendar.
|
||||
|
|
@ -65,19 +69,17 @@ interface BackendInterface {
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param mixed $calendarId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch);
|
||||
public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch);
|
||||
|
||||
/**
|
||||
* Delete a calendar and all its objects
|
||||
* Delete a calendar and all its objects.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendar($calendarId);
|
||||
public function deleteCalendar($calendarId);
|
||||
|
||||
/**
|
||||
* Returns all calendar objects within a calendar.
|
||||
|
|
@ -108,9 +110,10 @@ interface BackendInterface {
|
|||
* amount of times this is needed is reduced by a great degree.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObjects($calendarId);
|
||||
public function getCalendarObjects($calendarId);
|
||||
|
||||
/**
|
||||
* Returns information from a single calendar object, based on it's object
|
||||
|
|
@ -124,11 +127,12 @@ interface BackendInterface {
|
|||
*
|
||||
* This method must return null if the object did not exist.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function getCalendarObject($calendarId, $objectUri);
|
||||
public function getCalendarObject($calendarId, $objectUri);
|
||||
|
||||
/**
|
||||
* Returns a list of calendar objects.
|
||||
|
|
@ -140,9 +144,10 @@ interface BackendInterface {
|
|||
*
|
||||
* @param mixed $calendarId
|
||||
* @param array $uris
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleCalendarObjects($calendarId, array $uris);
|
||||
public function getMultipleCalendarObjects($calendarId, array $uris);
|
||||
|
||||
/**
|
||||
* Creates a new calendar object.
|
||||
|
|
@ -157,12 +162,13 @@ interface BackendInterface {
|
|||
* 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 mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
public function createCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
|
||||
/**
|
||||
* Updates an existing calendarobject, based on it's uri.
|
||||
|
|
@ -177,23 +183,23 @@ interface BackendInterface {
|
|||
* 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 mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function updateCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
public function updateCalendarObject($calendarId, $objectUri, $calendarData);
|
||||
|
||||
/**
|
||||
* Deletes an existing calendar object.
|
||||
*
|
||||
* The object uri is only the basename, or filename and not a full path.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri);
|
||||
public function deleteCalendarObject($calendarId, $objectUri);
|
||||
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
|
|
@ -242,9 +248,10 @@ interface BackendInterface {
|
|||
*
|
||||
* @param mixed $calendarId
|
||||
* @param array $filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function calendarQuery($calendarId, array $filters);
|
||||
public function calendarQuery($calendarId, array $filters);
|
||||
|
||||
/**
|
||||
* Searches through all of a users calendars and calendar objects to find
|
||||
|
|
@ -263,8 +270,8 @@ interface BackendInterface {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getCalendarObjectByUID($principalUri, $uid);
|
||||
|
||||
public function getCalendarObjectByUID($principalUri, $uid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
||||
|
|
@ -22,26 +24,26 @@ use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface NotificationSupport extends BackendInterface {
|
||||
|
||||
interface NotificationSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of notifications for a given principal url.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return NotificationInterface[]
|
||||
*/
|
||||
function getNotificationsForPrincipal($principalUri);
|
||||
public function getNotificationsForPrincipal($principalUri);
|
||||
|
||||
/**
|
||||
* This deletes a specific notifcation.
|
||||
*
|
||||
* This may be called by a client once it deems a notification handled.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $principalUri
|
||||
* @param NotificationInterface $notification
|
||||
* @return void
|
||||
*/
|
||||
function deleteNotification($principalUri, NotificationInterface $notification);
|
||||
public function deleteNotification($principalUri, NotificationInterface $notification);
|
||||
|
||||
/**
|
||||
* This method is called when a user replied to a request to share.
|
||||
|
|
@ -49,13 +51,13 @@ interface NotificationSupport extends BackendInterface {
|
|||
* If the user chose to accept the share, this method should return the
|
||||
* newly created calendar url.
|
||||
*
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $calendarUri The url to the calendar thats being shared
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
* @return null|string
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
|
||||
|
||||
public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
|
|
@ -10,8 +12,8 @@ namespace Sabre\CalDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SchedulingSupport extends BackendInterface {
|
||||
|
||||
interface SchedulingSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a single scheduling object for the inbox collection.
|
||||
*
|
||||
|
|
@ -26,9 +28,10 @@ interface SchedulingSupport extends BackendInterface {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getSchedulingObject($principalUri, $objectUri);
|
||||
public function getSchedulingObject($principalUri, $objectUri);
|
||||
|
||||
/**
|
||||
* Returns all scheduling objects for the inbox collection.
|
||||
|
|
@ -39,18 +42,18 @@ interface SchedulingSupport extends BackendInterface {
|
|||
* The main difference is that 'calendardata' is optional.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getSchedulingObjects($principalUri);
|
||||
public function getSchedulingObjects($principalUri);
|
||||
|
||||
/**
|
||||
* Deletes a scheduling object from the inbox collection.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
* @return void
|
||||
*/
|
||||
function deleteSchedulingObject($principalUri, $objectUri);
|
||||
public function deleteSchedulingObject($principalUri, $objectUri);
|
||||
|
||||
/**
|
||||
* Creates a new scheduling object. This should land in a users' inbox.
|
||||
|
|
@ -58,8 +61,6 @@ interface SchedulingSupport extends BackendInterface {
|
|||
* @param string $principalUri
|
||||
* @param string $objectUri
|
||||
* @param string $objectData
|
||||
* @return void
|
||||
*/
|
||||
function createSchedulingObject($principalUri, $objectUri, $objectData);
|
||||
|
||||
public function createSchedulingObject($principalUri, $objectUri, $objectData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
|
|
@ -20,16 +22,15 @@ namespace Sabre\CalDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SharingSupport extends BackendInterface {
|
||||
|
||||
interface SharingSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Updates the list of shares.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param mixed $calendarId
|
||||
* @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
|
||||
* @return void
|
||||
*/
|
||||
function updateInvites($calendarId, array $sharees);
|
||||
public function updateInvites($calendarId, array $sharees);
|
||||
|
||||
/**
|
||||
* Returns the list of people whom this calendar is shared with.
|
||||
|
|
@ -44,17 +45,16 @@ interface SharingSupport extends BackendInterface {
|
|||
* $properties
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
*
|
||||
* @return \Sabre\DAV\Xml\Element\Sharee[]
|
||||
*/
|
||||
function getInvites($calendarId);
|
||||
public function getInvites($calendarId);
|
||||
|
||||
/**
|
||||
* Publishes a calendar
|
||||
* Publishes a calendar.
|
||||
*
|
||||
* @param mixed $calendarId
|
||||
* @param bool $value
|
||||
* @return void
|
||||
* @param bool $value
|
||||
*/
|
||||
function setPublishStatus($calendarId, $value);
|
||||
|
||||
public function setPublishStatus($calendarId, $value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -31,24 +33,23 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SimplePDO extends AbstractBackend {
|
||||
|
||||
class SimplePDO extends AbstractBackend
|
||||
{
|
||||
/**
|
||||
* pdo
|
||||
* pdo.
|
||||
*
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* Creates the backend
|
||||
* Creates the backend.
|
||||
*
|
||||
* @param \PDO $pdo
|
||||
*/
|
||||
function __construct(\PDO $pdo) {
|
||||
|
||||
public function __construct(\PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,27 +74,25 @@ class SimplePDO extends AbstractBackend {
|
|||
* ACL will automatically be put in read-only mode.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarsForUser($principalUri) {
|
||||
|
||||
public function getCalendarsForUser($principalUri)
|
||||
{
|
||||
// Making fields a comma-delimited list
|
||||
$stmt = $this->pdo->prepare("SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC");
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC');
|
||||
$stmt->execute([$principalUri]);
|
||||
|
||||
$calendars = [];
|
||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$calendars[] = [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'principaluri' => $principalUri,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $calendars;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -104,32 +103,30 @@ class SimplePDO extends AbstractBackend {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $calendarUri
|
||||
* @param array $properties
|
||||
* @param array $properties
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function createCalendar($principalUri, $calendarUri, array $properties) {
|
||||
|
||||
$stmt = $this->pdo->prepare("INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)");
|
||||
public 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
|
||||
* Delete a calendar and all it's objects.
|
||||
*
|
||||
* @param string $calendarId
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendar($calendarId) {
|
||||
|
||||
public 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]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -161,27 +158,27 @@ class SimplePDO extends AbstractBackend {
|
|||
* amount of times this is needed is reduced by a great degree.
|
||||
*
|
||||
* @param string $calendarId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCalendarObjects($calendarId) {
|
||||
|
||||
public 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']),
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'etag' => '"'.md5($row['calendardata']).'"',
|
||||
'calendarid' => $calendarId,
|
||||
'size' => strlen($row['calendardata']),
|
||||
'calendardata' => $row['calendardata'],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,25 +195,27 @@ class SimplePDO extends AbstractBackend {
|
|||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function getCalendarObject($calendarId, $objectUri) {
|
||||
|
||||
public 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;
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'etag' => '"' . md5($row['calendardata']) . '"',
|
||||
'calendarid' => $calendarId,
|
||||
'size' => strlen($row['calendardata']),
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'etag' => '"'.md5($row['calendardata']).'"',
|
||||
'calendarid' => $calendarId,
|
||||
'size' => strlen($row['calendardata']),
|
||||
'calendardata' => $row['calendardata'],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -232,22 +231,22 @@ class SimplePDO extends AbstractBackend {
|
|||
* 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 mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createCalendarObject($calendarId, $objectUri, $calendarData) {
|
||||
|
||||
public function createCalendarObject($calendarId, $objectUri, $calendarData)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
|
||||
$stmt->execute([
|
||||
$calendarId,
|
||||
$objectUri,
|
||||
$calendarData
|
||||
$calendarData,
|
||||
]);
|
||||
|
||||
return '"' . md5($calendarData) . '"';
|
||||
|
||||
return '"'.md5($calendarData).'"';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -263,18 +262,18 @@ class SimplePDO extends AbstractBackend {
|
|||
* 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 mixed $calendarId
|
||||
* @param string $objectUri
|
||||
* @param string $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function updateCalendarObject($calendarId, $objectUri, $calendarData) {
|
||||
|
||||
public 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) . '"';
|
||||
|
||||
return '"'.md5($calendarData).'"';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -284,13 +283,10 @@ class SimplePDO extends AbstractBackend {
|
|||
*
|
||||
* @param string $calendarId
|
||||
* @param string $objectUri
|
||||
* @return void
|
||||
*/
|
||||
function deleteCalendarObject($calendarId, $objectUri) {
|
||||
|
||||
public function deleteCalendarObject($calendarId, $objectUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
|
||||
$stmt->execute([$calendarId, $objectUri]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -11,8 +13,8 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SubscriptionSupport extends BackendInterface {
|
||||
|
||||
interface SubscriptionSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of subscriptions for a principal.
|
||||
*
|
||||
|
|
@ -43,9 +45,10 @@ interface SubscriptionSupport extends BackendInterface {
|
|||
* default components).
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getSubscriptionsForUser($principalUri);
|
||||
public function getSubscriptionsForUser($principalUri);
|
||||
|
||||
/**
|
||||
* Creates a new subscription for a principal.
|
||||
|
|
@ -55,13 +58,14 @@ interface SubscriptionSupport extends BackendInterface {
|
|||
*
|
||||
* @param string $principalUri
|
||||
* @param string $uri
|
||||
* @param array $properties
|
||||
* @param array $properties
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function createSubscription($principalUri, $uri, array $properties);
|
||||
public function createSubscription($principalUri, $uri, array $properties);
|
||||
|
||||
/**
|
||||
* Updates a subscription
|
||||
* Updates a subscription.
|
||||
*
|
||||
* The list of mutations is stored in a Sabre\DAV\PropPatch object.
|
||||
* To do the actual updates, you must tell this object which properties
|
||||
|
|
@ -72,18 +76,15 @@ interface SubscriptionSupport extends BackendInterface {
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param mixed $subscriptionId
|
||||
* @param mixed $subscriptionId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateSubscription($subscriptionId, DAV\PropPatch $propPatch);
|
||||
public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch);
|
||||
|
||||
/**
|
||||
* Deletes a subscription.
|
||||
*
|
||||
* @param mixed $subscriptionId
|
||||
* @return void
|
||||
*/
|
||||
function deleteSubscription($subscriptionId);
|
||||
|
||||
public function deleteSubscription($subscriptionId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Backend;
|
||||
|
||||
/**
|
||||
|
|
@ -18,8 +20,8 @@ namespace Sabre\CalDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SyncSupport extends BackendInterface {
|
||||
|
||||
interface SyncSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* The getChanges method returns all the changes that have happened, since
|
||||
* the specified syncToken in the specified calendar.
|
||||
|
|
@ -72,10 +74,10 @@ interface SyncSupport extends BackendInterface {
|
|||
*
|
||||
* @param string $calendarId
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null);
|
||||
|
||||
public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -16,46 +18,44 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection, DAV\IMultiGet {
|
||||
|
||||
class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection, DAV\IMultiGet
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* This is an array with calendar information
|
||||
* This is an array with calendar information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $calendarInfo;
|
||||
|
||||
/**
|
||||
* CalDAV backend
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\BackendInterface $caldavBackend
|
||||
* @param array $calendarInfo
|
||||
* @param array $calendarInfo
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->calendarInfo = $calendarInfo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the calendar
|
||||
* Returns the name of the calendar.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->calendarInfo['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,69 +68,68 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
* Read the PropPatch documentation for more information.
|
||||
*
|
||||
* @param PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function propPatch(PropPatch $propPatch) {
|
||||
|
||||
public function propPatch(PropPatch $propPatch)
|
||||
{
|
||||
return $this->caldavBackend->updateCalendar($this->calendarInfo['id'], $propPatch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of properties
|
||||
* Returns the list of properties.
|
||||
*
|
||||
* @param array $requestedProperties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getProperties($requestedProperties) {
|
||||
|
||||
public function getProperties($requestedProperties)
|
||||
{
|
||||
$response = [];
|
||||
|
||||
foreach ($this->calendarInfo as $propName => $propValue) {
|
||||
|
||||
if (!is_null($propValue) && $propName[0] === '{')
|
||||
if (!is_null($propValue) && '{' === $propName[0]) {
|
||||
$response[$propName] = $this->calendarInfo[$propName];
|
||||
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a calendar object
|
||||
* Returns a calendar object.
|
||||
*
|
||||
* The contained calendar objects are for example Events or Todo's.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return \Sabre\CalDAV\ICalendarObject
|
||||
*/
|
||||
function getChild($name) {
|
||||
|
||||
public function getChild($name)
|
||||
{
|
||||
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
|
||||
|
||||
if (!$obj) throw new DAV\Exception\NotFound('Calendar object not found');
|
||||
|
||||
if (!$obj) {
|
||||
throw new DAV\Exception\NotFound('Calendar object not found');
|
||||
}
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
|
||||
return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full list of calendar objects
|
||||
* Returns the full list of calendar objects.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
}
|
||||
return $children;
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -140,77 +139,75 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
* If any children are not found, you do not have to return them.
|
||||
*
|
||||
* @param string[] $paths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleChildren(array $paths) {
|
||||
|
||||
public function getMultipleChildren(array $paths)
|
||||
{
|
||||
$objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj);
|
||||
}
|
||||
return $children;
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a child-node exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function childExists($name) {
|
||||
|
||||
public function childExists($name)
|
||||
{
|
||||
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name);
|
||||
if (!$obj)
|
||||
if (!$obj) {
|
||||
return false;
|
||||
else
|
||||
} else {
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory
|
||||
* Creates a new directory.
|
||||
*
|
||||
* We actually block this, as subdirectories are not allowed in calendars.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($name) {
|
||||
|
||||
public function createDirectory($name)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file
|
||||
* Creates a new file.
|
||||
*
|
||||
* The contents of the new file must be a valid ICalendar string.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @param resource $calendarData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createFile($name, $calendarData = null) {
|
||||
|
||||
public function createFile($name, $calendarData = null)
|
||||
{
|
||||
if (is_resource($calendarData)) {
|
||||
$calendarData = stream_get_contents($calendarData);
|
||||
}
|
||||
return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'], $name, $calendarData);
|
||||
|
||||
return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'], $name, $calendarData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the calendar.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteCalendar($this->calendarInfo['id']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -218,36 +215,30 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
* {DAV:}displayname to display a name to display a name.
|
||||
*
|
||||
* @param string $newName
|
||||
* @return void
|
||||
*/
|
||||
function setName($newName) {
|
||||
|
||||
public function setName($newName)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Renaming calendars is not yet supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->calendarInfo['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -262,8 +253,8 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
$acl = [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
|
|
@ -272,20 +263,19 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
|
||||
'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
],
|
||||
|
||||
];
|
||||
if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) {
|
||||
$acl[] = [
|
||||
|
|
@ -295,13 +285,12 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -311,8 +300,8 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildACL() {
|
||||
|
||||
public function getChildACL()
|
||||
{
|
||||
$acl = [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
|
|
@ -322,15 +311,14 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
|
||||
];
|
||||
if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) {
|
||||
$acl[] = [
|
||||
|
|
@ -340,16 +328,14 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
|
|
@ -365,12 +351,12 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
* documented by Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* @param array $filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function calendarQuery(array $filters) {
|
||||
|
||||
public function calendarQuery(array $filters)
|
||||
{
|
||||
return $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -382,8 +368,8 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getSyncToken() {
|
||||
|
||||
public function getSyncToken()
|
||||
{
|
||||
if (
|
||||
$this->caldavBackend instanceof Backend\SyncSupport &&
|
||||
isset($this->calendarInfo['{DAV:}sync-token'])
|
||||
|
|
@ -396,7 +382,6 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
) {
|
||||
return $this->calendarInfo['{http://sabredav.org/ns}sync-token'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -450,12 +435,13 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
* The limit is 'suggestive'. You are free to ignore it.
|
||||
*
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChanges($syncToken, $syncLevel, $limit = null) {
|
||||
|
||||
public function getChanges($syncToken, $syncLevel, $limit = null)
|
||||
{
|
||||
if (!$this->caldavBackend instanceof Backend\SyncSupport) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -466,7 +452,5 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
|
|||
$syncLevel,
|
||||
$limit
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\MkCol;
|
||||
use Sabre\DAVACL;
|
||||
use Sabre\HTTP\URLUtil;
|
||||
use Sabre\Uri;
|
||||
|
||||
/**
|
||||
* The CalendarHome represents a node that is usually in a users'
|
||||
|
|
@ -20,81 +22,74 @@ use Sabre\HTTP\URLUtil;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
||||
|
||||
class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* CalDAV backend
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Principal information
|
||||
* Principal information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalInfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\BackendInterface $caldavBackend
|
||||
* @param array $principalInfo
|
||||
* @param array $principalInfo
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $caldavBackend, $principalInfo) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, $principalInfo)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalInfo = $principalInfo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
public function getName()
|
||||
{
|
||||
list(, $name) = Uri\split($this->principalInfo['uri']);
|
||||
|
||||
list(, $name) = URLUtil::splitPath($this->principalInfo['uri']);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name of this object
|
||||
* Updates the name of this object.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function setName($name) {
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this object
|
||||
*
|
||||
* @return void
|
||||
* Deletes this object.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
throw new DAV\Exception\Forbidden();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date
|
||||
* Returns the last modification date.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,14 +97,12 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
*
|
||||
* This is currently not allowed
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $filename
|
||||
* @param resource $data
|
||||
* @return void
|
||||
*/
|
||||
function createFile($filename, $data = null) {
|
||||
|
||||
public function createFile($filename, $data = null)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,30 +111,29 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
* This is currently not allowed.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($filename) {
|
||||
|
||||
public function createDirectory($filename)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single calendar, by name
|
||||
* Returns a single calendar, by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Calendar
|
||||
*/
|
||||
function getChild($name) {
|
||||
|
||||
public function getChild($name)
|
||||
{
|
||||
// Special nodes
|
||||
if ($name === 'inbox' && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
if ('inbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
return new Schedule\Inbox($this->caldavBackend, $this->principalInfo['uri']);
|
||||
}
|
||||
if ($name === 'outbox' && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
if ('outbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) {
|
||||
return new Schedule\Outbox($this->principalInfo['uri']);
|
||||
}
|
||||
if ($name === 'notifications' && $this->caldavBackend instanceof Backend\NotificationSupport) {
|
||||
if ('notifications' === $name && $this->caldavBackend instanceof Backend\NotificationSupport) {
|
||||
return new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
|
||||
}
|
||||
|
||||
|
|
@ -162,36 +154,34 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
return new Subscriptions\Subscription($this->caldavBackend, $subscription);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new NotFound('Node with name \'' . $name . '\' could not be found');
|
||||
|
||||
throw new NotFound('Node with name \''.$name.'\' could not be found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a calendar exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function childExists($name) {
|
||||
|
||||
public function childExists($name)
|
||||
{
|
||||
try {
|
||||
return !!$this->getChild($name);
|
||||
return (bool) $this->getChild($name);
|
||||
} catch (NotFound $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of calendars
|
||||
* Returns a list of calendars.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
|
||||
$objs = [];
|
||||
foreach ($calendars as $calendar) {
|
||||
|
|
@ -220,35 +210,34 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
}
|
||||
|
||||
return $objs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new calendar or subscription.
|
||||
*
|
||||
* @param string $name
|
||||
* @param MkCol $mkCol
|
||||
* @param MkCol $mkCol
|
||||
*
|
||||
* @throws DAV\Exception\InvalidResourceType
|
||||
* @return void
|
||||
*/
|
||||
function createExtendedCollection($name, MkCol $mkCol) {
|
||||
|
||||
public function createExtendedCollection($name, MkCol $mkCol)
|
||||
{
|
||||
$isCalendar = false;
|
||||
$isSubscription = false;
|
||||
foreach ($mkCol->getResourceType() as $rt) {
|
||||
switch ($rt) {
|
||||
case '{DAV:}collection' :
|
||||
case '{http://calendarserver.org/ns/}shared-owner' :
|
||||
case '{DAV:}collection':
|
||||
case '{http://calendarserver.org/ns/}shared-owner':
|
||||
// ignore
|
||||
break;
|
||||
case '{urn:ietf:params:xml:ns:caldav}calendar' :
|
||||
case '{urn:ietf:params:xml:ns:caldav}calendar':
|
||||
$isCalendar = true;
|
||||
break;
|
||||
case '{http://calendarserver.org/ns/}subscribed' :
|
||||
case '{http://calendarserver.org/ns/}subscribed':
|
||||
$isSubscription = true;
|
||||
break;
|
||||
default :
|
||||
throw new DAV\Exception\InvalidResourceType('Unknown resourceType: ' . $rt);
|
||||
default:
|
||||
throw new DAV\Exception\InvalidResourceType('Unknown resourceType: '.$rt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -260,15 +249,11 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
throw new DAV\Exception\InvalidResourceType('This backend does not support subscriptions');
|
||||
}
|
||||
$this->caldavBackend->createSubscription($this->principalInfo['uri'], $name, $properties);
|
||||
|
||||
} elseif ($isCalendar) {
|
||||
$this->caldavBackend->createCalendar($this->principalInfo['uri'], $name, $properties);
|
||||
|
||||
} else {
|
||||
throw new DAV\Exception\InvalidResourceType('You can only create calendars and subscriptions in this collection');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -276,10 +261,9 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalInfo['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -294,8 +278,8 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
|
|
@ -309,46 +293,43 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-read',
|
||||
'principal' => $this->principalInfo['uri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is called when a user replied to a request to share.
|
||||
*
|
||||
* This method should return the url of the newly created calendar if the
|
||||
* share was accepted.
|
||||
*
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $href The sharee who is replying (often a mailto: address)
|
||||
* @param int $status One of the SharingPlugin::STATUS_* constants
|
||||
* @param string $calendarUri The url to the calendar thats being shared
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
* @return null|string
|
||||
* @param string $inReplyTo The unique id this message is a response to
|
||||
* @param string $summary A description of the reply
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) {
|
||||
|
||||
public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null)
|
||||
{
|
||||
if (!$this->caldavBackend instanceof Backend\SharingSupport) {
|
||||
throw new DAV\Exception\NotImplemented('Sharing support is not implemented by this backend.');
|
||||
}
|
||||
|
||||
return $this->caldavBackend->shareReply($href, $status, $calendarUri, $inReplyTo, $summary);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -367,12 +348,11 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
|
|||
* collection should be ignored.
|
||||
*
|
||||
* @param string $uid
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getCalendarObjectByUID($uid) {
|
||||
|
||||
public function getCalendarObjectByUID($uid)
|
||||
{
|
||||
return $this->caldavBackend->getCalendarObjectByUID($this->principalInfo['uri'], $uid);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
/**
|
||||
|
|
@ -9,33 +11,33 @@ namespace Sabre\CalDAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL {
|
||||
|
||||
class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL
|
||||
{
|
||||
use \Sabre\DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* Sabre\CalDAV\Backend\BackendInterface
|
||||
* Sabre\CalDAV\Backend\BackendInterface.
|
||||
*
|
||||
* @var Backend\AbstractBackend
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Array with information about this CalendarObject
|
||||
* Array with information about this CalendarObject.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $objectData;
|
||||
|
||||
/**
|
||||
* Array with information about the containing calendar
|
||||
* Array with information about the containing calendar.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $calendarInfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* The following properties may be passed within $objectData:
|
||||
*
|
||||
|
|
@ -49,11 +51,11 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
* * acl - (optional) Use this to override the default ACL for the node.
|
||||
*
|
||||
* @param Backend\BackendInterface $caldavBackend
|
||||
* @param array $calendarInfo
|
||||
* @param array $objectData
|
||||
* @param array $calendarInfo
|
||||
* @param array $objectData
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $caldavBackend, array $calendarInfo, array $objectData)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
|
||||
if (!isset($objectData['uri'])) {
|
||||
|
|
@ -62,44 +64,43 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
|
||||
$this->calendarInfo = $calendarInfo;
|
||||
$this->objectData = $objectData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uri for this object
|
||||
* Returns the uri for this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->objectData['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICalendar-formatted object
|
||||
* Returns the ICalendar-formatted object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get() {
|
||||
|
||||
public function get()
|
||||
{
|
||||
// Pre-populating the 'calendardata' is optional, if we don't have it
|
||||
// already we fetch it from the backend.
|
||||
if (!isset($this->objectData['calendardata'])) {
|
||||
$this->objectData = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
|
||||
}
|
||||
return $this->objectData['calendardata'];
|
||||
|
||||
return $this->objectData['calendardata'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ICalendar-formatted object
|
||||
* Updates the ICalendar-formatted object.
|
||||
*
|
||||
* @param string|resource $calendarData
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function put($calendarData) {
|
||||
|
||||
public function put($calendarData)
|
||||
{
|
||||
if (is_resource($calendarData)) {
|
||||
$calendarData = stream_get_contents($calendarData);
|
||||
}
|
||||
|
|
@ -108,33 +109,29 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
$this->objectData['etag'] = $etag;
|
||||
|
||||
return $etag;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the calendar object
|
||||
*
|
||||
* @return void
|
||||
* Deletes the calendar object.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'], $this->objectData['uri']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime content-type
|
||||
* Returns the mime content-type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getContentType() {
|
||||
|
||||
public function getContentType()
|
||||
{
|
||||
$mime = 'text/calendar; charset=utf-8';
|
||||
if (isset($this->objectData['component']) && $this->objectData['component']) {
|
||||
$mime .= '; component=' . $this->objectData['component'];
|
||||
$mime .= '; component='.$this->objectData['component'];
|
||||
}
|
||||
return $mime;
|
||||
|
||||
return $mime;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -144,53 +141,49 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
if (isset($this->objectData['etag'])) {
|
||||
return $this->objectData['etag'];
|
||||
} else {
|
||||
return '"' . md5($this->get()) . '"';
|
||||
return '"'.md5($this->get()).'"';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return $this->objectData['lastmodified'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this object in bytes
|
||||
* Returns the size of this object in bytes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getSize() {
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
if (array_key_exists('size', $this->objectData)) {
|
||||
return $this->objectData['size'];
|
||||
} else {
|
||||
return strlen($this->get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->calendarInfo['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -205,8 +198,8 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
// An alternative acl may be specified in the object data.
|
||||
if (isset($this->objectData['acl'])) {
|
||||
return $this->objectData['acl'];
|
||||
|
|
@ -221,17 +214,14 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use DateTime;
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* CalendarQuery Validator
|
||||
* CalendarQuery Validator.
|
||||
*
|
||||
* This class is responsible for checking if an iCalendar object matches a set
|
||||
* of filters. The main function to do this is 'validate'.
|
||||
|
|
@ -18,19 +20,20 @@ use Sabre\VObject;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarQueryValidator {
|
||||
|
||||
class CalendarQueryValidator
|
||||
{
|
||||
/**
|
||||
* Verify if a list of filters applies to the calendar data object
|
||||
* Verify if a list of filters applies to the calendar data object.
|
||||
*
|
||||
* The list of filters must be formatted as parsed by \Sabre\CalDAV\CalendarQueryParser
|
||||
*
|
||||
* @param VObject\Component\VCalendar $vObject
|
||||
* @param array $filters
|
||||
* @param array $filters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function validate(VObject\Component\VCalendar $vObject, array $filters) {
|
||||
|
||||
public function validate(VObject\Component\VCalendar $vObject, array $filters)
|
||||
{
|
||||
// The top level object is always a component filter.
|
||||
// We'll parse it manually, as it's pretty simple.
|
||||
if ($vObject->name !== $filters['name']) {
|
||||
|
|
@ -40,8 +43,6 @@ class CalendarQueryValidator {
|
|||
return
|
||||
$this->validateCompFilters($vObject, $filters['comp-filters']) &&
|
||||
$this->validatePropFilters($vObject, $filters['prop-filters']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,23 +53,21 @@ class CalendarQueryValidator {
|
|||
* itself.
|
||||
*
|
||||
* @param VObject\Component $parent
|
||||
* @param array $filters
|
||||
* @param array $filters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateCompFilters(VObject\Component $parent, array $filters) {
|
||||
|
||||
protected function validateCompFilters(VObject\Component $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
|
||||
$isDefined = isset($parent->{$filter['name']});
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
|
|
@ -80,6 +79,7 @@ class CalendarQueryValidator {
|
|||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -90,27 +90,23 @@ class CalendarQueryValidator {
|
|||
// If there are sub-filters, we need to find at least one component
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
|
||||
if (
|
||||
$this->validateCompFilters($subComponent, $filter['comp-filters']) &&
|
||||
$this->validatePropFilters($subComponent, $filter['prop-filters'])) {
|
||||
// We had a match, so this comp-filter succeeds
|
||||
continue 2;
|
||||
// We had a match, so this comp-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means there were sub-comp-filters or
|
||||
// sub-prop-filters and there was no match. This means this filter
|
||||
// needs to return false.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means we got through all comp-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,23 +117,21 @@ class CalendarQueryValidator {
|
|||
* itself.
|
||||
*
|
||||
* @param VObject\Component $parent
|
||||
* @param array $filters
|
||||
* @param array $filters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validatePropFilters(VObject\Component $parent, array $filters) {
|
||||
|
||||
protected function validatePropFilters(VObject\Component $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
|
||||
$isDefined = isset($parent->{$filter['name']});
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
|
|
@ -149,6 +143,7 @@ class CalendarQueryValidator {
|
|||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +154,6 @@ class CalendarQueryValidator {
|
|||
// If there are sub-filters, we need to find at least one property
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent->{$filter['name']} as $subComponent) {
|
||||
|
||||
if (
|
||||
$this->validateParamFilters($subComponent, $filter['param-filters']) &&
|
||||
(!$filter['text-match'] || $this->validateTextMatch($subComponent, $filter['text-match']))
|
||||
|
|
@ -167,20 +161,17 @@ class CalendarQueryValidator {
|
|||
// We had a match, so this prop-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means there were sub-param-filters or
|
||||
// text-match filters and there was no match. This means the
|
||||
// filter needs to return false.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means we got through all prop-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -191,23 +182,21 @@ class CalendarQueryValidator {
|
|||
* itself.
|
||||
*
|
||||
* @param VObject\Property $parent
|
||||
* @param array $filters
|
||||
* @param array $filters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateParamFilters(VObject\Property $parent, array $filters) {
|
||||
|
||||
protected function validateParamFilters(VObject\Property $parent, array $filters)
|
||||
{
|
||||
foreach ($filters as $filter) {
|
||||
|
||||
$isDefined = isset($parent[$filter['name']]);
|
||||
|
||||
if ($filter['is-not-defined']) {
|
||||
|
||||
if ($isDefined) {
|
||||
return false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
if (!$isDefined) {
|
||||
return false;
|
||||
|
|
@ -220,24 +209,20 @@ class CalendarQueryValidator {
|
|||
// If there are sub-filters, we need to find at least one parameter
|
||||
// for which the subfilters hold true.
|
||||
foreach ($parent[$filter['name']]->getParts() as $paramPart) {
|
||||
|
||||
if ($this->validateTextMatch($paramPart, $filter['text-match'])) {
|
||||
// We had a match, so this param-filter succeeds
|
||||
continue 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means there was a text-match filter and there
|
||||
// were no matches. This means the filter needs to return false.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// If we got here it means we got through all param-filters alive so the
|
||||
// filters were all true.
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -246,20 +231,20 @@ class CalendarQueryValidator {
|
|||
* A single text-match should be specified as well as the specific property
|
||||
* or parameter we need to validate.
|
||||
*
|
||||
* @param VObject\Node|string $check Value to check against.
|
||||
* @param array $textMatch
|
||||
* @param VObject\Node|string $check value to check against
|
||||
* @param array $textMatch
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateTextMatch($check, array $textMatch) {
|
||||
|
||||
protected function validateTextMatch($check, array $textMatch)
|
||||
{
|
||||
if ($check instanceof VObject\Node) {
|
||||
$check = $check->getValue();
|
||||
}
|
||||
|
||||
$isMatching = \Sabre\DAV\StringUtil::textMatch($check, $textMatch['value'], $textMatch['collation']);
|
||||
|
||||
return ($textMatch['negate-condition'] xor $isMatching);
|
||||
|
||||
return $textMatch['negate-condition'] xor $isMatching;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -269,12 +254,13 @@ class CalendarQueryValidator {
|
|||
* complex.
|
||||
*
|
||||
* @param VObject\Node $component
|
||||
* @param DateTime $start
|
||||
* @param DateTime $end
|
||||
* @param DateTime $start
|
||||
* @param DateTime $end
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateTimeRange(VObject\Node $component, $start, $end) {
|
||||
|
||||
protected function validateTimeRange(VObject\Node $component, $start, $end)
|
||||
{
|
||||
if (is_null($start)) {
|
||||
$start = new DateTime('1900-01-01');
|
||||
}
|
||||
|
|
@ -283,14 +269,13 @@ class CalendarQueryValidator {
|
|||
}
|
||||
|
||||
switch ($component->name) {
|
||||
|
||||
case 'VEVENT' :
|
||||
case 'VTODO' :
|
||||
case 'VJOURNAL' :
|
||||
case 'VEVENT':
|
||||
case 'VTODO':
|
||||
case 'VJOURNAL':
|
||||
|
||||
return $component->isInTimeRange($start, $end);
|
||||
|
||||
case 'VALARM' :
|
||||
case 'VALARM':
|
||||
|
||||
// If the valarm is wrapped in a recurring event, we need to
|
||||
// expand the recursions, and validate each.
|
||||
|
|
@ -298,10 +283,9 @@ class CalendarQueryValidator {
|
|||
// Our datamodel doesn't easily allow us to do this straight
|
||||
// in the VALARM component code, so this is a hack, and an
|
||||
// expensive one too.
|
||||
if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
|
||||
|
||||
if ('VEVENT' === $component->parent->name && $component->parent->RRULE) {
|
||||
// Fire up the iterator!
|
||||
$it = new VObject\Recur\EventIterator($component->parent->parent, (string)$component->parent->UID);
|
||||
$it = new VObject\Recur\EventIterator($component->parent->parent, (string) $component->parent->UID);
|
||||
while ($it->valid()) {
|
||||
$expandedEvent = $it->getEventObject();
|
||||
|
||||
|
|
@ -309,15 +293,14 @@ class CalendarQueryValidator {
|
|||
// one is the first to trigger. Based on this, we can
|
||||
// determine if we can 'give up' expanding events.
|
||||
$firstAlarm = null;
|
||||
if ($expandedEvent->VALARM !== null) {
|
||||
if (null !== $expandedEvent->VALARM) {
|
||||
foreach ($expandedEvent->VALARM as $expandedAlarm) {
|
||||
|
||||
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
|
||||
if ($expandedAlarm->isInTimeRange($start, $end)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
|
||||
if ('DATE-TIME' === (string) $expandedAlarm->TRIGGER['VALUE']) {
|
||||
// This is an alarm with a non-relative trigger
|
||||
// time, likely created by a buggy client. The
|
||||
// implication is that every alarm in this
|
||||
|
|
@ -346,30 +329,26 @@ class CalendarQueryValidator {
|
|||
}
|
||||
$it->next();
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return $component->isInTimeRange($start, $end);
|
||||
}
|
||||
|
||||
case 'VFREEBUSY' :
|
||||
throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on ' . $component->name . ' components');
|
||||
|
||||
case 'COMPLETED' :
|
||||
case 'CREATED' :
|
||||
case 'DTEND' :
|
||||
case 'DTSTAMP' :
|
||||
case 'DTSTART' :
|
||||
case 'DUE' :
|
||||
case 'LAST-MODIFIED' :
|
||||
return ($start <= $component->getDateTime() && $end >= $component->getDateTime());
|
||||
|
||||
|
||||
|
||||
default :
|
||||
throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a ' . $component->name . ' component');
|
||||
// no break
|
||||
case 'VFREEBUSY':
|
||||
throw new \Sabre\DAV\Exception\NotImplemented('time-range filters are currently not supported on '.$component->name.' components');
|
||||
case 'COMPLETED':
|
||||
case 'CREATED':
|
||||
case 'DTEND':
|
||||
case 'DTSTAMP':
|
||||
case 'DTSTART':
|
||||
case 'DUE':
|
||||
case 'LAST-MODIFIED':
|
||||
return $start <= $component->getDateTime() && $end >= $component->getDateTime();
|
||||
|
||||
default:
|
||||
throw new \Sabre\DAV\Exception\BadRequest('You cannot create a time-range filter on a '.$component->name.' component');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAVACL\PrincipalBackend;
|
||||
|
||||
/**
|
||||
* Calendars collection
|
||||
* Calendars collection.
|
||||
*
|
||||
* This object is responsible for generating a list of calendar-homes for each
|
||||
* user.
|
||||
|
|
@ -17,17 +19,17 @@ use Sabre\DAVACL\PrincipalBackend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection {
|
||||
|
||||
class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection
|
||||
{
|
||||
/**
|
||||
* CalDAV backend
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* This constructor needs both an authentication and a caldav backend.
|
||||
*
|
||||
|
|
@ -37,28 +39,26 @@ class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection {
|
|||
* to override this.
|
||||
*
|
||||
* @param PrincipalBackend\BackendInterface $principalBackend
|
||||
* @param Backend\BackendInterface $caldavBackend
|
||||
* @param string $principalPrefix
|
||||
* @param Backend\BackendInterface $caldavBackend
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals') {
|
||||
|
||||
public function __construct(PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals')
|
||||
{
|
||||
parent::__construct($principalBackend, $principalPrefix);
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nodename
|
||||
* Returns the nodename.
|
||||
*
|
||||
* We're overriding this, because the default will be the 'principalPrefix',
|
||||
* and we want it to be Sabre\CalDAV\Plugin::CALENDAR_ROOT
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Plugin::CALENDAR_ROOT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,12 +69,11 @@ class CalendarRoot extends \Sabre\DAVACL\AbstractPrincipalCollection {
|
|||
* supplied by the authentication backend.
|
||||
*
|
||||
* @param array $principal
|
||||
*
|
||||
* @return \Sabre\DAV\INode
|
||||
*/
|
||||
function getChildForPrincipal(array $principal) {
|
||||
|
||||
public function getChildForPrincipal(array $principal)
|
||||
{
|
||||
return new CalendarHome($this->caldavBackend, $principal);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Exception;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* InvalidComponentType
|
||||
* InvalidComponentType.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class InvalidComponentType extends DAV\Exception\Forbidden {
|
||||
|
||||
class InvalidComponentType extends DAV\Exception\Forbidden
|
||||
{
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {CALDAV:}supported-calendar-component as defined in rfc4791
|
||||
*
|
||||
* @param DAV\Server $server
|
||||
* @param DAV\Server $server
|
||||
* @param \DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
function serialize(DAV\Server $server, \DOMElement $errorNode) {
|
||||
|
||||
public function serialize(DAV\Server $server, \DOMElement $errorNode)
|
||||
{
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS(CalDAV\Plugin::NS_CALDAV, 'cal:supported-calendar-component');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use DateTime;
|
||||
|
|
@ -11,7 +13,7 @@ use Sabre\HTTP\ResponseInterface;
|
|||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* ICS Exporter
|
||||
* ICS Exporter.
|
||||
*
|
||||
* This plugin adds the ability to export entire calendars as .ics files.
|
||||
* This is useful for clients that don't support CalDAV yet. They often do
|
||||
|
|
@ -44,44 +46,49 @@ use Sabre\VObject;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ICSExportPlugin extends DAV\ServerPlugin {
|
||||
|
||||
class ICSExportPlugin extends DAV\ServerPlugin
|
||||
{
|
||||
/**
|
||||
* Reference to Server class
|
||||
* Reference to Server class.
|
||||
*
|
||||
* @var \Sabre\DAV\Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Initializes the plugin and registers event handlers
|
||||
* Initializes the plugin and registers event handlers.
|
||||
*
|
||||
* @param \Sabre\DAV\Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(DAV\Server $server) {
|
||||
|
||||
public function initialize(DAV\Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$server->on('method:GET', [$this, 'httpGet'], 90);
|
||||
$server->on('browserButtonActions', function($path, $node, &$actions) {
|
||||
$server->on('browserButtonActions', function ($path, $node, &$actions) {
|
||||
if ($node instanceof ICalendar) {
|
||||
$actions .= '<a href="' . htmlspecialchars($path, ENT_QUOTES, 'UTF-8') . '?export"><span class="oi" data-glyph="calendar"></span></a>';
|
||||
$actions .= '<a href="'.htmlspecialchars($path, ENT_QUOTES, 'UTF-8').'?export"><span class="oi" data-glyph="calendar"></span></a>';
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercepts GET requests on calendar urls ending with ?export.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @throws BadRequest
|
||||
* @throws DAV\Exception\NotFound
|
||||
* @throws VObject\InvalidDataException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function httpGet(RequestInterface $request, ResponseInterface $response) {
|
||||
|
||||
public function httpGet(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$queryParams = $request->getQueryParameters();
|
||||
if (!array_key_exists('export', $queryParams)) return;
|
||||
if (!array_key_exists('export', $queryParams)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $request->getPath();
|
||||
|
||||
|
|
@ -93,7 +100,7 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
'{http://apple.com/ns/ical/}calendar-color',
|
||||
]);
|
||||
|
||||
if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{' . Plugin::NS_CALDAV . '}calendar')) {
|
||||
if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{'.Plugin::NS_CALDAV.'}calendar')) {
|
||||
return;
|
||||
}
|
||||
// Marking the transactionType, for logging purposes.
|
||||
|
|
@ -117,7 +124,7 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
}
|
||||
$end = DateTime::createFromFormat('U', $queryParams['end']);
|
||||
}
|
||||
if (isset($queryParams['expand']) && !!$queryParams['expand']) {
|
||||
if (isset($queryParams['expand']) && (bool) $queryParams['expand']) {
|
||||
if (!$start || !$end) {
|
||||
throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.');
|
||||
}
|
||||
|
|
@ -126,12 +133,12 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
}
|
||||
if (isset($queryParams['componentType'])) {
|
||||
if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) {
|
||||
throw new BadRequest('You are not allowed to search for components of type: ' . $queryParams['componentType'] . ' here');
|
||||
throw new BadRequest('You are not allowed to search for components of type: '.$queryParams['componentType'].' here');
|
||||
}
|
||||
$componentType = $queryParams['componentType'];
|
||||
}
|
||||
|
||||
$format = \Sabre\HTTP\Util::Negotiate(
|
||||
$format = \Sabre\HTTP\negotiateContentType(
|
||||
$request->getHeader('Accept'),
|
||||
[
|
||||
'text/calendar',
|
||||
|
|
@ -140,7 +147,7 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
);
|
||||
|
||||
if (isset($queryParams['accept'])) {
|
||||
if ($queryParams['accept'] === 'application/calendar+json' || $queryParams['accept'] === 'jcal') {
|
||||
if ('application/calendar+json' === $queryParams['accept'] || 'jcal' === $queryParams['accept']) {
|
||||
$format = 'application/calendar+json';
|
||||
}
|
||||
}
|
||||
|
|
@ -152,61 +159,61 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
|
||||
// Returning false to break the event chain
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for generating the actual, full response.
|
||||
*
|
||||
* @param string $path
|
||||
* @param DateTime|null $start
|
||||
* @param DateTime|null $end
|
||||
* @param bool $expand
|
||||
* @param string $componentType
|
||||
* @param string $format
|
||||
* @param array $properties
|
||||
* @param string $path
|
||||
* @param DateTime|null $start
|
||||
* @param DateTime|null $end
|
||||
* @param bool $expand
|
||||
* @param string $componentType
|
||||
* @param string $format
|
||||
* @param array $properties
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @throws DAV\Exception\NotFound
|
||||
* @throws VObject\InvalidDataException
|
||||
*/
|
||||
protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response) {
|
||||
|
||||
$calDataProp = '{' . Plugin::NS_CALDAV . '}calendar-data';
|
||||
protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response)
|
||||
{
|
||||
$calDataProp = '{'.Plugin::NS_CALDAV.'}calendar-data';
|
||||
$calendarNode = $this->server->tree->getNodeForPath($path);
|
||||
|
||||
$blobs = [];
|
||||
if ($start || $end || $componentType) {
|
||||
|
||||
// If there was a start or end filter, we need to enlist
|
||||
// calendarQuery for speed.
|
||||
$queryResult = $calendarNode->calendarQuery([
|
||||
'name' => 'VCALENDAR',
|
||||
'name' => 'VCALENDAR',
|
||||
'comp-filters' => [
|
||||
[
|
||||
'name' => $componentType,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'name' => $componentType,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'is-not-defined' => false,
|
||||
'time-range' => [
|
||||
'time-range' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'end' => $end,
|
||||
],
|
||||
],
|
||||
],
|
||||
'prop-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'is-not-defined' => false,
|
||||
'time-range' => null,
|
||||
'time-range' => null,
|
||||
]);
|
||||
|
||||
// queryResult is just a list of base urls. We need to prefix the
|
||||
// calendar path.
|
||||
$queryResult = array_map(
|
||||
function($item) use ($path) {
|
||||
return $path . '/' . $item;
|
||||
function ($item) use ($path) {
|
||||
return $path.'/'.$item;
|
||||
},
|
||||
$queryResult
|
||||
);
|
||||
$nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]);
|
||||
unset($queryResult);
|
||||
|
||||
} else {
|
||||
$nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1);
|
||||
}
|
||||
|
|
@ -228,7 +235,7 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
$calendarTimeZone = null;
|
||||
// We're expanding, and for that we need to figure out the
|
||||
// calendar's timezone.
|
||||
$tzProp = '{' . Plugin::NS_CALDAV . '}calendar-timezone';
|
||||
$tzProp = '{'.Plugin::NS_CALDAV.'}calendar-timezone';
|
||||
$tzResult = $this->server->getProperties($path, [$tzProp]);
|
||||
if (isset($tzResult[$tzProp])) {
|
||||
// This property contains a VCALENDAR with a single
|
||||
|
|
@ -249,11 +256,11 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
$filenameExtension = '.ics';
|
||||
|
||||
switch ($format) {
|
||||
case 'text/calendar' :
|
||||
case 'text/calendar':
|
||||
$mergedCalendar = $mergedCalendar->serialize();
|
||||
$filenameExtension = '.ics';
|
||||
break;
|
||||
case 'application/calendar+json' :
|
||||
case 'application/calendar+json':
|
||||
$mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
|
||||
$filenameExtension = '.json';
|
||||
break;
|
||||
|
|
@ -264,29 +271,29 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
'',
|
||||
$calendarNode->getName()
|
||||
);
|
||||
$filename .= '-' . date('Y-m-d') . $filenameExtension;
|
||||
$filename .= '-'.date('Y-m-d').$filenameExtension;
|
||||
|
||||
$response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
|
||||
$response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
|
||||
$response->setHeader('Content-Type', $format);
|
||||
|
||||
$response->setStatus(200);
|
||||
$response->setBody($mergedCalendar);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all calendar objects, and builds one big iCalendar blob.
|
||||
*
|
||||
* @param array $properties Some CalDAV properties
|
||||
* @param array $properties Some CalDAV properties
|
||||
* @param array $inputObjects
|
||||
*
|
||||
* @return VObject\Component\VCalendar
|
||||
*/
|
||||
function mergeObjects(array $properties, array $inputObjects) {
|
||||
|
||||
public function mergeObjects(array $properties, array $inputObjects)
|
||||
{
|
||||
$calendar = new VObject\Component\VCalendar();
|
||||
$calendar->VERSION = '2.0';
|
||||
if (DAV\Server::$exposeVersion) {
|
||||
$calendar->PRODID = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN';
|
||||
$calendar->PRODID = '-//SabreDAV//SabreDAV '.DAV\Version::VERSION.'//EN';
|
||||
} else {
|
||||
$calendar->PRODID = '-//SabreDAV//SabreDAV//EN';
|
||||
}
|
||||
|
|
@ -303,41 +310,41 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
$objects = [];
|
||||
|
||||
foreach ($inputObjects as $href => $inputObject) {
|
||||
|
||||
$nodeComp = VObject\Reader::read($inputObject);
|
||||
|
||||
foreach ($nodeComp->children() as $child) {
|
||||
|
||||
switch ($child->name) {
|
||||
case 'VEVENT' :
|
||||
case 'VTODO' :
|
||||
case 'VJOURNAL' :
|
||||
case 'VEVENT':
|
||||
case 'VTODO':
|
||||
case 'VJOURNAL':
|
||||
$objects[] = clone $child;
|
||||
break;
|
||||
|
||||
// VTIMEZONE is special, because we need to filter out the duplicates
|
||||
case 'VTIMEZONE' :
|
||||
case 'VTIMEZONE':
|
||||
// Naively just checking tzid.
|
||||
if (in_array((string)$child->TZID, $collectedTimezones)) continue;
|
||||
if (in_array((string) $child->TZID, $collectedTimezones)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$timezones[] = clone $child;
|
||||
$collectedTimezones[] = $child->TZID;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// Destroy circular references to PHP will GC the object.
|
||||
$nodeComp->destroy();
|
||||
unset($nodeComp);
|
||||
|
||||
}
|
||||
|
||||
foreach ($timezones as $tz) $calendar->add($tz);
|
||||
foreach ($objects as $obj) $calendar->add($obj);
|
||||
foreach ($timezones as $tz) {
|
||||
$calendar->add($tz);
|
||||
}
|
||||
foreach ($objects as $obj) {
|
||||
$calendar->add($obj);
|
||||
}
|
||||
|
||||
return $calendar;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -348,10 +355,9 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'ics-export';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -365,14 +371,12 @@ class ICSExportPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds the ability to export CalDAV calendars as a single iCalendar file.',
|
||||
'link' => 'http://sabre.io/dav/ics-export-plugin/',
|
||||
'link' => 'http://sabre.io/dav/ics-export-plugin/',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* Calendar interface
|
||||
* Calendar interface.
|
||||
*
|
||||
* Implement this interface to allow a node to be recognized as an calendar.
|
||||
*
|
||||
|
|
@ -13,6 +15,6 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendar extends ICalendarObjectContainer, DAVACL\IACL {
|
||||
|
||||
interface ICalendar extends ICalendarObjectContainer, DAVACL\IACL
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* CalendarObject interface
|
||||
* CalendarObject interface.
|
||||
*
|
||||
* Extend the ICalendarObject interface to allow your custom nodes to be picked up as
|
||||
* CalendarObjects.
|
||||
|
|
@ -16,6 +18,6 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendarObject extends DAV\IFile {
|
||||
|
||||
interface ICalendarObject extends DAV\IFile
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
/**
|
||||
|
|
@ -15,8 +17,8 @@ namespace Sabre\CalDAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICalendarObjectContainer extends \Sabre\DAV\ICollection {
|
||||
|
||||
interface ICalendarObjectContainer extends \Sabre\DAV\ICollection
|
||||
{
|
||||
/**
|
||||
* Performs a calendar-query on the contents of this calendar.
|
||||
*
|
||||
|
|
@ -32,8 +34,8 @@ interface ICalendarObjectContainer extends \Sabre\DAV\ICollection {
|
|||
* documented by \Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* @param array $filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function calendarQuery(array $filters);
|
||||
|
||||
public function calendarQuery(array $filters);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV\Sharing\ISharedNode;
|
||||
|
|
@ -11,8 +13,8 @@ use Sabre\DAV\Sharing\ISharedNode;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ISharedCalendar extends ISharedNode {
|
||||
|
||||
interface ISharedCalendar extends ISharedNode
|
||||
{
|
||||
/**
|
||||
* Marks this calendar as published.
|
||||
*
|
||||
|
|
@ -20,7 +22,6 @@ interface ISharedCalendar extends ISharedNode {
|
|||
* subscribable calendar.
|
||||
*
|
||||
* @param bool $value
|
||||
* @return void
|
||||
*/
|
||||
function setPublishStatus($value);
|
||||
public function setPublishStatus($value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -20,49 +22,47 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Collection extends DAV\Collection implements ICollection, DAVACL\IACL {
|
||||
|
||||
class Collection extends DAV\Collection implements ICollection, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* The notification backend
|
||||
* The notification backend.
|
||||
*
|
||||
* @var CalDAV\Backend\NotificationSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Principal uri
|
||||
* Principal uri.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param CalDAV\Backend\NotificationSupport $caldavBackend
|
||||
* @param string $principalUri
|
||||
* @param string $principalUri
|
||||
*/
|
||||
function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri) {
|
||||
|
||||
public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all notifications for a principal
|
||||
* Returns all notifications for a principal.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$children = [];
|
||||
$notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri);
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
|
||||
$children[] = new Node(
|
||||
$this->caldavBackend,
|
||||
$this->principalUri,
|
||||
|
|
@ -71,31 +71,27 @@ class Collection extends DAV\Collection implements ICollection, DAVACL\IACL {
|
|||
}
|
||||
|
||||
return $children;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'notifications';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -18,6 +20,6 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICollection extends DAV\ICollection {
|
||||
|
||||
interface ICollection extends DAV\ICollection
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
||||
|
|
@ -18,15 +20,15 @@ use Sabre\CalDAV\Xml\Notification\NotificationInterface;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface INode {
|
||||
|
||||
interface INode
|
||||
{
|
||||
/**
|
||||
* This method must return an xml element, using the
|
||||
* Sabre\CalDAV\Xml\Notification\NotificationInterface classes.
|
||||
*
|
||||
* @return NotificationInterface
|
||||
*/
|
||||
function getNotificationType();
|
||||
public function getNotificationType();
|
||||
|
||||
/**
|
||||
* Returns the etag for the notification.
|
||||
|
|
@ -35,6 +37,5 @@ interface INode {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag();
|
||||
|
||||
public function getETag();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -18,55 +20,53 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Node extends DAV\File implements INode, DAVACL\IACL {
|
||||
|
||||
class Node extends DAV\File implements INode, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* The notification backend
|
||||
* The notification backend.
|
||||
*
|
||||
* @var CalDAV\Backend\NotificationSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* The actual notification
|
||||
* The actual notification.
|
||||
*
|
||||
* @var NotificationInterface
|
||||
*/
|
||||
protected $notification;
|
||||
|
||||
/**
|
||||
* Owner principal of the notification
|
||||
* Owner principal of the notification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param CalDAV\Backend\NotificationSupport $caldavBackend
|
||||
* @param string $principalUri
|
||||
* @param NotificationInterface $notification
|
||||
* @param string $principalUri
|
||||
* @param NotificationInterface $notification
|
||||
*/
|
||||
function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri, NotificationInterface $notification) {
|
||||
|
||||
public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri, NotificationInterface $notification)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
$this->notification = $notification;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path name for this notification
|
||||
* Returns the path name for this notification.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
return $this->notification->getId() . '.xml';
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->notification->getId().'.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,10 +76,9 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
return $this->notification->getETag();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,34 +87,28 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
|
|||
*
|
||||
* @return NotificationInterface
|
||||
*/
|
||||
function getNotificationType() {
|
||||
|
||||
public function getNotificationType()
|
||||
{
|
||||
return $this->notification;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this notification
|
||||
*
|
||||
* @return void
|
||||
* Deletes this notification.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteNotification($this->getOwner(), $this->notification);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Notifications;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -12,7 +14,7 @@ use Sabre\HTTP\RequestInterface;
|
|||
use Sabre\HTTP\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Notifications plugin
|
||||
* Notifications plugin.
|
||||
*
|
||||
* This plugin implements several features required by the caldav-notification
|
||||
* draft specification.
|
||||
|
|
@ -24,10 +26,10 @@ use Sabre\HTTP\ResponseInterface;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Plugin extends ServerPlugin {
|
||||
|
||||
class Plugin extends ServerPlugin
|
||||
{
|
||||
/**
|
||||
* This is the namespace for the proprietary calendarserver extensions
|
||||
* This is the namespace for the proprietary calendarserver extensions.
|
||||
*/
|
||||
const NS_CALENDARSERVER = 'http://calendarserver.org/ns/';
|
||||
|
||||
|
|
@ -46,10 +48,9 @@ class Plugin extends ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'notifications';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -61,58 +62,49 @@ class Plugin extends ServerPlugin {
|
|||
* This method should set up the required event subscriptions.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(Server $server) {
|
||||
|
||||
public function initialize(Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$server->on('method:GET', [$this, 'httpGet'], 90);
|
||||
$server->on('propFind', [$this, 'propFind']);
|
||||
$server->on('propFind', [$this, 'propFind']);
|
||||
|
||||
$server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs';
|
||||
$server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{' . self::NS_CALENDARSERVER . '}notification';
|
||||
$server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{'.self::NS_CALENDARSERVER.'}notification';
|
||||
|
||||
array_push($server->protectedProperties,
|
||||
'{' . self::NS_CALENDARSERVER . '}notification-URL',
|
||||
'{' . self::NS_CALENDARSERVER . '}notificationtype'
|
||||
'{'.self::NS_CALENDARSERVER.'}notification-URL',
|
||||
'{'.self::NS_CALENDARSERVER.'}notificationtype'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* PropFind
|
||||
* PropFind.
|
||||
*
|
||||
* @param PropFind $propFind
|
||||
* @param PropFind $propFind
|
||||
* @param BaseINode $node
|
||||
* @return void
|
||||
*/
|
||||
function propFind(PropFind $propFind, BaseINode $node) {
|
||||
|
||||
public function propFind(PropFind $propFind, BaseINode $node)
|
||||
{
|
||||
$caldavPlugin = $this->server->getPlugin('caldav');
|
||||
|
||||
if ($node instanceof DAVACL\IPrincipal) {
|
||||
|
||||
$principalUrl = $node->getPrincipalUrl();
|
||||
|
||||
// notification-URL property
|
||||
$propFind->handle('{' . self::NS_CALENDARSERVER . '}notification-URL', function() use ($principalUrl, $caldavPlugin) {
|
||||
$propFind->handle('{'.self::NS_CALENDARSERVER.'}notification-URL', function () use ($principalUrl, $caldavPlugin) {
|
||||
$notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl).'/notifications/';
|
||||
|
||||
$notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl) . '/notifications/';
|
||||
return new DAV\Xml\Property\Href($notificationPath);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if ($node instanceof INode) {
|
||||
|
||||
$propFind->handle(
|
||||
'{' . self::NS_CALENDARSERVER . '}notificationtype',
|
||||
'{'.self::NS_CALENDARSERVER.'}notificationtype',
|
||||
[$node, 'getNotificationType']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -121,12 +113,11 @@ class Plugin extends ServerPlugin {
|
|||
* We use this to intercept GET calls to notification nodes, and return the
|
||||
* proper response.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return void
|
||||
*/
|
||||
function httpGet(RequestInterface $request, ResponseInterface $response) {
|
||||
|
||||
public function httpGet(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$path = $request->getPath();
|
||||
|
||||
try {
|
||||
|
|
@ -135,8 +126,9 @@ class Plugin extends ServerPlugin {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$node instanceof INode)
|
||||
if (!$node instanceof INode) {
|
||||
return;
|
||||
}
|
||||
|
||||
$writer = $this->server->xml->getWriter();
|
||||
$writer->contextUri = $this->server->getBaseUri();
|
||||
|
|
@ -153,7 +145,6 @@ class Plugin extends ServerPlugin {
|
|||
|
||||
// Return false to break the event chain.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -167,14 +158,12 @@ class Plugin extends ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.',
|
||||
'link' => 'http://sabre.io/dav/caldav-sharing/',
|
||||
'link' => 'http://sabre.io/dav/caldav-sharing/',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* Principal collection
|
||||
* Principal collection.
|
||||
*
|
||||
* This is an alternative collection to the standard ACL principal collection.
|
||||
* This collection adds support for the calendar-proxy-read and
|
||||
|
|
@ -16,18 +18,17 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Collection extends DAVACL\PrincipalCollection {
|
||||
|
||||
class Collection extends DAVACL\PrincipalCollection
|
||||
{
|
||||
/**
|
||||
* Returns a child object based on principal information
|
||||
* Returns a child object based on principal information.
|
||||
*
|
||||
* @param array $principalInfo
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
function getChildForPrincipal(array $principalInfo) {
|
||||
|
||||
public function getChildForPrincipal(array $principalInfo)
|
||||
{
|
||||
return new User($this->principalBackend, $principalInfo);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* ProxyRead principal interface
|
||||
* ProxyRead principal interface.
|
||||
*
|
||||
* Any principal node implementing this interface will be picked up as a 'proxy
|
||||
* principal group'.
|
||||
|
|
@ -14,6 +16,6 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IProxyRead extends DAVACL\IPrincipal {
|
||||
|
||||
interface IProxyRead extends DAVACL\IPrincipal
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* ProxyWrite principal interface
|
||||
* ProxyWrite principal interface.
|
||||
*
|
||||
* Any principal node implementing this interface will be picked up as a 'proxy
|
||||
* principal group'.
|
||||
|
|
@ -14,6 +16,6 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IProxyWrite extends DAVACL\IPrincipal {
|
||||
|
||||
interface IProxyWrite extends DAVACL\IPrincipal
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* ProxyRead principal
|
||||
* ProxyRead principal.
|
||||
*
|
||||
* This class represents a principal group, hosted under the main principal.
|
||||
* This is needed to implement 'Calendar delegation' support. This class is
|
||||
|
|
@ -16,8 +18,8 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ProxyRead implements IProxyRead {
|
||||
|
||||
class ProxyRead implements IProxyRead
|
||||
{
|
||||
/**
|
||||
* Principal information from the parent principal.
|
||||
*
|
||||
|
|
@ -26,7 +28,7 @@ class ProxyRead implements IProxyRead {
|
|||
protected $principalInfo;
|
||||
|
||||
/**
|
||||
* Principal backend
|
||||
* Principal backend.
|
||||
*
|
||||
* @var DAVACL\PrincipalBackend\BackendInterface
|
||||
*/
|
||||
|
|
@ -38,13 +40,12 @@ class ProxyRead implements IProxyRead {
|
|||
* Note that you MUST supply the parent principal information.
|
||||
*
|
||||
* @param DAVACL\PrincipalBackend\BackendInterface $principalBackend
|
||||
* @param array $principalInfo
|
||||
* @param array $principalInfo
|
||||
*/
|
||||
function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) {
|
||||
|
||||
public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo)
|
||||
{
|
||||
$this->principalInfo = $principalInfo;
|
||||
$this->principalBackend = $principalBackend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,103 +53,91 @@ class ProxyRead implements IProxyRead {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'calendar-proxy-read';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification time
|
||||
*
|
||||
* @return null
|
||||
* Returns the last modification time.
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the current node
|
||||
* Deletes the current node.
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to delete node');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the node
|
||||
* Renames the node.
|
||||
*
|
||||
* @param string $name The new name
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function setName($name) {
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to rename file');
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of alternative urls for a principal
|
||||
* Returns a list of alternative urls for a principal.
|
||||
*
|
||||
* This can for example be an email address, or ldap url.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getAlternateUriSet() {
|
||||
|
||||
public function getAlternateUriSet()
|
||||
{
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full principal url
|
||||
* Returns the full principal url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPrincipalUrl() {
|
||||
|
||||
return $this->principalInfo['uri'] . '/' . $this->getName();
|
||||
|
||||
public function getPrincipalUrl()
|
||||
{
|
||||
return $this->principalInfo['uri'].'/'.$this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of group members
|
||||
* Returns the list of group members.
|
||||
*
|
||||
* If this principal is a group, this function should return
|
||||
* all member principal uri's for the group.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMemberSet() {
|
||||
|
||||
public function getGroupMemberSet()
|
||||
{
|
||||
return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of groups this principal is member of
|
||||
* Returns the list of groups this principal is member of.
|
||||
*
|
||||
* If this principal is a member of a (list of) groups, this function
|
||||
* should return a list of principal uri's for it's members.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMembership() {
|
||||
|
||||
public function getGroupMembership()
|
||||
{
|
||||
return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of group members
|
||||
* Sets a list of group members.
|
||||
*
|
||||
* If this principal is a group, this method sets all the group members.
|
||||
* The list of members is always overwritten, never appended to.
|
||||
|
|
@ -156,26 +145,22 @@ class ProxyRead implements IProxyRead {
|
|||
* This method should throw an exception if the members could not be set.
|
||||
*
|
||||
* @param array $principals
|
||||
* @return void
|
||||
*/
|
||||
function setGroupMemberSet(array $principals) {
|
||||
|
||||
public function setGroupMemberSet(array $principals)
|
||||
{
|
||||
$this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the displayname
|
||||
* Returns the displayname.
|
||||
*
|
||||
* This should be a human readable name for the principal.
|
||||
* If none is available, return the nodename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getDisplayName() {
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->getName();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* ProxyWrite principal
|
||||
* ProxyWrite principal.
|
||||
*
|
||||
* This class represents a principal group, hosted under the main principal.
|
||||
* This is needed to implement 'Calendar delegation' support. This class is
|
||||
|
|
@ -16,35 +18,34 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ProxyWrite implements IProxyWrite {
|
||||
|
||||
class ProxyWrite implements IProxyWrite
|
||||
{
|
||||
/**
|
||||
* Parent principal information
|
||||
* Parent principal information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalInfo;
|
||||
|
||||
/**
|
||||
* Principal Backend
|
||||
* Principal Backend.
|
||||
*
|
||||
* @var DAVACL\PrincipalBackend\BackendInterface
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* Creates the object
|
||||
* Creates the object.
|
||||
*
|
||||
* Note that you MUST supply the parent principal information.
|
||||
*
|
||||
* @param DAVACL\PrincipalBackend\BackendInterface $principalBackend
|
||||
* @param array $principalInfo
|
||||
* @param array $principalInfo
|
||||
*/
|
||||
function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) {
|
||||
|
||||
public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo)
|
||||
{
|
||||
$this->principalInfo = $principalInfo;
|
||||
$this->principalBackend = $principalBackend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,103 +53,91 @@ class ProxyWrite implements IProxyWrite {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'calendar-proxy-write';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification time
|
||||
*
|
||||
* @return null
|
||||
* Returns the last modification time.
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the current node
|
||||
* Deletes the current node.
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to delete node');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the node
|
||||
* Renames the node.
|
||||
*
|
||||
* @param string $name The new name
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function setName($name) {
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to rename file');
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of alternative urls for a principal
|
||||
* Returns a list of alternative urls for a principal.
|
||||
*
|
||||
* This can for example be an email address, or ldap url.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getAlternateUriSet() {
|
||||
|
||||
public function getAlternateUriSet()
|
||||
{
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full principal url
|
||||
* Returns the full principal url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPrincipalUrl() {
|
||||
|
||||
return $this->principalInfo['uri'] . '/' . $this->getName();
|
||||
|
||||
public function getPrincipalUrl()
|
||||
{
|
||||
return $this->principalInfo['uri'].'/'.$this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of group members
|
||||
* Returns the list of group members.
|
||||
*
|
||||
* If this principal is a group, this function should return
|
||||
* all member principal uri's for the group.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMemberSet() {
|
||||
|
||||
public function getGroupMemberSet()
|
||||
{
|
||||
return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of groups this principal is member of
|
||||
* Returns the list of groups this principal is member of.
|
||||
*
|
||||
* If this principal is a member of a (list of) groups, this function
|
||||
* should return a list of principal uri's for it's members.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMembership() {
|
||||
|
||||
public function getGroupMembership()
|
||||
{
|
||||
return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of group members
|
||||
* Sets a list of group members.
|
||||
*
|
||||
* If this principal is a group, this method sets all the group members.
|
||||
* The list of members is always overwritten, never appended to.
|
||||
|
|
@ -156,26 +145,22 @@ class ProxyWrite implements IProxyWrite {
|
|||
* This method should throw an exception if the members could not be set.
|
||||
*
|
||||
* @param array $principals
|
||||
* @return void
|
||||
*/
|
||||
function setGroupMemberSet(array $principals) {
|
||||
|
||||
public function setGroupMemberSet(array $principals)
|
||||
{
|
||||
$this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the displayname
|
||||
* Returns the displayname.
|
||||
*
|
||||
* This should be a human readable name for the principal.
|
||||
* If none is available, return the nodename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getDisplayName() {
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->getName();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Principal;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* CalDAV principal
|
||||
* CalDAV principal.
|
||||
*
|
||||
* This is a standard user-principal for CalDAV. This principal is also a
|
||||
* collection and returns the caldav-proxy-read and caldav-proxy-write child
|
||||
|
|
@ -16,91 +18,91 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class User extends DAVACL\Principal implements DAV\ICollection {
|
||||
|
||||
class User extends DAVACL\Principal implements DAV\ICollection
|
||||
{
|
||||
/**
|
||||
* Creates a new file in the directory
|
||||
* Creates a new file in the directory.
|
||||
*
|
||||
* @param string $name Name of the file
|
||||
* @param resource $data initial payload, passed as a readable stream resource
|
||||
*
|
||||
* @param string $name Name of the file
|
||||
* @param resource $data Initial payload, passed as a readable stream resource.
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function createFile($name, $data = null) {
|
||||
|
||||
throw new DAV\Exception\Forbidden('Permission denied to create file (filename ' . $name . ')');
|
||||
|
||||
public function createFile($name, $data = null)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to create file (filename '.$name.')');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new subdirectory
|
||||
* Creates a new subdirectory.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($name) {
|
||||
|
||||
public function createDirectory($name)
|
||||
{
|
||||
throw new DAV\Exception\Forbidden('Permission denied to create directory');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific child node, referenced by its name
|
||||
* Returns a specific child node, referenced by its name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return DAV\INode
|
||||
*/
|
||||
function getChild($name) {
|
||||
|
||||
$principal = $this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/' . $name);
|
||||
public function getChild($name)
|
||||
{
|
||||
$principal = $this->principalBackend->getPrincipalByPath($this->getPrincipalURL().'/'.$name);
|
||||
if (!$principal) {
|
||||
throw new DAV\Exception\NotFound('Node with name ' . $name . ' was not found');
|
||||
throw new DAV\Exception\NotFound('Node with name '.$name.' was not found');
|
||||
}
|
||||
if ($name === 'calendar-proxy-read')
|
||||
if ('calendar-proxy-read' === $name) {
|
||||
return new ProxyRead($this->principalBackend, $this->principalProperties);
|
||||
}
|
||||
|
||||
if ($name === 'calendar-proxy-write')
|
||||
if ('calendar-proxy-write' === $name) {
|
||||
return new ProxyWrite($this->principalBackend, $this->principalProperties);
|
||||
}
|
||||
|
||||
throw new DAV\Exception\NotFound('Node with name ' . $name . ' was not found');
|
||||
|
||||
throw new DAV\Exception\NotFound('Node with name '.$name.' was not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the child nodes
|
||||
* Returns an array with all the child nodes.
|
||||
*
|
||||
* @return DAV\INode[]
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$r = [];
|
||||
if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-read')) {
|
||||
if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL().'/calendar-proxy-read')) {
|
||||
$r[] = new ProxyRead($this->principalBackend, $this->principalProperties);
|
||||
}
|
||||
if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-write')) {
|
||||
if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL().'/calendar-proxy-write')) {
|
||||
$r[] = new ProxyWrite($this->principalBackend, $this->principalProperties);
|
||||
}
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the child node exists
|
||||
* Returns whether or not the child node exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function childExists($name) {
|
||||
|
||||
public function childExists($name)
|
||||
{
|
||||
try {
|
||||
$this->getChild($name);
|
||||
|
||||
return true;
|
||||
} catch (DAV\Exception\NotFound $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,21 +117,20 @@ class User extends DAVACL\Principal implements DAV\ICollection {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
$acl = parent::getACL();
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read',
|
||||
'principal' => $this->principalProperties['uri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->principalProperties['uri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
/**
|
||||
|
|
@ -10,6 +12,6 @@ namespace Sabre\CalDAV\Schedule;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IInbox extends \Sabre\CalDAV\ICalendarObjectContainer, \Sabre\DAVACL\IACL {
|
||||
|
||||
interface IInbox extends \Sabre\CalDAV\ICalendarObjectContainer, \Sabre\DAVACL\IACL
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -19,8 +21,8 @@ use Sabre\VObject\ITip;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class IMipPlugin extends DAV\ServerPlugin {
|
||||
|
||||
class IMipPlugin extends DAV\ServerPlugin
|
||||
{
|
||||
/**
|
||||
* Email address used in From: header.
|
||||
*
|
||||
|
|
@ -29,7 +31,7 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
protected $senderEmail;
|
||||
|
||||
/**
|
||||
* ITipMessage
|
||||
* ITipMessage.
|
||||
*
|
||||
* @var ITip\Message
|
||||
*/
|
||||
|
|
@ -43,10 +45,9 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
* generally be some kind of no-reply email
|
||||
* address you own.
|
||||
*/
|
||||
function __construct($senderEmail) {
|
||||
|
||||
public function __construct($senderEmail)
|
||||
{
|
||||
$this->senderEmail = $senderEmail;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -60,10 +61,9 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
* @param DAV\Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(DAV\Server $server) {
|
||||
|
||||
public function initialize(DAV\Server $server)
|
||||
{
|
||||
$server->on('schedule', [$this, 'schedule'], 120);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,67 +74,68 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'imip';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for the 'schedule' event.
|
||||
*
|
||||
* @param ITip\Message $iTipMessage
|
||||
* @return void
|
||||
*/
|
||||
function schedule(ITip\Message $iTipMessage) {
|
||||
|
||||
public function schedule(ITip\Message $iTipMessage)
|
||||
{
|
||||
// Not sending any emails if the system considers the update
|
||||
// insignificant.
|
||||
if (!$iTipMessage->significantChange) {
|
||||
if (!$iTipMessage->scheduleStatus) {
|
||||
$iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$summary = $iTipMessage->message->VEVENT->SUMMARY;
|
||||
|
||||
if (parse_url($iTipMessage->sender, PHP_URL_SCHEME) !== 'mailto')
|
||||
if ('mailto' !== parse_url($iTipMessage->sender, PHP_URL_SCHEME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parse_url($iTipMessage->recipient, PHP_URL_SCHEME) !== 'mailto')
|
||||
if ('mailto' !== parse_url($iTipMessage->recipient, PHP_URL_SCHEME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sender = substr($iTipMessage->sender, 7);
|
||||
$recipient = substr($iTipMessage->recipient, 7);
|
||||
|
||||
if ($iTipMessage->senderName) {
|
||||
$sender = $iTipMessage->senderName . ' <' . $sender . '>';
|
||||
$sender = $iTipMessage->senderName.' <'.$sender.'>';
|
||||
}
|
||||
if ($iTipMessage->recipientName) {
|
||||
$recipient = $iTipMessage->recipientName . ' <' . $recipient . '>';
|
||||
if ($iTipMessage->recipientName && $iTipMessage->recipientName != $recipient) {
|
||||
$recipient = $iTipMessage->recipientName.' <'.$recipient.'>';
|
||||
}
|
||||
|
||||
$subject = 'SabreDAV iTIP message';
|
||||
switch (strtoupper($iTipMessage->method)) {
|
||||
case 'REPLY' :
|
||||
$subject = 'Re: ' . $summary;
|
||||
case 'REPLY':
|
||||
$subject = 'Re: '.$summary;
|
||||
break;
|
||||
case 'REQUEST' :
|
||||
$subject = $summary;
|
||||
case 'REQUEST':
|
||||
$subject = 'Invitation: '.$summary;
|
||||
break;
|
||||
case 'CANCEL' :
|
||||
$subject = 'Cancelled: ' . $summary;
|
||||
case 'CANCEL':
|
||||
$subject = 'Cancelled: '.$summary;
|
||||
break;
|
||||
}
|
||||
|
||||
$headers = [
|
||||
'Reply-To: ' . $sender,
|
||||
'From: ' . $this->senderEmail,
|
||||
'Content-Type: text/calendar; charset=UTF-8; method=' . $iTipMessage->method,
|
||||
'Reply-To: '.$sender,
|
||||
'From: '.$iTipMessage->senderName.' <'.$this->senderEmail.'>',
|
||||
'Content-Type: text/calendar; charset=UTF-8; method='.$iTipMessage->method,
|
||||
];
|
||||
if (DAV\Server::$exposeVersion) {
|
||||
$headers[] = 'X-Sabre-Version: ' . DAV\Version::VERSION;
|
||||
$headers[] = 'X-Sabre-Version: '.DAV\Version::VERSION;
|
||||
}
|
||||
$this->mail(
|
||||
$recipient,
|
||||
|
|
@ -143,7 +144,6 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
$headers
|
||||
);
|
||||
$iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip';
|
||||
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
|
|
@ -152,16 +152,14 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
/**
|
||||
* This function is responsible for sending the actual email.
|
||||
*
|
||||
* @param string $to Recipient email address
|
||||
* @param string $to Recipient email address
|
||||
* @param string $subject Subject of the email
|
||||
* @param string $body iCalendar body
|
||||
* @param array $headers List of headers
|
||||
* @return void
|
||||
* @param string $body iCalendar body
|
||||
* @param array $headers List of headers
|
||||
*/
|
||||
protected function mail($to, $subject, $body, array $headers) {
|
||||
|
||||
protected function mail($to, $subject, $body, array $headers)
|
||||
{
|
||||
mail($to, $subject, $body, implode("\r\n", $headers));
|
||||
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
|
@ -177,14 +175,12 @@ class IMipPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Email delivery (rfc6047) for CalDAV scheduling',
|
||||
'link' => 'http://sabre.io/dav/scheduling/',
|
||||
'link' => 'http://sabre.io/dav/scheduling/',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
/**
|
||||
|
|
@ -10,6 +12,6 @@ namespace Sabre\CalDAV\Schedule;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IOutbox extends \Sabre\DAV\ICollection, \Sabre\DAVACL\IACL {
|
||||
|
||||
interface IOutbox extends \Sabre\DAV\ICollection, \Sabre\DAVACL\IACL
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
/**
|
||||
* The SchedulingObject represents a scheduling object in the Inbox collection
|
||||
* The SchedulingObject represents a scheduling object in the Inbox collection.
|
||||
*
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
*/
|
||||
interface ISchedulingObject extends \Sabre\CalDAV\ICalendarObject {
|
||||
|
||||
interface ISchedulingObject extends \Sabre\CalDAV\ICalendarObject
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -9,41 +11,40 @@ use Sabre\DAVACL;
|
|||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* The CalDAV scheduling inbox
|
||||
* The CalDAV scheduling inbox.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Inbox extends DAV\Collection implements IInbox {
|
||||
|
||||
class Inbox extends DAV\Collection implements IInbox
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* CalDAV backend
|
||||
* CalDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* The principal Uri
|
||||
* The principal Uri.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\SchedulingSupport $caldavBackend
|
||||
* @param string $principalUri
|
||||
* @param string $principalUri
|
||||
*/
|
||||
function __construct(Backend\SchedulingSupport $caldavBackend, $principalUri) {
|
||||
|
||||
public function __construct(Backend\SchedulingSupport $caldavBackend, $principalUri)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -53,19 +54,18 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'inbox';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the child nodes
|
||||
* Returns an array with all the child nodes.
|
||||
*
|
||||
* @return \Sabre\DAV\INode[]
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$objs = $this->caldavBackend->getSchedulingObjects($this->principalUri);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
|
|
@ -73,12 +73,12 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
$obj['principaluri'] = $this->principalUri;
|
||||
$children[] = new SchedulingObject($this->caldavBackend, $obj);
|
||||
}
|
||||
return $children;
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file in the directory
|
||||
* Creates a new file in the directory.
|
||||
*
|
||||
* Data will either be supplied as a stream resource, or in certain cases
|
||||
* as a string. Keep in mind that you may have to support either.
|
||||
|
|
@ -97,27 +97,26 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
* return the same contents of what was submitted here, you are strongly
|
||||
* recommended to omit the ETag.
|
||||
*
|
||||
* @param string $name Name of the file
|
||||
* @param string $name Name of the file
|
||||
* @param resource|string $data Initial payload
|
||||
* @return null|string
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createFile($name, $data = null) {
|
||||
|
||||
public function createFile($name, $data = null)
|
||||
{
|
||||
$this->caldavBackend->createSchedulingObject($this->principalUri, $name, $data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,8 +131,8 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
|
|
@ -152,16 +151,15 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}unbind',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver',
|
||||
'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-deliver',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -179,10 +177,11 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
* documented by \Sabre\CalDAV\CalendarQueryParser.
|
||||
*
|
||||
* @param array $filters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function calendarQuery(array $filters) {
|
||||
|
||||
public function calendarQuery(array $filters)
|
||||
{
|
||||
$result = [];
|
||||
$validator = new CalDAV\CalendarQueryValidator();
|
||||
|
||||
|
|
@ -196,8 +195,7 @@ class Inbox extends DAV\Collection implements IInbox {
|
|||
// Destroy circular references to PHP will GC the object.
|
||||
$vObject->destroy();
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -7,7 +9,7 @@ use Sabre\DAV;
|
|||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* The CalDAV scheduling outbox
|
||||
* The CalDAV scheduling outbox.
|
||||
*
|
||||
* The outbox is mainly used as an endpoint in the tree for a client to do
|
||||
* free-busy requests. This functionality is completely handled by the
|
||||
|
|
@ -17,26 +19,25 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Outbox extends DAV\Collection implements IOutbox {
|
||||
|
||||
class Outbox extends DAV\Collection implements IOutbox
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* The principal Uri
|
||||
* The principal Uri.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*/
|
||||
function __construct($principalUri) {
|
||||
|
||||
public function __construct($principalUri)
|
||||
{
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -46,34 +47,31 @@ class Outbox extends DAV\Collection implements IOutbox {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'outbox';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the child nodes
|
||||
* Returns an array with all the child nodes.
|
||||
*
|
||||
* @return \Sabre\DAV\INode[]
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,11 +86,11 @@ class Outbox extends DAV\Collection implements IOutbox {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
|
||||
'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send',
|
||||
'principal' => $this->getOwner(),
|
||||
'protected' => true,
|
||||
],
|
||||
|
|
@ -102,22 +100,20 @@ class Outbox extends DAV\Collection implements IOutbox {
|
|||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,35 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Schedule;
|
||||
|
||||
use Sabre\CalDAV\Backend;
|
||||
use Sabre\DAV\Exception\MethodNotAllowed;
|
||||
|
||||
/**
|
||||
* The SchedulingObject represents a scheduling object in the Inbox collection
|
||||
* The SchedulingObject represents a scheduling object in the Inbox collection.
|
||||
*
|
||||
* @author Brett (https://github.com/bretten)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
*/
|
||||
class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements ISchedulingObject {
|
||||
|
||||
class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements ISchedulingObject
|
||||
{
|
||||
/**
|
||||
/* The CalDAV backend
|
||||
*
|
||||
* @var Backend\SchedulingSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* Array with information about this SchedulingObject
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $objectData;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* The following properties may be passed within $objectData:
|
||||
*
|
||||
|
|
@ -43,73 +31,65 @@ class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements IScheduli
|
|||
* * acl - (optional) Use this to override the default ACL for the node.
|
||||
*
|
||||
* @param Backend\SchedulingSupport $caldavBackend
|
||||
* @param array $objectData
|
||||
* @param array $objectData
|
||||
*/
|
||||
function __construct(Backend\SchedulingSupport $caldavBackend, array $objectData) {
|
||||
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
public function __construct(Backend\SchedulingSupport $caldavBackend, array $objectData)
|
||||
{
|
||||
parent::__construct($caldavBackend, [], $objectData);
|
||||
|
||||
if (!isset($objectData['uri'])) {
|
||||
throw new \InvalidArgumentException('The objectData argument must contain an \'uri\' property');
|
||||
}
|
||||
|
||||
$this->objectData = $objectData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICalendar-formatted object
|
||||
* Returns the ICalendar-formatted object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get() {
|
||||
|
||||
public function get()
|
||||
{
|
||||
// Pre-populating the 'calendardata' is optional, if we don't have it
|
||||
// already we fetch it from the backend.
|
||||
if (!isset($this->objectData['calendardata'])) {
|
||||
$this->objectData = $this->caldavBackend->getSchedulingObject($this->objectData['principaluri'], $this->objectData['uri']);
|
||||
}
|
||||
return $this->objectData['calendardata'];
|
||||
|
||||
return $this->objectData['calendardata'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ICalendar-formatted object
|
||||
* Updates the ICalendar-formatted object.
|
||||
*
|
||||
* @param string|resource $calendarData
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function put($calendarData) {
|
||||
|
||||
public function put($calendarData)
|
||||
{
|
||||
throw new MethodNotAllowed('Updating scheduling objects is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the scheduling message
|
||||
*
|
||||
* @return void
|
||||
* Deletes the scheduling message.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteSchedulingObject($this->objectData['principaluri'], $this->objectData['uri']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->objectData['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
|
|
@ -122,8 +102,8 @@ class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements IScheduli
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
// An alternative acl may be specified in the object data.
|
||||
//
|
||||
|
||||
|
|
@ -140,16 +120,14 @@ class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements IScheduli
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
'principal' => $this->objectData['principaluri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->objectData['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->objectData['principaluri'] . '/calendar-proxy-read',
|
||||
'principal' => $this->objectData['principaluri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV\Sharing\Plugin as SPlugin;
|
||||
|
|
@ -11,8 +13,8 @@ use Sabre\DAV\Sharing\Plugin as SPlugin;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SharedCalendar extends Calendar implements ISharedCalendar {
|
||||
|
||||
class SharedCalendar extends Calendar implements ISharedCalendar
|
||||
{
|
||||
/**
|
||||
* Returns the 'access level' for the instance of this shared resource.
|
||||
*
|
||||
|
|
@ -21,10 +23,9 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
function getShareAccess() {
|
||||
|
||||
public function getShareAccess()
|
||||
{
|
||||
return isset($this->calendarInfo['share-access']) ? $this->calendarInfo['share-access'] : SPlugin::ACCESS_NOTSHARED;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -38,10 +39,9 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getShareResourceUri() {
|
||||
|
||||
public function getShareResourceUri()
|
||||
{
|
||||
return $this->calendarInfo['share-resource-uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,12 +50,10 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
* Every item must be a Sharee object.
|
||||
*
|
||||
* @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
|
||||
* @return void
|
||||
*/
|
||||
function updateInvites(array $sharees) {
|
||||
|
||||
public function updateInvites(array $sharees)
|
||||
{
|
||||
$this->caldavBackend->updateInvites($this->calendarInfo['id'], $sharees);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,10 +72,9 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
*
|
||||
* @return \Sabre\DAV\Xml\Element\Sharee[]
|
||||
*/
|
||||
function getInvites() {
|
||||
|
||||
public function getInvites()
|
||||
{
|
||||
return $this->caldavBackend->getInvites($this->calendarInfo['id']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -87,12 +84,10 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
* subscribable calendar.
|
||||
*
|
||||
* @param bool $value
|
||||
* @return void
|
||||
*/
|
||||
function setPublishStatus($value) {
|
||||
|
||||
public function setPublishStatus($value)
|
||||
{
|
||||
$this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -107,13 +102,13 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
$acl = [];
|
||||
|
||||
switch ($this->getShareAccess()) {
|
||||
case SPlugin::ACCESS_NOTSHARED :
|
||||
case SPlugin::ACCESS_SHAREDOWNER :
|
||||
case SPlugin::ACCESS_NOTSHARED:
|
||||
case SPlugin::ACCESS_SHAREDOWNER:
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}share',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
|
|
@ -121,76 +116,10 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}share',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
// No break intentional!
|
||||
case SPlugin::ACCESS_READWRITE :
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
// No break intentional!
|
||||
case SPlugin::ACCESS_READ :
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write-properties',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write-properties',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
break;
|
||||
}
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the ACL's for calendar objects in this calendar.
|
||||
* The result of this method automatically gets passed to the
|
||||
* calendar-object nodes in the calendar.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildACL() {
|
||||
|
||||
$acl = [];
|
||||
|
||||
switch ($this->getShareAccess()) {
|
||||
case SPlugin::ACCESS_NOTSHARED :
|
||||
// No break intentional
|
||||
case SPlugin::ACCESS_SHAREDOWNER :
|
||||
// No break intentional
|
||||
// no break intentional!
|
||||
case SPlugin::ACCESS_READWRITE:
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
|
|
@ -199,10 +128,73 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
// No break intentional
|
||||
// no break intentional!
|
||||
case SPlugin::ACCESS_READ:
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write-properties',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write-properties',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy',
|
||||
'principal' => '{DAV:}authenticated',
|
||||
'protected' => true,
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ACL's for calendar objects in this calendar.
|
||||
* The result of this method automatically gets passed to the
|
||||
* calendar-object nodes in the calendar.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildACL()
|
||||
{
|
||||
$acl = [];
|
||||
|
||||
switch ($this->getShareAccess()) {
|
||||
case SPlugin::ACCESS_NOTSHARED:
|
||||
case SPlugin::ACCESS_SHAREDOWNER:
|
||||
case SPlugin::ACCESS_READWRITE:
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->calendarInfo['principaluri'],
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}write',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
// no break intentional
|
||||
case SPlugin::ACCESS_READ:
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
|
|
@ -211,19 +203,17 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
|
|||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
];
|
||||
$acl[] = [
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
|
||||
'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -23,8 +25,8 @@ use Sabre\HTTP\ResponseInterface;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SharingPlugin extends DAV\ServerPlugin {
|
||||
|
||||
class SharingPlugin extends DAV\ServerPlugin
|
||||
{
|
||||
/**
|
||||
* Reference to SabreDAV server object.
|
||||
*
|
||||
|
|
@ -40,10 +42,9 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getFeatures() {
|
||||
|
||||
public function getFeatures()
|
||||
{
|
||||
return ['calendarserver-sharing'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -54,10 +55,9 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'caldav-sharing';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,10 +69,9 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
* This method should set up the required event subscriptions.
|
||||
*
|
||||
* @param DAV\Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(DAV\Server $server) {
|
||||
|
||||
public function initialize(DAV\Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
|
||||
if (is_null($this->server->getPlugin('sharing'))) {
|
||||
|
|
@ -81,19 +80,18 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
|
||||
array_push(
|
||||
$this->server->protectedProperties,
|
||||
'{' . Plugin::NS_CALENDARSERVER . '}invite',
|
||||
'{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
|
||||
'{' . Plugin::NS_CALENDARSERVER . '}shared-url'
|
||||
'{'.Plugin::NS_CALENDARSERVER.'}invite',
|
||||
'{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes',
|
||||
'{'.Plugin::NS_CALENDARSERVER.'}shared-url'
|
||||
);
|
||||
|
||||
$this->server->xml->elementMap['{' . Plugin::NS_CALENDARSERVER . '}share'] = 'Sabre\\CalDAV\\Xml\\Request\\Share';
|
||||
$this->server->xml->elementMap['{' . Plugin::NS_CALENDARSERVER . '}invite-reply'] = 'Sabre\\CalDAV\\Xml\\Request\\InviteReply';
|
||||
|
||||
$this->server->on('propFind', [$this, 'propFindEarly']);
|
||||
$this->server->on('propFind', [$this, 'propFindLate'], 150);
|
||||
$this->server->on('propPatch', [$this, 'propPatch'], 40);
|
||||
$this->server->on('method:POST', [$this, 'httpPost']);
|
||||
$this->server->xml->elementMap['{'.Plugin::NS_CALENDARSERVER.'}share'] = 'Sabre\\CalDAV\\Xml\\Request\\Share';
|
||||
$this->server->xml->elementMap['{'.Plugin::NS_CALENDARSERVER.'}invite-reply'] = 'Sabre\\CalDAV\\Xml\\Request\\InviteReply';
|
||||
|
||||
$this->server->on('propFind', [$this, 'propFindEarly']);
|
||||
$this->server->on('propFind', [$this, 'propFindLate'], 150);
|
||||
$this->server->on('propPatch', [$this, 'propPatch'], 40);
|
||||
$this->server->on('method:POST', [$this, 'httpPost']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,47 +101,17 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
* This allows us to inject any properties early.
|
||||
*
|
||||
* @param DAV\PropFind $propFind
|
||||
* @param DAV\INode $node
|
||||
* @return void
|
||||
* @param DAV\INode $node
|
||||
*/
|
||||
function propFindEarly(DAV\PropFind $propFind, DAV\INode $node) {
|
||||
|
||||
public function propFindEarly(DAV\PropFind $propFind, DAV\INode $node)
|
||||
{
|
||||
if ($node instanceof ISharedCalendar) {
|
||||
|
||||
$propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}invite', function() use ($node) {
|
||||
|
||||
// Fetching owner information
|
||||
$props = $this->server->getPropertiesForPath($node->getOwner(), [
|
||||
'{http://sabredav.org/ns}email-address',
|
||||
'{DAV:}displayname',
|
||||
], 0);
|
||||
|
||||
$ownerInfo = [
|
||||
'href' => $node->getOwner(),
|
||||
];
|
||||
|
||||
if (isset($props[0][200])) {
|
||||
|
||||
// We're mapping the internal webdav properties to the
|
||||
// elements caldav-sharing expects.
|
||||
if (isset($props[0][200]['{http://sabredav.org/ns}email-address'])) {
|
||||
$ownerInfo['href'] = 'mailto:' . $props[0][200]['{http://sabredav.org/ns}email-address'];
|
||||
}
|
||||
if (isset($props[0][200]['{DAV:}displayname'])) {
|
||||
$ownerInfo['commonName'] = $props[0][200]['{DAV:}displayname'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$propFind->handle('{'.Plugin::NS_CALENDARSERVER.'}invite', function () use ($node) {
|
||||
return new Xml\Property\Invite(
|
||||
$node->getInvites(),
|
||||
$ownerInfo
|
||||
$node->getInvites()
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,31 +120,27 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
* have been shared.
|
||||
*
|
||||
* @param DAV\PropFind $propFind
|
||||
* @param DAV\INode $node
|
||||
* @return void
|
||||
* @param DAV\INode $node
|
||||
*/
|
||||
function propFindLate(DAV\PropFind $propFind, DAV\INode $node) {
|
||||
|
||||
public function propFindLate(DAV\PropFind $propFind, DAV\INode $node)
|
||||
{
|
||||
if ($node instanceof ISharedCalendar) {
|
||||
$shareAccess = $node->getShareAccess();
|
||||
if ($rt = $propFind->get('{DAV:}resourcetype')) {
|
||||
switch ($shareAccess) {
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER :
|
||||
$rt->add('{' . Plugin::NS_CALENDARSERVER . '}shared-owner');
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER:
|
||||
$rt->add('{'.Plugin::NS_CALENDARSERVER.'}shared-owner');
|
||||
break;
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_READ :
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE :
|
||||
$rt->add('{' . Plugin::NS_CALENDARSERVER . '}shared');
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_READ:
|
||||
case \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE:
|
||||
$rt->add('{'.Plugin::NS_CALENDARSERVER.'}shared');
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
$propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes', function() {
|
||||
$propFind->handle('{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes', function () {
|
||||
return new Xml\Property\AllowedSharingModes(true, false);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -190,20 +154,21 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
* Even though this is no longer in the current spec, we keep this around
|
||||
* because OS X 10.7 may still make use of this feature.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
* @param DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function propPatch($path, DAV\PropPatch $propPatch) {
|
||||
|
||||
public function propPatch($path, DAV\PropPatch $propPatch)
|
||||
{
|
||||
$node = $this->server->tree->getNodeForPath($path);
|
||||
if (!$node instanceof ISharedCalendar)
|
||||
if (!$node instanceof ISharedCalendar) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($node->getShareAccess() === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER || $node->getShareAccess() === \Sabre\DAV\Sharing\Plugin::ACCESS_NOTSHARED) {
|
||||
|
||||
$propPatch->handle('{DAV:}resourcetype', function($value) use ($node) {
|
||||
if ($value->is('{' . Plugin::NS_CALENDARSERVER . '}shared-owner')) return false;
|
||||
if (\Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $node->getShareAccess() || \Sabre\DAV\Sharing\Plugin::ACCESS_NOTSHARED === $node->getShareAccess()) {
|
||||
$propPatch->handle('{DAV:}resourcetype', function ($value) use ($node) {
|
||||
if ($value->is('{'.Plugin::NS_CALENDARSERVER.'}shared-owner')) {
|
||||
return false;
|
||||
}
|
||||
$shares = $node->getInvites();
|
||||
foreach ($shares as $share) {
|
||||
$share->access = DAV\Sharing\Plugin::ACCESS_NOACCESS;
|
||||
|
|
@ -211,28 +176,30 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
$node->updateInvites($shares);
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We intercept this to handle POST requests on calendars.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return null|bool
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
function httpPost(RequestInterface $request, ResponseInterface $response) {
|
||||
|
||||
public function httpPost(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$path = $request->getPath();
|
||||
|
||||
// Only handling xml
|
||||
$contentType = $request->getHeader('Content-Type');
|
||||
if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false)
|
||||
if (null === $contentType) {
|
||||
return;
|
||||
}
|
||||
if (false === strpos($contentType, 'application/xml') && false === strpos($contentType, 'text/xml')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Making sure the node exists
|
||||
try {
|
||||
|
|
@ -255,10 +222,9 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
$message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType);
|
||||
|
||||
switch ($documentType) {
|
||||
|
||||
// Both the DAV:share-resource and CALENDARSERVER:share requests
|
||||
// behave identically.
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}share' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}share':
|
||||
|
||||
$sharingPlugin = $this->server->getPlugin('sharing');
|
||||
$sharingPlugin->shareResource($path, $message->sharees);
|
||||
|
|
@ -273,7 +239,7 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
|
||||
// The invite-reply document is sent when the user replies to an
|
||||
// invitation of a calendar share.
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}invite-reply' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}invite-reply':
|
||||
|
||||
// This only works on the calendar-home-root node.
|
||||
if (!$node instanceof CalendarHome) {
|
||||
|
|
@ -304,20 +270,20 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
|
||||
if ($url) {
|
||||
$writer = $this->server->xml->getWriter();
|
||||
$writer->contextUri = $request->getUrl();
|
||||
$writer->openMemory();
|
||||
$writer->startDocument();
|
||||
$writer->startElement('{' . Plugin::NS_CALENDARSERVER . '}shared-as');
|
||||
$writer->startElement('{'.Plugin::NS_CALENDARSERVER.'}shared-as');
|
||||
$writer->write(new LocalHref($url));
|
||||
$writer->endElement();
|
||||
$response->setHeader('Content-Type', 'application/xml');
|
||||
$response->setBody($writer->outputMemory());
|
||||
|
||||
}
|
||||
|
||||
// Breaking the event chain
|
||||
return false;
|
||||
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}publish-calendar' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}publish-calendar':
|
||||
|
||||
// We can only deal with IShareableCalendar objects
|
||||
if (!$node instanceof ISharedCalendar) {
|
||||
|
|
@ -345,7 +311,7 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
// Breaking the event chain
|
||||
return false;
|
||||
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}unpublish-calendar' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}unpublish-calendar':
|
||||
|
||||
// We can only deal with IShareableCalendar objects
|
||||
if (!$node instanceof ISharedCalendar) {
|
||||
|
|
@ -371,11 +337,7 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
|
||||
// Breaking the event chain
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -389,13 +351,12 @@ class SharingPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds support for caldav-sharing.',
|
||||
'link' => 'http://sabre.io/dav/caldav-sharing/',
|
||||
'link' => 'http://sabre.io/dav/caldav-sharing/',
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Subscriptions;
|
||||
|
||||
use Sabre\DAV\ICollection;
|
||||
use Sabre\DAV\IProperties;
|
||||
|
||||
/**
|
||||
* ISubscription
|
||||
* ISubscription.
|
||||
*
|
||||
* Nodes implementing this interface represent calendar subscriptions.
|
||||
*
|
||||
|
|
@ -34,7 +36,6 @@ use Sabre\DAV\IProperties;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ISubscription extends ICollection, IProperties {
|
||||
|
||||
|
||||
interface ISubscription extends ICollection, IProperties
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Subscriptions;
|
||||
|
||||
use Sabre\DAV\INode;
|
||||
|
|
@ -17,8 +19,8 @@ use Sabre\DAV\ServerPlugin;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Plugin extends ServerPlugin {
|
||||
|
||||
class Plugin extends ServerPlugin
|
||||
{
|
||||
/**
|
||||
* This initializes the plugin.
|
||||
*
|
||||
|
|
@ -28,10 +30,9 @@ class Plugin extends ServerPlugin {
|
|||
* This method should set up the required event subscriptions.
|
||||
*
|
||||
* @param Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(Server $server) {
|
||||
|
||||
public function initialize(Server $server)
|
||||
{
|
||||
$server->resourceTypeMapping['Sabre\\CalDAV\\Subscriptions\\ISubscription'] =
|
||||
'{http://calendarserver.org/ns/}subscribed';
|
||||
|
||||
|
|
@ -39,7 +40,6 @@ class Plugin extends ServerPlugin {
|
|||
'Sabre\\DAV\\Xml\\Property\\Href';
|
||||
|
||||
$server->on('propFind', [$this, 'propFind'], 150);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,21 +50,19 @@ class Plugin extends ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getFeatures() {
|
||||
|
||||
public function getFeatures()
|
||||
{
|
||||
return ['calendarserver-subscribed'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered after properties have been fetched.
|
||||
*
|
||||
* @param PropFind $propFind
|
||||
* @param INode $node
|
||||
* @return void
|
||||
* @param INode $node
|
||||
*/
|
||||
function propFind(PropFind $propFind, INode $node) {
|
||||
|
||||
public function propFind(PropFind $propFind, INode $node)
|
||||
{
|
||||
// There's a bunch of properties that must appear as a self-closing
|
||||
// xml-element. This event handler ensures that this will be the case.
|
||||
$props = [
|
||||
|
|
@ -74,13 +72,10 @@ class Plugin extends ServerPlugin {
|
|||
];
|
||||
|
||||
foreach ($props as $prop) {
|
||||
|
||||
if ($propFind->getStatus($prop) === 200) {
|
||||
if (200 === $propFind->getStatus($prop)) {
|
||||
$propFind->set($prop, '', 200);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,10 +86,9 @@ class Plugin extends ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'subscriptions';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -108,13 +102,12 @@ class Plugin extends ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'This plugin allows users to store iCalendar subscriptions in their calendar-home.',
|
||||
'link' => null,
|
||||
'link' => null,
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Subscriptions;
|
||||
|
||||
use Sabre\CalDAV\Backend\SubscriptionSupport;
|
||||
|
|
@ -10,7 +12,7 @@ use Sabre\DAVACL\ACLTrait;
|
|||
use Sabre\DAVACL\IACL;
|
||||
|
||||
/**
|
||||
* Subscription Node
|
||||
* Subscription Node.
|
||||
*
|
||||
* This node represents a subscription.
|
||||
*
|
||||
|
|
@ -18,32 +20,32 @@ use Sabre\DAVACL\IACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Subscription extends Collection implements ISubscription, IACL {
|
||||
|
||||
class Subscription extends Collection implements ISubscription, IACL
|
||||
{
|
||||
use ACLTrait;
|
||||
|
||||
/**
|
||||
* caldavBackend
|
||||
* caldavBackend.
|
||||
*
|
||||
* @var SubscriptionSupport
|
||||
*/
|
||||
protected $caldavBackend;
|
||||
|
||||
/**
|
||||
* subscriptionInfo
|
||||
* subscriptionInfo.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $subscriptionInfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param SubscriptionSupport $caldavBackend
|
||||
* @param array $subscriptionInfo
|
||||
* @param array $subscriptionInfo
|
||||
*/
|
||||
function __construct(SubscriptionSupport $caldavBackend, array $subscriptionInfo) {
|
||||
|
||||
public function __construct(SubscriptionSupport $caldavBackend, array $subscriptionInfo)
|
||||
{
|
||||
$this->caldavBackend = $caldavBackend;
|
||||
$this->subscriptionInfo = $subscriptionInfo;
|
||||
|
||||
|
|
@ -56,10 +58,9 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
|
||||
foreach ($required as $r) {
|
||||
if (!isset($subscriptionInfo[$r])) {
|
||||
throw new \InvalidArgumentException('The ' . $r . ' field is required when creating a subscription node');
|
||||
throw new \InvalidArgumentException('The '.$r.' field is required when creating a subscription node');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,47 +70,41 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->subscriptionInfo['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification time
|
||||
* Returns the last modification time.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
if (isset($this->subscriptionInfo['lastmodified'])) {
|
||||
return $this->subscriptionInfo['lastmodified'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the current node
|
||||
*
|
||||
* @return void
|
||||
* Deletes the current node.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->caldavBackend->deleteSubscription(
|
||||
$this->subscriptionInfo['id']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all the child nodes
|
||||
* Returns an array with all the child nodes.
|
||||
*
|
||||
* @return \Sabre\DAV\INode[]
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -122,15 +117,13 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
* Read the PropPatch documentation for more information.
|
||||
*
|
||||
* @param PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function propPatch(PropPatch $propPatch) {
|
||||
|
||||
public function propPatch(PropPatch $propPatch)
|
||||
{
|
||||
return $this->caldavBackend->updateSubscription(
|
||||
$this->subscriptionInfo['id'],
|
||||
$propPatch
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,29 +139,27 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
* The Server class will filter out the extra.
|
||||
*
|
||||
* @param array $properties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getProperties($properties) {
|
||||
|
||||
public function getProperties($properties)
|
||||
{
|
||||
$r = [];
|
||||
|
||||
foreach ($properties as $prop) {
|
||||
|
||||
switch ($prop) {
|
||||
case '{http://calendarserver.org/ns/}source' :
|
||||
case '{http://calendarserver.org/ns/}source':
|
||||
$r[$prop] = new Href($this->subscriptionInfo['source']);
|
||||
break;
|
||||
default :
|
||||
default:
|
||||
if (array_key_exists($prop, $this->subscriptionInfo)) {
|
||||
$r[$prop] = $this->subscriptionInfo[$prop];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -178,10 +169,9 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->subscriptionInfo['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,8 +186,8 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
|
|
@ -206,16 +196,14 @@ class Subscription extends Collection implements ISubscription, IACL {
|
|||
],
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-write',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-write',
|
||||
'protected' => true,
|
||||
],
|
||||
[
|
||||
'privilege' => '{DAV:}read',
|
||||
'principal' => $this->getOwner() . '/calendar-proxy-read',
|
||||
'principal' => $this->getOwner().'/calendar-proxy-read',
|
||||
'protected' => true,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -25,8 +27,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarData implements XmlDeserializable {
|
||||
|
||||
class CalendarData implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -46,24 +48,24 @@ class CalendarData implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'contentType' => $reader->getAttribute('content-type') ?: 'text/calendar',
|
||||
'version' => $reader->getAttribute('version') ?: '2.0',
|
||||
'version' => $reader->getAttribute('version') ?: '2.0',
|
||||
];
|
||||
|
||||
$elems = (array)$reader->parseInnerTree();
|
||||
$elems = (array) $reader->parseInnerTree();
|
||||
foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
case '{' . Plugin::NS_CALDAV . '}expand' :
|
||||
case '{'.Plugin::NS_CALDAV.'}expand':
|
||||
|
||||
$result['expand'] = [
|
||||
'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
];
|
||||
|
||||
if (!$result['expand']['start'] || !$result['expand']['end']) {
|
||||
|
|
@ -74,11 +76,8 @@ class CalendarData implements XmlDeserializable {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -22,8 +24,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CompFilter implements XmlDeserializable {
|
||||
|
||||
class CompFilter implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -43,16 +45,17 @@ class CompFilter implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'name' => null,
|
||||
'name' => null,
|
||||
'is-not-defined' => false,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'time-range' => false,
|
||||
'comp-filters' => [],
|
||||
'prop-filters' => [],
|
||||
'time-range' => false,
|
||||
];
|
||||
|
||||
$att = $reader->parseAttributes();
|
||||
|
|
@ -60,38 +63,34 @@ class CompFilter implements XmlDeserializable {
|
|||
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
if (is_array($elems)) foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CALDAV . '}comp-filter' :
|
||||
if (is_array($elems)) {
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
case '{'.Plugin::NS_CALDAV.'}comp-filter':
|
||||
$result['comp-filters'][] = $elem['value'];
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}prop-filter' :
|
||||
case '{'.Plugin::NS_CALDAV.'}prop-filter':
|
||||
$result['prop-filters'][] = $elem['value'];
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}is-not-defined' :
|
||||
case '{'.Plugin::NS_CALDAV.'}is-not-defined':
|
||||
$result['is-not-defined'] = true;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}time-range' :
|
||||
if ($result['name'] === 'VCALENDAR') {
|
||||
case '{'.Plugin::NS_CALDAV.'}time-range':
|
||||
if ('VCALENDAR' === $result['name']) {
|
||||
throw new BadRequest('You cannot add time-range filters on the VCALENDAR component');
|
||||
}
|
||||
$result['time-range'] = [
|
||||
'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
];
|
||||
if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
|
||||
throw new BadRequest('The end-date must be larger than the start-date');
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -20,8 +22,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ParamFilter implements XmlDeserializable {
|
||||
|
||||
class ParamFilter implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -41,14 +43,15 @@ class ParamFilter implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'name' => null,
|
||||
'name' => null,
|
||||
'is-not-defined' => false,
|
||||
'text-match' => null,
|
||||
'text-match' => null,
|
||||
];
|
||||
|
||||
$att = $reader->parseAttributes();
|
||||
|
|
@ -56,27 +59,23 @@ class ParamFilter implements XmlDeserializable {
|
|||
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
if (is_array($elems)) foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CALDAV . '}is-not-defined' :
|
||||
if (is_array($elems)) {
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
case '{'.Plugin::NS_CALDAV.'}is-not-defined':
|
||||
$result['is-not-defined'] = true;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}text-match' :
|
||||
case '{'.Plugin::NS_CALDAV.'}text-match':
|
||||
$result['text-match'] = [
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes',
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap',
|
||||
'value' => $elem['value'],
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'],
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap',
|
||||
'value' => $elem['value'],
|
||||
];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -22,8 +24,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class PropFilter implements XmlDeserializable {
|
||||
|
||||
class PropFilter implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -43,16 +45,17 @@ class PropFilter implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'name' => null,
|
||||
'name' => null,
|
||||
'is-not-defined' => false,
|
||||
'param-filters' => [],
|
||||
'text-match' => null,
|
||||
'time-range' => false,
|
||||
'param-filters' => [],
|
||||
'text-match' => null,
|
||||
'time-range' => false,
|
||||
];
|
||||
|
||||
$att = $reader->parseAttributes();
|
||||
|
|
@ -60,39 +63,35 @@ class PropFilter implements XmlDeserializable {
|
|||
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
if (is_array($elems)) foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CALDAV . '}param-filter' :
|
||||
if (is_array($elems)) {
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
case '{'.Plugin::NS_CALDAV.'}param-filter':
|
||||
$result['param-filters'][] = $elem['value'];
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}is-not-defined' :
|
||||
case '{'.Plugin::NS_CALDAV.'}is-not-defined':
|
||||
$result['is-not-defined'] = true;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}time-range' :
|
||||
case '{'.Plugin::NS_CALDAV.'}time-range':
|
||||
$result['time-range'] = [
|
||||
'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
|
||||
];
|
||||
if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
|
||||
throw new BadRequest('The end-date must be larger than the start-date');
|
||||
}
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}text-match' :
|
||||
case '{'.Plugin::NS_CALDAV.'}text-match':
|
||||
$result['text-match'] = [
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes',
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap',
|
||||
'value' => $elem['value'],
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'],
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap',
|
||||
'value' => $elem['value'],
|
||||
];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Notification;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -17,19 +19,19 @@ use Sabre\Xml\Writer;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Invite implements NotificationInterface {
|
||||
|
||||
class Invite implements NotificationInterface
|
||||
{
|
||||
/**
|
||||
* A unique id for the message
|
||||
* A unique id for the message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Timestamp of the notification
|
||||
* Timestamp of the notification.
|
||||
*
|
||||
* @var DateTime
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $dtStamp;
|
||||
|
||||
|
|
@ -63,7 +65,7 @@ class Invite implements NotificationInterface {
|
|||
protected $hostUrl;
|
||||
|
||||
/**
|
||||
* Url to the sharer of the calendar
|
||||
* Url to the sharer of the calendar.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -91,21 +93,21 @@ class Invite implements NotificationInterface {
|
|||
protected $lastName;
|
||||
|
||||
/**
|
||||
* A description of the share request
|
||||
* A description of the share request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $summary;
|
||||
|
||||
/**
|
||||
* The Etag for the notification
|
||||
* The Etag for the notification.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $etag;
|
||||
|
||||
/**
|
||||
* The list of supported components
|
||||
* The list of supported components.
|
||||
*
|
||||
* @var CalDAV\Xml\Property\SupportedCalendarComponentSet
|
||||
*/
|
||||
|
|
@ -138,8 +140,8 @@ class Invite implements NotificationInterface {
|
|||
*
|
||||
* @param array $values All the options
|
||||
*/
|
||||
function __construct(array $values) {
|
||||
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$required = [
|
||||
'id',
|
||||
'etag',
|
||||
|
|
@ -152,17 +154,16 @@ class Invite implements NotificationInterface {
|
|||
];
|
||||
foreach ($required as $item) {
|
||||
if (!isset($values[$item])) {
|
||||
throw new \InvalidArgumentException($item . ' is a required constructor option');
|
||||
throw new \InvalidArgumentException($item.' is a required constructor option');
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (!property_exists($this, $key)) {
|
||||
throw new \InvalidArgumentException('Unknown option: ' . $key);
|
||||
throw new \InvalidArgumentException('Unknown option: '.$key);
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -182,12 +183,10 @@ class Invite implements NotificationInterface {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
$writer->writeElement('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-notification');
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
$writer->writeElement('{'.CalDAV\Plugin::NS_CALENDARSERVER.'}invite-notification');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -195,95 +194,90 @@ class Invite implements NotificationInterface {
|
|||
* response body.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerializeFull(Writer $writer) {
|
||||
public function xmlSerializeFull(Writer $writer)
|
||||
{
|
||||
$cs = '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}';
|
||||
|
||||
$cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}';
|
||||
$this->dtStamp->setTimezone(new \DateTimeZone('GMT'));
|
||||
$writer->writeElement($cs.'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z'));
|
||||
|
||||
$this->dtStamp->setTimezone(new \DateTimezone('GMT'));
|
||||
$writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z'));
|
||||
$writer->startElement($cs.'invite-notification');
|
||||
|
||||
$writer->startElement($cs . 'invite-notification');
|
||||
|
||||
$writer->writeElement($cs . 'uid', $this->id);
|
||||
$writer->writeElement($cs.'uid', $this->id);
|
||||
$writer->writeElement('{DAV:}href', $this->href);
|
||||
|
||||
switch ($this->type) {
|
||||
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED :
|
||||
$writer->writeElement($cs . 'invite-accepted');
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED:
|
||||
$writer->writeElement($cs.'invite-accepted');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::INVITE_NORESPONSE :
|
||||
$writer->writeElement($cs . 'invite-noresponse');
|
||||
case DAV\Sharing\Plugin::INVITE_NORESPONSE:
|
||||
$writer->writeElement($cs.'invite-noresponse');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$writer->writeElement($cs . 'hosturl', [
|
||||
'{DAV:}href' => $writer->contextUri . $this->hostUrl
|
||||
$writer->writeElement($cs.'hosturl', [
|
||||
'{DAV:}href' => $writer->contextUri.$this->hostUrl,
|
||||
]);
|
||||
|
||||
if ($this->summary) {
|
||||
$writer->writeElement($cs . 'summary', $this->summary);
|
||||
$writer->writeElement($cs.'summary', $this->summary);
|
||||
}
|
||||
|
||||
$writer->startElement($cs . 'access');
|
||||
$writer->startElement($cs.'access');
|
||||
if ($this->readOnly) {
|
||||
$writer->writeElement($cs . 'read');
|
||||
$writer->writeElement($cs.'read');
|
||||
} else {
|
||||
$writer->writeElement($cs . 'read-write');
|
||||
$writer->writeElement($cs.'read-write');
|
||||
}
|
||||
$writer->endElement(); // access
|
||||
|
||||
$writer->startElement($cs . 'organizer');
|
||||
$writer->startElement($cs.'organizer');
|
||||
// If the organizer contains a 'mailto:' part, it means it should be
|
||||
// treated as absolute.
|
||||
if (strtolower(substr($this->organizer, 0, 7)) === 'mailto:') {
|
||||
if ('mailto:' === strtolower(substr($this->organizer, 0, 7))) {
|
||||
$writer->writeElement('{DAV:}href', $this->organizer);
|
||||
} else {
|
||||
$writer->writeElement('{DAV:}href', $writer->contextUri . $this->organizer);
|
||||
$writer->writeElement('{DAV:}href', $writer->contextUri.$this->organizer);
|
||||
}
|
||||
if ($this->commonName) {
|
||||
$writer->writeElement($cs . 'common-name', $this->commonName);
|
||||
$writer->writeElement($cs.'common-name', $this->commonName);
|
||||
}
|
||||
if ($this->firstName) {
|
||||
$writer->writeElement($cs . 'first-name', $this->firstName);
|
||||
$writer->writeElement($cs.'first-name', $this->firstName);
|
||||
}
|
||||
if ($this->lastName) {
|
||||
$writer->writeElement($cs . 'last-name', $this->lastName);
|
||||
$writer->writeElement($cs.'last-name', $this->lastName);
|
||||
}
|
||||
$writer->endElement(); // organizer
|
||||
|
||||
if ($this->commonName) {
|
||||
$writer->writeElement($cs . 'organizer-cn', $this->commonName);
|
||||
$writer->writeElement($cs.'organizer-cn', $this->commonName);
|
||||
}
|
||||
if ($this->firstName) {
|
||||
$writer->writeElement($cs . 'organizer-first', $this->firstName);
|
||||
$writer->writeElement($cs.'organizer-first', $this->firstName);
|
||||
}
|
||||
if ($this->lastName) {
|
||||
$writer->writeElement($cs . 'organizer-last', $this->lastName);
|
||||
$writer->writeElement($cs.'organizer-last', $this->lastName);
|
||||
}
|
||||
if ($this->supportedComponents) {
|
||||
$writer->writeElement('{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set', $this->supportedComponents);
|
||||
$writer->writeElement('{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set', $this->supportedComponents);
|
||||
}
|
||||
|
||||
$writer->endElement(); // invite-notification
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique id for this notification
|
||||
* Returns a unique id for this notification.
|
||||
*
|
||||
* This is just the base url. This should generally be some kind of unique
|
||||
* id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getId() {
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -293,10 +287,8 @@ class Invite implements NotificationInterface {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
return $this->etag;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Notification;
|
||||
|
||||
use Sabre\CalDAV;
|
||||
|
|
@ -14,19 +16,19 @@ use Sabre\Xml\Writer;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class InviteReply implements NotificationInterface {
|
||||
|
||||
class InviteReply implements NotificationInterface
|
||||
{
|
||||
/**
|
||||
* A unique id for the message
|
||||
* A unique id for the message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Timestamp of the notification
|
||||
* Timestamp of the notification.
|
||||
*
|
||||
* @var DateTime
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $dtStamp;
|
||||
|
||||
|
|
@ -59,14 +61,14 @@ class InviteReply implements NotificationInterface {
|
|||
protected $hostUrl;
|
||||
|
||||
/**
|
||||
* A description of the share request
|
||||
* A description of the share request.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $summary;
|
||||
|
||||
/**
|
||||
* Notification Etag
|
||||
* Notification Etag.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -90,8 +92,8 @@ class InviteReply implements NotificationInterface {
|
|||
*
|
||||
* @param array $values
|
||||
*/
|
||||
function __construct(array $values) {
|
||||
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$required = [
|
||||
'id',
|
||||
'etag',
|
||||
|
|
@ -103,17 +105,16 @@ class InviteReply implements NotificationInterface {
|
|||
];
|
||||
foreach ($required as $item) {
|
||||
if (!isset($values[$item])) {
|
||||
throw new \InvalidArgumentException($item . ' is a required constructor option');
|
||||
throw new \InvalidArgumentException($item.' is a required constructor option');
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if (!property_exists($this, $key)) {
|
||||
throw new \InvalidArgumentException('Unknown option: ' . $key);
|
||||
throw new \InvalidArgumentException('Unknown option: '.$key);
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -133,12 +134,10 @@ class InviteReply implements NotificationInterface {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
$writer->writeElement('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-reply');
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
$writer->writeElement('{'.CalDAV\Plugin::NS_CALENDARSERVER.'}invite-reply');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,55 +145,50 @@ class InviteReply implements NotificationInterface {
|
|||
* response body.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerializeFull(Writer $writer) {
|
||||
public function xmlSerializeFull(Writer $writer)
|
||||
{
|
||||
$cs = '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}';
|
||||
|
||||
$cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}';
|
||||
$this->dtStamp->setTimezone(new \DateTimeZone('GMT'));
|
||||
$writer->writeElement($cs.'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z'));
|
||||
|
||||
$this->dtStamp->setTimezone(new \DateTimezone('GMT'));
|
||||
$writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z'));
|
||||
$writer->startElement($cs.'invite-reply');
|
||||
|
||||
$writer->startElement($cs . 'invite-reply');
|
||||
|
||||
$writer->writeElement($cs . 'uid', $this->id);
|
||||
$writer->writeElement($cs . 'in-reply-to', $this->inReplyTo);
|
||||
$writer->writeElement($cs.'uid', $this->id);
|
||||
$writer->writeElement($cs.'in-reply-to', $this->inReplyTo);
|
||||
$writer->writeElement('{DAV:}href', $this->href);
|
||||
|
||||
switch ($this->type) {
|
||||
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED :
|
||||
$writer->writeElement($cs . 'invite-accepted');
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED:
|
||||
$writer->writeElement($cs.'invite-accepted');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::INVITE_DECLINED :
|
||||
$writer->writeElement($cs . 'invite-declined');
|
||||
case DAV\Sharing\Plugin::INVITE_DECLINED:
|
||||
$writer->writeElement($cs.'invite-declined');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$writer->writeElement($cs . 'hosturl', [
|
||||
'{DAV:}href' => $writer->contextUri . $this->hostUrl
|
||||
$writer->writeElement($cs.'hosturl', [
|
||||
'{DAV:}href' => $writer->contextUri.$this->hostUrl,
|
||||
]);
|
||||
|
||||
if ($this->summary) {
|
||||
$writer->writeElement($cs . 'summary', $this->summary);
|
||||
$writer->writeElement($cs.'summary', $this->summary);
|
||||
}
|
||||
$writer->endElement(); // invite-reply
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique id for this notification
|
||||
* Returns a unique id for this notification.
|
||||
*
|
||||
* This is just the base url. This should generally be some kind of unique
|
||||
* id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getId() {
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -204,10 +198,8 @@ class InviteReply implements NotificationInterface {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
return $this->etag;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Notification;
|
||||
|
||||
use Sabre\Xml\Writer;
|
||||
|
|
@ -12,26 +14,25 @@ use Sabre\Xml\XmlSerializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface NotificationInterface extends XmlSerializable {
|
||||
|
||||
interface NotificationInterface extends XmlSerializable
|
||||
{
|
||||
/**
|
||||
* This method serializes the entire notification, as it is used in the
|
||||
* response body.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerializeFull(Writer $writer);
|
||||
public function xmlSerializeFull(Writer $writer);
|
||||
|
||||
/**
|
||||
* Returns a unique id for this notification
|
||||
* Returns a unique id for this notification.
|
||||
*
|
||||
* This is just the base url. This should generally be some kind of unique
|
||||
* id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getId();
|
||||
public function getId();
|
||||
|
||||
/**
|
||||
* Returns the ETag for this notification.
|
||||
|
|
@ -40,6 +41,5 @@ interface NotificationInterface extends XmlSerializable {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag();
|
||||
|
||||
public function getETag();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Notification;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
use Sabre\Xml\Writer;
|
||||
|
||||
/**
|
||||
* SystemStatus notification
|
||||
* SystemStatus notification.
|
||||
*
|
||||
* This notification can be used to indicate to the user that the system is
|
||||
* down.
|
||||
|
|
@ -15,14 +17,14 @@ use Sabre\Xml\Writer;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SystemStatus implements NotificationInterface {
|
||||
|
||||
class SystemStatus implements NotificationInterface
|
||||
{
|
||||
const TYPE_LOW = 1;
|
||||
const TYPE_MEDIUM = 2;
|
||||
const TYPE_HIGH = 3;
|
||||
|
||||
/**
|
||||
* A unique id
|
||||
* A unique id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -50,7 +52,7 @@ class SystemStatus implements NotificationInterface {
|
|||
protected $href;
|
||||
|
||||
/**
|
||||
* Notification Etag
|
||||
* Notification Etag.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -64,18 +66,17 @@ class SystemStatus implements NotificationInterface {
|
|||
*
|
||||
* @param string $id
|
||||
* @param string $etag
|
||||
* @param int $type
|
||||
* @param int $type
|
||||
* @param string $description
|
||||
* @param string $href
|
||||
*/
|
||||
function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null) {
|
||||
|
||||
public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->description = $description;
|
||||
$this->href = $href;
|
||||
$this->etag = $etag;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,27 +92,25 @@ class SystemStatus implements NotificationInterface {
|
|||
* responsible for closing them.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
switch ($this->type) {
|
||||
case self::TYPE_LOW :
|
||||
case self::TYPE_LOW:
|
||||
$type = 'low';
|
||||
break;
|
||||
case self::TYPE_MEDIUM :
|
||||
case self::TYPE_MEDIUM:
|
||||
$type = 'medium';
|
||||
break;
|
||||
default :
|
||||
case self::TYPE_HIGH :
|
||||
default:
|
||||
case self::TYPE_HIGH:
|
||||
$type = 'high';
|
||||
break;
|
||||
}
|
||||
|
||||
$writer->startElement('{' . Plugin::NS_CALENDARSERVER . '}systemstatus');
|
||||
$writer->startElement('{'.Plugin::NS_CALENDARSERVER.'}systemstatus');
|
||||
$writer->writeAttribute('type', $type);
|
||||
$writer->endElement();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -119,51 +118,47 @@ class SystemStatus implements NotificationInterface {
|
|||
* response body.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerializeFull(Writer $writer) {
|
||||
|
||||
$cs = '{' . Plugin::NS_CALENDARSERVER . '}';
|
||||
public function xmlSerializeFull(Writer $writer)
|
||||
{
|
||||
$cs = '{'.Plugin::NS_CALENDARSERVER.'}';
|
||||
switch ($this->type) {
|
||||
case self::TYPE_LOW :
|
||||
case self::TYPE_LOW:
|
||||
$type = 'low';
|
||||
break;
|
||||
case self::TYPE_MEDIUM :
|
||||
case self::TYPE_MEDIUM:
|
||||
$type = 'medium';
|
||||
break;
|
||||
default :
|
||||
case self::TYPE_HIGH :
|
||||
default:
|
||||
case self::TYPE_HIGH:
|
||||
$type = 'high';
|
||||
break;
|
||||
}
|
||||
|
||||
$writer->startElement($cs . 'systemstatus');
|
||||
$writer->startElement($cs.'systemstatus');
|
||||
$writer->writeAttribute('type', $type);
|
||||
|
||||
|
||||
if ($this->description) {
|
||||
$writer->writeElement($cs . 'description', $this->description);
|
||||
$writer->writeElement($cs.'description', $this->description);
|
||||
}
|
||||
if ($this->href) {
|
||||
$writer->writeElement('{DAV:}href', $this->href);
|
||||
}
|
||||
|
||||
$writer->endElement(); // systemstatus
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique id for this notification
|
||||
* Returns a unique id for this notification.
|
||||
*
|
||||
* This is just the base url. This should generally be some kind of unique
|
||||
* id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getId() {
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -173,10 +168,8 @@ class SystemStatus implements NotificationInterface {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
return $this->etag;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -7,7 +9,7 @@ use Sabre\Xml\Writer;
|
|||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* AllowedSharingModes
|
||||
* AllowedSharingModes.
|
||||
*
|
||||
* This property encodes the 'allowed-sharing-modes' property, as defined by
|
||||
* the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/
|
||||
|
|
@ -18,14 +20,15 @@ use Sabre\Xml\XmlSerializable;
|
|||
* such as VEVENT, VTODO
|
||||
*
|
||||
* @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class AllowedSharingModes implements XmlSerializable {
|
||||
|
||||
class AllowedSharingModes implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* Whether or not a calendar can be shared with another user
|
||||
* Whether or not a calendar can be shared with another user.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
|
|
@ -39,17 +42,15 @@ class AllowedSharingModes implements XmlSerializable {
|
|||
protected $canBePublished;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param bool $canBeShared
|
||||
* @param bool $canBePublished
|
||||
* @return void
|
||||
*/
|
||||
function __construct($canBeShared, $canBePublished) {
|
||||
|
||||
public function __construct($canBeShared, $canBePublished)
|
||||
{
|
||||
$this->canBeShared = $canBeShared;
|
||||
$this->canBePublished = $canBePublished;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,19 +70,14 @@ class AllowedSharingModes implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
if ($this->canBeShared) {
|
||||
$writer->writeElement('{' . Plugin::NS_CALENDARSERVER . '}can-be-shared');
|
||||
$writer->writeElement('{'.Plugin::NS_CALENDARSERVER.'}can-be-shared');
|
||||
}
|
||||
if ($this->canBePublished) {
|
||||
$writer->writeElement('{' . Plugin::NS_CALENDARSERVER . '}can-be-published');
|
||||
$writer->writeElement('{'.Plugin::NS_CALENDARSERVER.'}can-be-published');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\Xml\Writer;
|
||||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* email-address-set property
|
||||
* email-address-set property.
|
||||
*
|
||||
* This property represents the email-address-set property in the
|
||||
* http://calendarserver.org/ns/ namespace.
|
||||
|
|
@ -17,35 +19,33 @@ use Sabre\Xml\XmlSerializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class EmailAddressSet implements XmlSerializable {
|
||||
|
||||
class EmailAddressSet implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* emails
|
||||
* emails.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $emails;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
* __construct.
|
||||
*
|
||||
* @param array $emails
|
||||
*/
|
||||
function __construct(array $emails) {
|
||||
|
||||
public function __construct(array $emails)
|
||||
{
|
||||
$this->emails = $emails;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the email addresses
|
||||
* Returns the email addresses.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getValue() {
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->emails;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -65,16 +65,11 @@ class EmailAddressSet implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
foreach ($this->emails as $email) {
|
||||
|
||||
$writer->writeElement('{http://calendarserver.org/ns/}email-address', $email);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -9,19 +11,20 @@ use Sabre\Xml\Writer;
|
|||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* Invite property
|
||||
* Invite property.
|
||||
*
|
||||
* This property encodes the 'invite' property, as defined by
|
||||
* the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/
|
||||
* namespace.
|
||||
*
|
||||
* @see https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing-02.txt
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Invite implements XmlSerializable {
|
||||
|
||||
class Invite implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* The list of users a calendar has been shared to.
|
||||
*
|
||||
|
|
@ -34,10 +37,9 @@ class Invite implements XmlSerializable {
|
|||
*
|
||||
* @param Sharee[] $sharees
|
||||
*/
|
||||
function __construct(array $sharees) {
|
||||
|
||||
public function __construct(array $sharees)
|
||||
{
|
||||
$this->sharees = $sharees;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,10 +47,9 @@ class Invite implements XmlSerializable {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getValue() {
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->sharees;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,61 +69,54 @@ class Invite implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
$cs = '{' . Plugin::NS_CALENDARSERVER . '}';
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
$cs = '{'.Plugin::NS_CALENDARSERVER.'}';
|
||||
|
||||
foreach ($this->sharees as $sharee) {
|
||||
|
||||
if ($sharee->access === DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
|
||||
$writer->startElement($cs . 'organizer');
|
||||
if (DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $sharee->access) {
|
||||
$writer->startElement($cs.'organizer');
|
||||
} else {
|
||||
$writer->startElement($cs . 'user');
|
||||
$writer->startElement($cs.'user');
|
||||
|
||||
switch ($sharee->inviteStatus) {
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED :
|
||||
$writer->writeElement($cs . 'invite-accepted');
|
||||
case DAV\Sharing\Plugin::INVITE_ACCEPTED:
|
||||
$writer->writeElement($cs.'invite-accepted');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::INVITE_DECLINED :
|
||||
$writer->writeElement($cs . 'invite-declined');
|
||||
case DAV\Sharing\Plugin::INVITE_DECLINED:
|
||||
$writer->writeElement($cs.'invite-declined');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::INVITE_NORESPONSE :
|
||||
$writer->writeElement($cs . 'invite-noresponse');
|
||||
case DAV\Sharing\Plugin::INVITE_NORESPONSE:
|
||||
$writer->writeElement($cs.'invite-noresponse');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::INVITE_INVALID :
|
||||
$writer->writeElement($cs . 'invite-invalid');
|
||||
case DAV\Sharing\Plugin::INVITE_INVALID:
|
||||
$writer->writeElement($cs.'invite-invalid');
|
||||
break;
|
||||
}
|
||||
|
||||
$writer->startElement($cs . 'access');
|
||||
$writer->startElement($cs.'access');
|
||||
switch ($sharee->access) {
|
||||
case DAV\Sharing\Plugin::ACCESS_READWRITE :
|
||||
$writer->writeElement($cs . 'read-write');
|
||||
case DAV\Sharing\Plugin::ACCESS_READWRITE:
|
||||
$writer->writeElement($cs.'read-write');
|
||||
break;
|
||||
case DAV\Sharing\Plugin::ACCESS_READ :
|
||||
$writer->writeElement($cs . 'read');
|
||||
case DAV\Sharing\Plugin::ACCESS_READ:
|
||||
$writer->writeElement($cs.'read');
|
||||
break;
|
||||
|
||||
}
|
||||
$writer->endElement(); // access
|
||||
|
||||
}
|
||||
|
||||
$href = new DAV\Xml\Property\Href($sharee->href);
|
||||
$href->xmlSerialize($writer);
|
||||
|
||||
if (isset($sharee->properties['{DAV:}displayname'])) {
|
||||
$writer->writeElement($cs . 'common-name', $sharee->properties['{DAV:}displayname']);
|
||||
$writer->writeElement($cs.'common-name', $sharee->properties['{DAV:}displayname']);
|
||||
}
|
||||
if ($sharee->comment) {
|
||||
$writer->writeElement($cs . 'summary', $sharee->comment);
|
||||
$writer->writeElement($cs.'summary', $sharee->comment);
|
||||
}
|
||||
$writer->endElement(); // organizer or user
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -24,41 +26,39 @@ use Sabre\Xml\Writer;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class ScheduleCalendarTransp implements Element {
|
||||
|
||||
class ScheduleCalendarTransp implements Element
|
||||
{
|
||||
const TRANSPARENT = 'transparent';
|
||||
const OPAQUE = 'opaque';
|
||||
|
||||
/**
|
||||
* value
|
||||
* value.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* Creates the property
|
||||
* Creates the property.
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
function __construct($value) {
|
||||
|
||||
if ($value !== self::TRANSPARENT && $value !== self::OPAQUE) {
|
||||
public function __construct($value)
|
||||
{
|
||||
if (self::TRANSPARENT !== $value && self::OPAQUE !== $value) {
|
||||
throw new \InvalidArgumentException('The value must either be specified as "transparent" or "opaque"');
|
||||
}
|
||||
$this->value = $value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value
|
||||
* Returns the current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getValue() {
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -78,19 +78,17 @@ class ScheduleCalendarTransp implements Element {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
switch ($this->value) {
|
||||
case self::TRANSPARENT :
|
||||
$writer->writeElement('{' . Plugin::NS_CALDAV . '}transparent');
|
||||
case self::TRANSPARENT:
|
||||
$writer->writeElement('{'.Plugin::NS_CALDAV.'}transparent');
|
||||
break;
|
||||
case self::OPAQUE :
|
||||
$writer->writeElement('{' . Plugin::NS_CALDAV . '}opaque');
|
||||
case self::OPAQUE:
|
||||
$writer->writeElement('{'.Plugin::NS_CALDAV.'}opaque');
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -112,10 +110,11 @@ class ScheduleCalendarTransp implements Element {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = Deserializer\enum($reader, Plugin::NS_CALDAV);
|
||||
|
||||
if (in_array('transparent', $elems)) {
|
||||
|
|
@ -123,8 +122,7 @@ class ScheduleCalendarTransp implements Element {
|
|||
} else {
|
||||
$value = self::OPAQUE;
|
||||
}
|
||||
|
||||
return new self($value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -21,8 +23,8 @@ use Sabre\Xml\Writer;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SupportedCalendarComponentSet implements Element {
|
||||
|
||||
class SupportedCalendarComponentSet implements Element
|
||||
{
|
||||
/**
|
||||
* List of supported components.
|
||||
*
|
||||
|
|
@ -37,21 +39,19 @@ class SupportedCalendarComponentSet implements Element {
|
|||
*
|
||||
* @param array $components
|
||||
*/
|
||||
function __construct(array $components) {
|
||||
|
||||
public function __construct(array $components)
|
||||
{
|
||||
$this->components = $components;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of supported components
|
||||
* Returns the list of supported components.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getValue() {
|
||||
|
||||
public function getValue()
|
||||
{
|
||||
return $this->components;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -71,18 +71,14 @@ class SupportedCalendarComponentSet implements Element {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
foreach ($this->components as $component) {
|
||||
|
||||
$writer->startElement('{' . Plugin::NS_CALDAV . '}comp');
|
||||
$writer->startElement('{'.Plugin::NS_CALDAV.'}comp');
|
||||
$writer->writeAttributes(['name' => $component]);
|
||||
$writer->endElement();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -104,16 +100,17 @@ class SupportedCalendarComponentSet implements Element {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
$components = [];
|
||||
|
||||
foreach ((array)$elems as $elem) {
|
||||
if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}comp') {
|
||||
foreach ((array) $elems as $elem) {
|
||||
if ($elem['name'] === '{'.Plugin::NS_CALDAV.'}comp') {
|
||||
$components[] = $elem['attributes']['name'];
|
||||
}
|
||||
}
|
||||
|
|
@ -123,7 +120,5 @@ class SupportedCalendarComponentSet implements Element {
|
|||
}
|
||||
|
||||
return new self($components);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -7,7 +9,7 @@ use Sabre\Xml\Writer;
|
|||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* Supported-calendar-data property
|
||||
* Supported-calendar-data property.
|
||||
*
|
||||
* This property is a representation of the supported-calendar-data property
|
||||
* in the CalDAV namespace. SabreDAV only has support for text/calendar;2.0
|
||||
|
|
@ -20,8 +22,8 @@ use Sabre\Xml\XmlSerializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SupportedCalendarData implements XmlSerializable {
|
||||
|
||||
class SupportedCalendarData implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* The xmlSerialize method is called during xml writing.
|
||||
*
|
||||
|
|
@ -39,22 +41,19 @@ class SupportedCalendarData implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
$writer->startElement('{' . Plugin::NS_CALDAV . '}calendar-data');
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
$writer->startElement('{'.Plugin::NS_CALDAV.'}calendar-data');
|
||||
$writer->writeAttributes([
|
||||
'content-type' => 'text/calendar',
|
||||
'version' => '2.0',
|
||||
'version' => '2.0',
|
||||
]);
|
||||
$writer->endElement(); // calendar-data
|
||||
$writer->startElement('{' . Plugin::NS_CALDAV . '}calendar-data');
|
||||
$writer->startElement('{'.Plugin::NS_CALDAV.'}calendar-data');
|
||||
$writer->writeAttributes([
|
||||
'content-type' => 'application/calendar+json',
|
||||
]);
|
||||
$writer->endElement(); // calendar-data
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Property;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -7,7 +9,7 @@ use Sabre\Xml\Writer;
|
|||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* supported-collation-set property
|
||||
* supported-collation-set property.
|
||||
*
|
||||
* This property is a representation of the supported-collation-set property
|
||||
* in the CalDAV namespace.
|
||||
|
|
@ -19,8 +21,8 @@ use Sabre\Xml\XmlSerializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SupportedCollationSet implements XmlSerializable {
|
||||
|
||||
class SupportedCollationSet implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* The xmlSerialize method is called during xml writing.
|
||||
*
|
||||
|
|
@ -38,20 +40,17 @@ class SupportedCollationSet implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
$collations = [
|
||||
'i;ascii-casemap',
|
||||
'i;octet',
|
||||
'i;unicode-casemap'
|
||||
'i;unicode-casemap',
|
||||
];
|
||||
|
||||
foreach ($collations as $collation) {
|
||||
$writer->writeElement('{' . Plugin::NS_CALDAV . '}supported-collation', $collation);
|
||||
$writer->writeElement('{'.Plugin::NS_CALDAV.'}supported-collation', $collation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -19,8 +21,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarMultiGetReport implements XmlDeserializable {
|
||||
|
||||
class CalendarMultiGetReport implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* An array with requested properties.
|
||||
*
|
||||
|
|
@ -80,36 +82,33 @@ class CalendarMultiGetReport implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = $reader->parseInnerTree([
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData',
|
||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
]);
|
||||
|
||||
$newProps = [
|
||||
'hrefs' => [],
|
||||
'hrefs' => [],
|
||||
'properties' => [],
|
||||
];
|
||||
|
||||
foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{DAV:}prop' :
|
||||
case '{DAV:}prop':
|
||||
$newProps['properties'] = array_keys($elem['value']);
|
||||
if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
|
||||
$newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
|
||||
if (isset($elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'])) {
|
||||
$newProps += $elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'];
|
||||
}
|
||||
break;
|
||||
case '{DAV:}href' :
|
||||
case '{DAV:}href':
|
||||
$newProps['hrefs'][] = Uri\resolve($reader->contextUri, $elem['value']);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$obj = new self();
|
||||
|
|
@ -118,7 +117,5 @@ class CalendarMultiGetReport implements XmlDeserializable {
|
|||
}
|
||||
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -19,8 +21,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalendarQueryReport implements XmlDeserializable {
|
||||
|
||||
class CalendarQueryReport implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* An array with requested properties.
|
||||
*
|
||||
|
|
@ -80,38 +82,39 @@ class CalendarQueryReport implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = $reader->parseInnerTree([
|
||||
'{urn:ietf:params:xml:ns:caldav}comp-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}prop-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}param-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}comp-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}prop-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}param-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter',
|
||||
'{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData',
|
||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
]);
|
||||
|
||||
$newProps = [
|
||||
'filters' => null,
|
||||
'filters' => null,
|
||||
'properties' => [],
|
||||
];
|
||||
|
||||
if (!is_array($elems)) $elems = [];
|
||||
if (!is_array($elems)) {
|
||||
$elems = [];
|
||||
}
|
||||
|
||||
foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{DAV:}prop' :
|
||||
case '{DAV:}prop':
|
||||
$newProps['properties'] = array_keys($elem['value']);
|
||||
if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
|
||||
$newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
|
||||
if (isset($elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'])) {
|
||||
$newProps += $elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'];
|
||||
}
|
||||
break;
|
||||
case '{' . Plugin::NS_CALDAV . '}filter' :
|
||||
case '{'.Plugin::NS_CALDAV.'}filter':
|
||||
foreach ($elem['value'] as $subElem) {
|
||||
if ($subElem['name'] === '{' . Plugin::NS_CALDAV . '}comp-filter') {
|
||||
if ($subElem['name'] === '{'.Plugin::NS_CALDAV.'}comp-filter') {
|
||||
if (!is_null($newProps['filters'])) {
|
||||
throw new BadRequest('Only one top-level comp-filter may be defined');
|
||||
}
|
||||
|
|
@ -119,21 +122,18 @@ class CalendarQueryReport implements XmlDeserializable {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (is_null($newProps['filters'])) {
|
||||
throw new BadRequest('The {' . Plugin::NS_CALDAV . '}filter element is required for this request');
|
||||
throw new BadRequest('The {'.Plugin::NS_CALDAV.'}filter element is required for this request');
|
||||
}
|
||||
|
||||
$obj = new self();
|
||||
foreach ($newProps as $key => $value) {
|
||||
$obj->$key = $value;
|
||||
}
|
||||
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -9,7 +11,7 @@ use Sabre\Xml\Reader;
|
|||
use Sabre\Xml\XmlDeserializable;
|
||||
|
||||
/**
|
||||
* FreeBusyQueryReport
|
||||
* FreeBusyQueryReport.
|
||||
*
|
||||
* This class parses the {DAV:}free-busy-query REPORT, as defined in:
|
||||
*
|
||||
|
|
@ -19,19 +21,19 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class FreeBusyQueryReport implements XmlDeserializable {
|
||||
|
||||
class FreeBusyQueryReport implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* Starttime of report
|
||||
* Starttime of report.
|
||||
*
|
||||
* @var DateTime|null
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
public $start;
|
||||
|
||||
/**
|
||||
* End time of report
|
||||
* End time of report.
|
||||
*
|
||||
* @var DateTime|null
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
public $end;
|
||||
|
||||
|
|
@ -54,22 +56,23 @@ class FreeBusyQueryReport implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
$timeRange = '{' . Plugin::NS_CALDAV . '}time-range';
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$timeRange = '{'.Plugin::NS_CALDAV.'}time-range';
|
||||
|
||||
$start = null;
|
||||
$end = null;
|
||||
|
||||
foreach ((array)$reader->parseInnerTree([]) as $elem) {
|
||||
|
||||
if ($elem['name'] !== $timeRange) continue;
|
||||
foreach ((array) $reader->parseInnerTree([]) as $elem) {
|
||||
if ($elem['name'] !== $timeRange) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$start = empty($elem['attributes']['start']) ?: $elem['attributes']['start'];
|
||||
$end = empty($elem['attributes']['end']) ?: $elem['attributes']['end'];
|
||||
|
||||
}
|
||||
if (!$start && !$end) {
|
||||
throw new BadRequest('The freebusy report must have a time-range element');
|
||||
|
|
@ -85,7 +88,5 @@ class FreeBusyQueryReport implements XmlDeserializable {
|
|||
$result->end = $end;
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -11,7 +13,7 @@ use Sabre\Xml\Reader;
|
|||
use Sabre\Xml\XmlDeserializable;
|
||||
|
||||
/**
|
||||
* Invite-reply POST request parser
|
||||
* Invite-reply POST request parser.
|
||||
*
|
||||
* This class parses the invite-reply POST request, as defined in:
|
||||
*
|
||||
|
|
@ -21,8 +23,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class InviteReply implements XmlDeserializable {
|
||||
|
||||
class InviteReply implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The sharee calendar user address.
|
||||
*
|
||||
|
|
@ -40,14 +42,14 @@ class InviteReply implements XmlDeserializable {
|
|||
public $calendarUri;
|
||||
|
||||
/**
|
||||
* The id of the invite message that's being responded to
|
||||
* The id of the invite message that's being responded to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $inReplyTo;
|
||||
|
||||
/**
|
||||
* An optional message
|
||||
* An optional message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -61,22 +63,21 @@ class InviteReply implements XmlDeserializable {
|
|||
public $status;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $href
|
||||
* @param string $calendarUri
|
||||
* @param string $inReplyTo
|
||||
* @param string $summary
|
||||
* @param int $status
|
||||
* @param int $status
|
||||
*/
|
||||
function __construct($href, $calendarUri, $inReplyTo, $summary, $status) {
|
||||
|
||||
public function __construct($href, $calendarUri, $inReplyTo, $summary, $status)
|
||||
{
|
||||
$this->href = $href;
|
||||
$this->calendarUri = $calendarUri;
|
||||
$this->inReplyTo = $inReplyTo;
|
||||
$this->summary = $summary;
|
||||
$this->status = $status;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,10 +99,11 @@ class InviteReply implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = KeyValue::xmlDeserialize($reader);
|
||||
|
||||
$href = null;
|
||||
|
|
@ -111,40 +113,35 @@ class InviteReply implements XmlDeserializable {
|
|||
$status = null;
|
||||
|
||||
foreach ($elems as $name => $value) {
|
||||
|
||||
switch ($name) {
|
||||
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}hosturl' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}hosturl':
|
||||
foreach ($value as $bla) {
|
||||
if ($bla['name'] === '{DAV:}href') {
|
||||
if ('{DAV:}href' === $bla['name']) {
|
||||
$calendarUri = $bla['value'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}invite-accepted' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}invite-accepted':
|
||||
$status = DAV\Sharing\Plugin::INVITE_ACCEPTED;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}invite-declined' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}invite-declined':
|
||||
$status = DAV\Sharing\Plugin::INVITE_DECLINED;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}in-reply-to' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}in-reply-to':
|
||||
$inReplyTo = $value;
|
||||
break;
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}summary' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}summary':
|
||||
$summary = $value;
|
||||
break;
|
||||
case '{DAV:}href' :
|
||||
case '{DAV:}href':
|
||||
$href = $value;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (is_null($calendarUri)) {
|
||||
throw new BadRequest('The {http://calendarserver.org/ns/}hosturl/{DAV:}href element must exist');
|
||||
}
|
||||
|
||||
return new self($href, $calendarUri, $inReplyTo, $summary, $status);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\Xml\Reader;
|
||||
|
|
@ -16,8 +18,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class MkCalendar implements XmlDeserializable {
|
||||
|
||||
class MkCalendar implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The list of properties that will be set.
|
||||
*
|
||||
|
|
@ -30,10 +32,9 @@ class MkCalendar implements XmlDeserializable {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getProperties() {
|
||||
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -55,10 +56,11 @@ class MkCalendar implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$self = new self();
|
||||
|
||||
$elementMap = $reader->elementMap;
|
||||
|
|
@ -67,13 +69,11 @@ class MkCalendar implements XmlDeserializable {
|
|||
$elems = $reader->parseInnerTree($elementMap);
|
||||
|
||||
foreach ($elems as $elem) {
|
||||
if ($elem['name'] === '{DAV:}set') {
|
||||
if ('{DAV:}set' === $elem['name']) {
|
||||
$self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']);
|
||||
}
|
||||
}
|
||||
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CalDAV\Xml\Request;
|
||||
|
||||
use Sabre\CalDAV\Plugin;
|
||||
|
|
@ -8,7 +10,7 @@ use Sabre\Xml\Reader;
|
|||
use Sabre\Xml\XmlDeserializable;
|
||||
|
||||
/**
|
||||
* Share POST request parser
|
||||
* Share POST request parser.
|
||||
*
|
||||
* This class parses the share POST request, as defined in:
|
||||
*
|
||||
|
|
@ -18,8 +20,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Share implements XmlDeserializable {
|
||||
|
||||
class Share implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The list of new people added or updated or removed from the share.
|
||||
*
|
||||
|
|
@ -28,14 +30,13 @@ class Share implements XmlDeserializable {
|
|||
public $sharees = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Sharee[] $sharees
|
||||
*/
|
||||
function __construct(array $sharees) {
|
||||
|
||||
public function __construct(array $sharees)
|
||||
{
|
||||
$this->sharees = $sharees;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,55 +58,52 @@ class Share implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$elems = $reader->parseGetElements([
|
||||
'{' . Plugin::NS_CALENDARSERVER . '}set' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{' . Plugin::NS_CALENDARSERVER . '}remove' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{'.Plugin::NS_CALENDARSERVER.'}set' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
'{'.Plugin::NS_CALENDARSERVER.'}remove' => 'Sabre\\Xml\\Element\\KeyValue',
|
||||
]);
|
||||
|
||||
$sharees = [];
|
||||
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}set' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}set':
|
||||
$sharee = $elem['value'];
|
||||
|
||||
$sumElem = '{' . Plugin::NS_CALENDARSERVER . '}summary';
|
||||
$commonName = '{' . Plugin::NS_CALENDARSERVER . '}common-name';
|
||||
$sumElem = '{'.Plugin::NS_CALENDARSERVER.'}summary';
|
||||
$commonName = '{'.Plugin::NS_CALENDARSERVER.'}common-name';
|
||||
|
||||
$properties = [];
|
||||
if (isset($sharee[$commonName])) {
|
||||
$properties['{DAV:}displayname'] = $sharee[$commonName];
|
||||
}
|
||||
|
||||
$access = array_key_exists('{' . Plugin::NS_CALENDARSERVER . '}read-write', $sharee)
|
||||
$access = array_key_exists('{'.Plugin::NS_CALENDARSERVER.'}read-write', $sharee)
|
||||
? \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE
|
||||
: \Sabre\DAV\Sharing\Plugin::ACCESS_READ;
|
||||
|
||||
$sharees[] = new Sharee([
|
||||
'href' => $sharee['{DAV:}href'],
|
||||
'href' => $sharee['{DAV:}href'],
|
||||
'properties' => $properties,
|
||||
'access' => $access,
|
||||
'comment' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null
|
||||
'access' => $access,
|
||||
'comment' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null,
|
||||
]);
|
||||
break;
|
||||
|
||||
case '{' . Plugin::NS_CALENDARSERVER . '}remove' :
|
||||
case '{'.Plugin::NS_CALENDARSERVER.'}remove':
|
||||
$sharees[] = new Sharee([
|
||||
'href' => $elem['value']['{DAV:}href'],
|
||||
'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS
|
||||
'href' => $elem['value']['{DAV:}href'],
|
||||
'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS,
|
||||
]);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new self($sharees);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* The AddressBook class represents a CardDAV addressbook, owned by a specific user
|
||||
* The AddressBook class represents a CardDAV addressbook, owned by a specific user.
|
||||
*
|
||||
* The AddressBook can contain multiple vcards
|
||||
*
|
||||
|
|
@ -14,77 +16,78 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class AddressBook extends DAV\Collection implements IAddressBook, DAV\IProperties, DAVACL\IACL, DAV\Sync\ISyncCollection, DAV\IMultiGet {
|
||||
|
||||
class AddressBook extends DAV\Collection implements IAddressBook, DAV\IProperties, DAVACL\IACL, DAV\Sync\ISyncCollection, DAV\IMultiGet
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* This is an array with addressbook information
|
||||
* This is an array with addressbook information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $addressBookInfo;
|
||||
|
||||
/**
|
||||
* CardDAV backend
|
||||
* CardDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $carddavBackend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\BackendInterface $carddavBackend
|
||||
* @param array $addressBookInfo
|
||||
* @param array $addressBookInfo
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo)
|
||||
{
|
||||
$this->carddavBackend = $carddavBackend;
|
||||
$this->addressBookInfo = $addressBookInfo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the addressbook
|
||||
* Returns the name of the addressbook.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->addressBookInfo['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a card
|
||||
* Returns a card.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Card
|
||||
*/
|
||||
function getChild($name) {
|
||||
|
||||
public function getChild($name)
|
||||
{
|
||||
$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
|
||||
if (!$obj) throw new DAV\Exception\NotFound('Card not found');
|
||||
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
|
||||
if (!$obj) {
|
||||
throw new DAV\Exception\NotFound('Card not found');
|
||||
}
|
||||
|
||||
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full list of cards
|
||||
* Returns the full list of cards.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$objs = $this->carddavBackend->getCards($this->addressBookInfo['id']);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj);
|
||||
}
|
||||
return $children;
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,47 +97,47 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
* If any children are not found, you do not have to return them.
|
||||
*
|
||||
* @param string[] $paths
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleChildren(array $paths) {
|
||||
|
||||
public function getMultipleChildren(array $paths)
|
||||
{
|
||||
$objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths);
|
||||
$children = [];
|
||||
foreach ($objs as $obj) {
|
||||
$obj['acl'] = $this->getChildACL();
|
||||
$children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj);
|
||||
}
|
||||
return $children;
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new directory
|
||||
* Creates a new directory.
|
||||
*
|
||||
* We actually block this, as subdirectories are not allowed in addressbooks.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($name) {
|
||||
|
||||
public function createDirectory($name)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating collections in addressbooks is not allowed');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file
|
||||
* Creates a new file.
|
||||
*
|
||||
* The contents of the new file must be a valid VCARD.
|
||||
*
|
||||
* This method may return an ETag.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @param resource $vcardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createFile($name, $vcardData = null) {
|
||||
|
||||
public function createFile($name, $vcardData = null)
|
||||
{
|
||||
if (is_resource($vcardData)) {
|
||||
$vcardData = stream_get_contents($vcardData);
|
||||
}
|
||||
|
|
@ -142,41 +145,32 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
$vcardData = DAV\StringUtil::ensureUTF8($vcardData);
|
||||
|
||||
return $this->carddavBackend->createCard($this->addressBookInfo['id'], $name, $vcardData);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entire addressbook.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->carddavBackend->deleteAddressBook($this->addressBookInfo['id']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the addressbook
|
||||
* Renames the addressbook.
|
||||
*
|
||||
* @param string $newName
|
||||
* @return void
|
||||
*/
|
||||
function setName($newName) {
|
||||
|
||||
public function setName($newName)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Renaming addressbooks is not yet supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -189,12 +183,10 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
* Read the PropPatch documentation for more information.
|
||||
*
|
||||
* @param DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function propPatch(DAV\PropPatch $propPatch) {
|
||||
|
||||
public function propPatch(DAV\PropPatch $propPatch)
|
||||
{
|
||||
return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $propPatch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -206,39 +198,33 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
* If the array is empty, it means 'all properties' were requested.
|
||||
*
|
||||
* @param array $properties
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getProperties($properties) {
|
||||
|
||||
public function getProperties($properties)
|
||||
{
|
||||
$response = [];
|
||||
foreach ($properties as $propertyName) {
|
||||
|
||||
if (isset($this->addressBookInfo[$propertyName])) {
|
||||
|
||||
$response[$propertyName] = $this->addressBookInfo[$propertyName];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->addressBookInfo['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the ACL's for card nodes in this address book.
|
||||
* The result of this method automatically gets passed to the
|
||||
|
|
@ -246,8 +232,8 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildACL() {
|
||||
|
||||
public function getChildACL()
|
||||
{
|
||||
return [
|
||||
[
|
||||
'privilege' => '{DAV:}all',
|
||||
|
|
@ -255,10 +241,8 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
'protected' => true,
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the current sync-token for this collection.
|
||||
* This can be any string.
|
||||
|
|
@ -268,8 +252,8 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getSyncToken() {
|
||||
|
||||
public function getSyncToken()
|
||||
{
|
||||
if (
|
||||
$this->carddavBackend instanceof Backend\SyncSupport &&
|
||||
isset($this->addressBookInfo['{DAV:}sync-token'])
|
||||
|
|
@ -282,7 +266,6 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
) {
|
||||
return $this->addressBookInfo['{http://sabredav.org/ns}sync-token'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -336,12 +319,13 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
* The limit is 'suggestive'. You are free to ignore it.
|
||||
*
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChanges($syncToken, $syncLevel, $limit = null) {
|
||||
|
||||
public function getChanges($syncToken, $syncLevel, $limit = null)
|
||||
{
|
||||
if (!$this->carddavBackend instanceof Backend\SyncSupport) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -352,6 +336,5 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
|
|||
$syncLevel,
|
||||
$limit
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -8,7 +10,7 @@ use Sabre\DAVACL;
|
|||
use Sabre\Uri;
|
||||
|
||||
/**
|
||||
* AddressBook Home class
|
||||
* AddressBook Home class.
|
||||
*
|
||||
* This collection contains a list of addressbooks associated with one user.
|
||||
*
|
||||
|
|
@ -16,81 +18,74 @@ use Sabre\Uri;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection, DAVACL\IACL {
|
||||
|
||||
class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* Principal uri
|
||||
* Principal uri.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalUri;
|
||||
|
||||
/**
|
||||
* carddavBackend
|
||||
* carddavBackend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $carddavBackend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\BackendInterface $carddavBackend
|
||||
* @param string $principalUri
|
||||
* @param string $principalUri
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $carddavBackend, $principalUri) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $carddavBackend, $principalUri)
|
||||
{
|
||||
$this->carddavBackend = $carddavBackend;
|
||||
$this->principalUri = $principalUri;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
list(, $name) = Uri\split($this->principalUri);
|
||||
return $name;
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the name of this object
|
||||
* Updates the name of this object.
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
function setName($name) {
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this object
|
||||
*
|
||||
* @return void
|
||||
* Deletes this object.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date
|
||||
* Returns the last modification date.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,14 +93,12 @@ class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection,
|
|||
*
|
||||
* This is currently not allowed
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $filename
|
||||
* @param resource $data
|
||||
* @return void
|
||||
*/
|
||||
function createFile($filename, $data = null) {
|
||||
|
||||
public function createFile($filename, $data = null)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,78 +107,74 @@ class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection,
|
|||
* This is currently not allowed.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($filename) {
|
||||
|
||||
public function createDirectory($filename)
|
||||
{
|
||||
throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single addressbook, by name
|
||||
* Returns a single addressbook, by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @todo needs optimizing
|
||||
*
|
||||
* @return AddressBook
|
||||
*/
|
||||
function getChild($name) {
|
||||
|
||||
public function getChild($name)
|
||||
{
|
||||
foreach ($this->getChildren() as $child) {
|
||||
if ($name == $child->getName())
|
||||
if ($name == $child->getName()) {
|
||||
return $child;
|
||||
|
||||
}
|
||||
}
|
||||
throw new DAV\Exception\NotFound('Addressbook with name \'' . $name . '\' could not be found');
|
||||
|
||||
throw new DAV\Exception\NotFound('Addressbook with name \''.$name.'\' could not be found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of addressbooks
|
||||
* Returns a list of addressbooks.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChildren() {
|
||||
|
||||
public function getChildren()
|
||||
{
|
||||
$addressbooks = $this->carddavBackend->getAddressBooksForUser($this->principalUri);
|
||||
$objs = [];
|
||||
foreach ($addressbooks as $addressbook) {
|
||||
$objs[] = new AddressBook($this->carddavBackend, $addressbook);
|
||||
}
|
||||
return $objs;
|
||||
|
||||
return $objs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new address book.
|
||||
*
|
||||
* @param string $name
|
||||
* @param MkCol $mkCol
|
||||
* @param MkCol $mkCol
|
||||
*
|
||||
* @throws DAV\Exception\InvalidResourceType
|
||||
* @return void
|
||||
*/
|
||||
function createExtendedCollection($name, MkCol $mkCol) {
|
||||
|
||||
if (!$mkCol->hasResourceType('{' . Plugin::NS_CARDDAV . '}addressbook')) {
|
||||
public function createExtendedCollection($name, MkCol $mkCol)
|
||||
{
|
||||
if (!$mkCol->hasResourceType('{'.Plugin::NS_CARDDAV.'}addressbook')) {
|
||||
throw new DAV\Exception\InvalidResourceType('Unknown resourceType for this collection');
|
||||
}
|
||||
$properties = $mkCol->getRemainingValues();
|
||||
$mkCol->setRemainingResultCode(201);
|
||||
$this->carddavBackend->createAddressBook($this->principalUri, $name, $properties);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->principalUri;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* AddressBook rootnode
|
||||
* AddressBook rootnode.
|
||||
*
|
||||
* This object lists a collection of users, which can contain addressbooks.
|
||||
*
|
||||
|
|
@ -13,24 +15,24 @@ use Sabre\DAVACL;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class AddressBookRoot extends DAVACL\AbstractPrincipalCollection {
|
||||
|
||||
class AddressBookRoot extends DAVACL\AbstractPrincipalCollection
|
||||
{
|
||||
/**
|
||||
* Principal Backend
|
||||
* Principal Backend.
|
||||
*
|
||||
* @var DAVACL\PrincipalBackend\BackendInterface
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* CardDAV backend
|
||||
* CardDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $carddavBackend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* This constructor needs both a principal and a carddav backend.
|
||||
*
|
||||
|
|
@ -40,25 +42,23 @@ class AddressBookRoot extends DAVACL\AbstractPrincipalCollection {
|
|||
* to override this.
|
||||
*
|
||||
* @param DAVACL\PrincipalBackend\BackendInterface $principalBackend
|
||||
* @param Backend\BackendInterface $carddavBackend
|
||||
* @param string $principalPrefix
|
||||
* @param Backend\BackendInterface $carddavBackend
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $carddavBackend, $principalPrefix = 'principals') {
|
||||
|
||||
public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, Backend\BackendInterface $carddavBackend, $principalPrefix = 'principals')
|
||||
{
|
||||
$this->carddavBackend = $carddavBackend;
|
||||
parent::__construct($principalBackend, $principalPrefix);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the node
|
||||
* Returns the name of the node.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return Plugin::ADDRESSBOOK_ROOT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,12 +69,11 @@ class AddressBookRoot extends DAVACL\AbstractPrincipalCollection {
|
|||
* supplied by the authentication backend.
|
||||
*
|
||||
* @param array $principal
|
||||
*
|
||||
* @return \Sabre\DAV\INode
|
||||
*/
|
||||
function getChildForPrincipal(array $principal) {
|
||||
|
||||
public function getChildForPrincipal(array $principal)
|
||||
{
|
||||
return new AddressBookHome($this->carddavBackend, $principal['uri']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Backend;
|
||||
|
||||
/**
|
||||
* CardDAV abstract Backend
|
||||
* CardDAV abstract Backend.
|
||||
*
|
||||
* This class serves as a base-class for addressbook backends
|
||||
*
|
||||
|
|
@ -13,8 +15,8 @@ namespace Sabre\CardDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
abstract class AbstractBackend implements BackendInterface {
|
||||
|
||||
abstract class AbstractBackend implements BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of cards.
|
||||
*
|
||||
|
|
@ -25,14 +27,13 @@ abstract class AbstractBackend implements BackendInterface {
|
|||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param array $uris
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleCards($addressBookId, array $uris) {
|
||||
|
||||
return array_map(function($uri) use ($addressBookId) {
|
||||
public function getMultipleCards($addressBookId, array $uris)
|
||||
{
|
||||
return array_map(function ($uri) use ($addressBookId) {
|
||||
return $this->getCard($addressBookId, $uri);
|
||||
}, $uris);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Backend;
|
||||
|
||||
/**
|
||||
* CardDAV Backend Interface
|
||||
* CardDAV Backend Interface.
|
||||
*
|
||||
* Any CardDAV backend must implement this interface.
|
||||
*
|
||||
|
|
@ -15,8 +17,8 @@ namespace Sabre\CardDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface BackendInterface {
|
||||
|
||||
interface BackendInterface
|
||||
{
|
||||
/**
|
||||
* Returns the list of addressbooks for a specific user.
|
||||
*
|
||||
|
|
@ -32,9 +34,10 @@ interface BackendInterface {
|
|||
* {http://calendarserver.org/ns/}getctag
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getAddressBooksForUser($principalUri);
|
||||
public function getAddressBooksForUser($principalUri);
|
||||
|
||||
/**
|
||||
* Updates properties for an address book.
|
||||
|
|
@ -48,11 +51,10 @@ interface BackendInterface {
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param string $addressBookId
|
||||
* @param string $addressBookId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch);
|
||||
public function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch);
|
||||
|
||||
/**
|
||||
* Creates a new address book.
|
||||
|
|
@ -61,19 +63,19 @@ interface BackendInterface {
|
|||
* in any format, including ints, strings, arrays or objects.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $url Just the 'basename' of the url.
|
||||
* @param array $properties
|
||||
* @param string $url just the 'basename' of the url
|
||||
* @param array $properties
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function createAddressBook($principalUri, $url, array $properties);
|
||||
public function createAddressBook($principalUri, $url, array $properties);
|
||||
|
||||
/**
|
||||
* Deletes an entire addressbook and all its contents
|
||||
* Deletes an entire addressbook and all its contents.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @return void
|
||||
*/
|
||||
function deleteAddressBook($addressBookId);
|
||||
public function deleteAddressBook($addressBookId);
|
||||
|
||||
/**
|
||||
* Returns all cards for a specific addressbook id.
|
||||
|
|
@ -92,9 +94,10 @@ interface BackendInterface {
|
|||
* This may speed up certain requests, especially with large cards.
|
||||
*
|
||||
* @param mixed $addressbookId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCards($addressbookId);
|
||||
public function getCards($addressbookId);
|
||||
|
||||
/**
|
||||
* Returns a specfic card.
|
||||
|
|
@ -104,11 +107,12 @@ interface BackendInterface {
|
|||
*
|
||||
* If the card does not exist, you must return false.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCard($addressBookId, $cardUri);
|
||||
public function getCard($addressBookId, $cardUri);
|
||||
|
||||
/**
|
||||
* Returns a list of cards.
|
||||
|
|
@ -120,9 +124,10 @@ interface BackendInterface {
|
|||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param array $uris
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleCards($addressBookId, array $uris);
|
||||
public function getMultipleCards($addressBookId, array $uris);
|
||||
|
||||
/**
|
||||
* Creates a new card.
|
||||
|
|
@ -144,12 +149,13 @@ interface BackendInterface {
|
|||
*
|
||||
* If you don't return an ETag, you can just return null.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createCard($addressBookId, $cardUri, $cardData);
|
||||
public function createCard($addressBookId, $cardUri, $cardData);
|
||||
|
||||
/**
|
||||
* Updates a card.
|
||||
|
|
@ -171,20 +177,21 @@ interface BackendInterface {
|
|||
*
|
||||
* If you don't return an ETag, you can just return null.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function updateCard($addressBookId, $cardUri, $cardData);
|
||||
public function updateCard($addressBookId, $cardUri, $cardData);
|
||||
|
||||
/**
|
||||
* Deletes a card
|
||||
* Deletes a card.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function deleteCard($addressBookId, $cardUri);
|
||||
|
||||
public function deleteCard($addressBookId, $cardUri);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Backend;
|
||||
|
||||
use Sabre\CardDAV;
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* PDO CardDAV backend
|
||||
* PDO CardDAV backend.
|
||||
*
|
||||
* This CardDAV backend uses PDO to store addressbooks
|
||||
*
|
||||
|
|
@ -14,22 +16,22 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class PDO extends AbstractBackend implements SyncSupport {
|
||||
|
||||
class PDO extends AbstractBackend implements SyncSupport
|
||||
{
|
||||
/**
|
||||
* PDO connection
|
||||
* PDO connection.
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* The PDO table name used to store addressbooks
|
||||
* The PDO table name used to store addressbooks.
|
||||
*/
|
||||
public $addressBooksTableName = 'addressbooks';
|
||||
|
||||
/**
|
||||
* The PDO table name used to store cards
|
||||
* The PDO table name used to store cards.
|
||||
*/
|
||||
public $cardsTableName = 'cards';
|
||||
|
||||
|
|
@ -41,48 +43,44 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
public $addressBookChangesTableName = 'addressbookchanges';
|
||||
|
||||
/**
|
||||
* Sets up the object
|
||||
* Sets up the object.
|
||||
*
|
||||
* @param \PDO $pdo
|
||||
*/
|
||||
function __construct(\PDO $pdo) {
|
||||
|
||||
public function __construct(\PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of addressbooks for a specific user.
|
||||
*
|
||||
* @param string $principalUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getAddressBooksForUser($principalUri) {
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, synctoken FROM ' . $this->addressBooksTableName . ' WHERE principaluri = ?');
|
||||
public function getAddressBooksForUser($principalUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, synctoken FROM '.$this->addressBooksTableName.' WHERE principaluri = ?');
|
||||
$stmt->execute([$principalUri]);
|
||||
|
||||
$addressBooks = [];
|
||||
|
||||
foreach ($stmt->fetchAll() as $row) {
|
||||
|
||||
$addressBooks[] = [
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'principaluri' => $row['principaluri'],
|
||||
'{DAV:}displayname' => $row['displayname'],
|
||||
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
|
||||
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'],
|
||||
'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
'principaluri' => $row['principaluri'],
|
||||
'{DAV:}displayname' => $row['displayname'],
|
||||
'{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => $row['description'],
|
||||
'{http://calendarserver.org/ns/}getctag' => $row['synctoken'],
|
||||
'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return $addressBooks;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates properties for an address book.
|
||||
*
|
||||
|
|
@ -95,32 +93,29 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* Read the PropPatch documentation for more info and examples.
|
||||
*
|
||||
* @param string $addressBookId
|
||||
* @param string $addressBookId
|
||||
* @param \Sabre\DAV\PropPatch $propPatch
|
||||
* @return void
|
||||
*/
|
||||
function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) {
|
||||
|
||||
public function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch)
|
||||
{
|
||||
$supportedProperties = [
|
||||
'{DAV:}displayname',
|
||||
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description',
|
||||
'{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description',
|
||||
];
|
||||
|
||||
$propPatch->handle($supportedProperties, function($mutations) use ($addressBookId) {
|
||||
|
||||
$propPatch->handle($supportedProperties, function ($mutations) use ($addressBookId) {
|
||||
$updates = [];
|
||||
foreach ($mutations as $property => $newValue) {
|
||||
|
||||
switch ($property) {
|
||||
case '{DAV:}displayname' :
|
||||
case '{DAV:}displayname':
|
||||
$updates['displayname'] = $newValue;
|
||||
break;
|
||||
case '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' :
|
||||
case '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description':
|
||||
$updates['description'] = $newValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$query = 'UPDATE ' . $this->addressBooksTableName . ' SET ';
|
||||
$query = 'UPDATE '.$this->addressBooksTableName.' SET ';
|
||||
$first = true;
|
||||
foreach ($updates as $key => $value) {
|
||||
if ($first) {
|
||||
|
|
@ -128,7 +123,7 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
} else {
|
||||
$query .= ', ';
|
||||
}
|
||||
$query .= ' ' . $key . ' = :' . $key . ' ';
|
||||
$query .= ' '.$key.' = :'.$key.' ';
|
||||
}
|
||||
$query .= ' WHERE id = :addressbookid';
|
||||
|
||||
|
|
@ -137,72 +132,67 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
|
||||
$stmt->execute($updates);
|
||||
|
||||
$this->addChange($addressBookId, "", 2);
|
||||
$this->addChange($addressBookId, '', 2);
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new address book
|
||||
* Creates a new address book.
|
||||
*
|
||||
* @param string $principalUri
|
||||
* @param string $url Just the 'basename' of the url.
|
||||
* @param array $properties
|
||||
* @param string $url just the 'basename' of the url
|
||||
* @param array $properties
|
||||
*
|
||||
* @return int Last insert id
|
||||
*/
|
||||
function createAddressBook($principalUri, $url, array $properties) {
|
||||
|
||||
public function createAddressBook($principalUri, $url, array $properties)
|
||||
{
|
||||
$values = [
|
||||
'displayname' => null,
|
||||
'description' => null,
|
||||
'displayname' => null,
|
||||
'description' => null,
|
||||
'principaluri' => $principalUri,
|
||||
'uri' => $url,
|
||||
'uri' => $url,
|
||||
];
|
||||
|
||||
foreach ($properties as $property => $newValue) {
|
||||
|
||||
switch ($property) {
|
||||
case '{DAV:}displayname' :
|
||||
case '{DAV:}displayname':
|
||||
$values['displayname'] = $newValue;
|
||||
break;
|
||||
case '{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' :
|
||||
case '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description':
|
||||
$values['description'] = $newValue;
|
||||
break;
|
||||
default :
|
||||
throw new DAV\Exception\BadRequest('Unknown property: ' . $property);
|
||||
default:
|
||||
throw new DAV\Exception\BadRequest('Unknown property: '.$property);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO ' . $this->addressBooksTableName . ' (uri, displayname, description, principaluri, synctoken) VALUES (:uri, :displayname, :description, :principaluri, 1)';
|
||||
$query = 'INSERT INTO '.$this->addressBooksTableName.' (uri, displayname, description, principaluri, synctoken) VALUES (:uri, :displayname, :description, :principaluri, 1)';
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
$stmt->execute($values);
|
||||
return $this->pdo->lastInsertId(
|
||||
$this->addressBooksTableName . '_id_seq'
|
||||
);
|
||||
|
||||
return $this->pdo->lastInsertId(
|
||||
$this->addressBooksTableName.'_id_seq'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an entire addressbook and all its contents
|
||||
* Deletes an entire addressbook and all its contents.
|
||||
*
|
||||
* @param int $addressBookId
|
||||
* @return void
|
||||
*/
|
||||
function deleteAddressBook($addressBookId) {
|
||||
|
||||
$stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
|
||||
public function deleteAddressBook($addressBookId)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('DELETE FROM '.$this->cardsTableName.' WHERE addressbookid = ?');
|
||||
$stmt->execute([$addressBookId]);
|
||||
|
||||
$stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
|
||||
$stmt = $this->pdo->prepare('DELETE FROM '.$this->addressBooksTableName.' WHERE id = ?');
|
||||
$stmt->execute([$addressBookId]);
|
||||
|
||||
$stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBookChangesTableName . ' WHERE addressbookid = ?');
|
||||
$stmt = $this->pdo->prepare('DELETE FROM '.$this->addressBookChangesTableName.' WHERE addressbookid = ?');
|
||||
$stmt->execute([$addressBookId]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -222,21 +212,22 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
* This may speed up certain requests, especially with large cards.
|
||||
*
|
||||
* @param mixed $addressbookId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCards($addressbookId) {
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, size FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
|
||||
public function getCards($addressbookId)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, size FROM '.$this->cardsTableName.' WHERE addressbookid = ?');
|
||||
$stmt->execute([$addressbookId]);
|
||||
|
||||
$result = [];
|
||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$row['etag'] = '"' . $row['etag'] . '"';
|
||||
$row['lastmodified'] = (int)$row['lastmodified'];
|
||||
$row['etag'] = '"'.$row['etag'].'"';
|
||||
$row['lastmodified'] = (int) $row['lastmodified'];
|
||||
$result[] = $row;
|
||||
}
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -247,23 +238,26 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* If the card does not exist, you must return false.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getCard($addressBookId, $cardUri) {
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified, etag, size FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ? LIMIT 1');
|
||||
public function getCard($addressBookId, $cardUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified, etag, size FROM '.$this->cardsTableName.' WHERE addressbookid = ? AND uri = ? LIMIT 1');
|
||||
$stmt->execute([$addressBookId, $cardUri]);
|
||||
|
||||
$result = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$result) return false;
|
||||
if (!$result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result['etag'] = '"'.$result['etag'].'"';
|
||||
$result['lastmodified'] = (int) $result['lastmodified'];
|
||||
|
||||
$result['etag'] = '"' . $result['etag'] . '"';
|
||||
$result['lastmodified'] = (int)$result['lastmodified'];
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -276,11 +270,12 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param array $uris
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getMultipleCards($addressBookId, array $uris) {
|
||||
|
||||
$query = 'SELECT id, uri, lastmodified, etag, size, carddata FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri IN (';
|
||||
public function getMultipleCards($addressBookId, array $uris)
|
||||
{
|
||||
$query = 'SELECT id, uri, lastmodified, etag, size, carddata FROM '.$this->cardsTableName.' WHERE addressbookid = ? AND uri IN (';
|
||||
// Inserting a whole bunch of question marks
|
||||
$query .= implode(',', array_fill(0, count($uris), '?'));
|
||||
$query .= ')';
|
||||
|
|
@ -289,12 +284,12 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
$stmt->execute(array_merge([$addressBookId], $uris));
|
||||
$result = [];
|
||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$row['etag'] = '"' . $row['etag'] . '"';
|
||||
$row['lastmodified'] = (int)$row['lastmodified'];
|
||||
$row['etag'] = '"'.$row['etag'].'"';
|
||||
$row['lastmodified'] = (int) $row['lastmodified'];
|
||||
$result[] = $row;
|
||||
}
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -317,14 +312,15 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* If you don't return an ETag, you can just return null.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function createCard($addressBookId, $cardUri, $cardData) {
|
||||
|
||||
$stmt = $this->pdo->prepare('INSERT INTO ' . $this->cardsTableName . ' (carddata, uri, lastmodified, addressbookid, size, etag) VALUES (?, ?, ?, ?, ?, ?)');
|
||||
public function createCard($addressBookId, $cardUri, $cardData)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('INSERT INTO '.$this->cardsTableName.' (carddata, uri, lastmodified, addressbookid, size, etag) VALUES (?, ?, ?, ?, ?, ?)');
|
||||
|
||||
$etag = md5($cardData);
|
||||
|
||||
|
|
@ -339,8 +335,7 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
|
||||
$this->addChange($addressBookId, $cardUri, 1);
|
||||
|
||||
return '"' . $etag . '"';
|
||||
|
||||
return '"'.$etag.'"';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -363,14 +358,15 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* If you don't return an ETag, you can just return null.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function updateCard($addressBookId, $cardUri, $cardData) {
|
||||
|
||||
$stmt = $this->pdo->prepare('UPDATE ' . $this->cardsTableName . ' SET carddata = ?, lastmodified = ?, size = ?, etag = ? WHERE uri = ? AND addressbookid =?');
|
||||
public function updateCard($addressBookId, $cardUri, $cardData)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('UPDATE '.$this->cardsTableName.' SET carddata = ?, lastmodified = ?, size = ?, etag = ? WHERE uri = ? AND addressbookid =?');
|
||||
|
||||
$etag = md5($cardData);
|
||||
$stmt->execute([
|
||||
|
|
@ -379,31 +375,30 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
strlen($cardData),
|
||||
$etag,
|
||||
$cardUri,
|
||||
$addressBookId
|
||||
$addressBookId,
|
||||
]);
|
||||
|
||||
$this->addChange($addressBookId, $cardUri, 2);
|
||||
|
||||
return '"' . $etag . '"';
|
||||
|
||||
return '"'.$etag.'"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a card
|
||||
* Deletes a card.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function deleteCard($addressBookId, $cardUri) {
|
||||
|
||||
$stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ?');
|
||||
public function deleteCard($addressBookId, $cardUri)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('DELETE FROM '.$this->cardsTableName.' WHERE addressbookid = ? AND uri = ?');
|
||||
$stmt->execute([$addressBookId, $cardUri]);
|
||||
|
||||
$this->addChange($addressBookId, $cardUri, 3);
|
||||
|
||||
return $stmt->rowCount() === 1;
|
||||
|
||||
return 1 === $stmt->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -458,30 +453,34 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
*
|
||||
* @param string $addressBookId
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null) {
|
||||
|
||||
public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null)
|
||||
{
|
||||
// Current synctoken
|
||||
$stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
|
||||
$stmt = $this->pdo->prepare('SELECT synctoken FROM '.$this->addressBooksTableName.' WHERE id = ?');
|
||||
$stmt->execute([$addressBookId]);
|
||||
$currentToken = $stmt->fetchColumn(0);
|
||||
|
||||
if (is_null($currentToken)) return null;
|
||||
if (is_null($currentToken)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = [
|
||||
'syncToken' => $currentToken,
|
||||
'added' => [],
|
||||
'modified' => [],
|
||||
'deleted' => [],
|
||||
'added' => [],
|
||||
'modified' => [],
|
||||
'deleted' => [],
|
||||
];
|
||||
|
||||
if ($syncToken) {
|
||||
|
||||
$query = "SELECT uri, operation FROM " . $this->addressBookChangesTableName . " WHERE synctoken >= ? AND synctoken < ? AND addressbookid = ? ORDER BY synctoken";
|
||||
if ($limit > 0) $query .= " LIMIT " . (int)$limit;
|
||||
$query = 'SELECT uri, operation FROM '.$this->addressBookChangesTableName.' WHERE synctoken >= ? AND synctoken < ? AND addressbookid = ? ORDER BY synctoken';
|
||||
if ($limit > 0) {
|
||||
$query .= ' LIMIT '.(int) $limit;
|
||||
}
|
||||
|
||||
// Fetching all changes
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
|
|
@ -492,13 +491,10 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
// This loop ensures that any duplicates are overwritten, only the
|
||||
// last change on a node is relevant.
|
||||
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
|
||||
$changes[$row['uri']] = $row['operation'];
|
||||
|
||||
}
|
||||
|
||||
foreach ($changes as $uri => $operation) {
|
||||
|
||||
switch ($operation) {
|
||||
case 1:
|
||||
$result['added'][] = $uri;
|
||||
|
|
@ -510,41 +506,38 @@ class PDO extends AbstractBackend implements SyncSupport {
|
|||
$result['deleted'][] = $uri;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// No synctoken supplied, this is the initial sync.
|
||||
$query = "SELECT uri FROM " . $this->cardsTableName . " WHERE addressbookid = ?";
|
||||
$query = 'SELECT uri FROM '.$this->cardsTableName.' WHERE addressbookid = ?';
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
$stmt->execute([$addressBookId]);
|
||||
|
||||
$result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
}
|
||||
return $result;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a change record to the addressbookchanges table.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param mixed $addressBookId
|
||||
* @param string $objectUri
|
||||
* @param int $operation 1 = add, 2 = modify, 3 = delete
|
||||
* @return void
|
||||
* @param int $operation 1 = add, 2 = modify, 3 = delete
|
||||
*/
|
||||
protected function addChange($addressBookId, $objectUri, $operation) {
|
||||
|
||||
$stmt = $this->pdo->prepare('INSERT INTO ' . $this->addressBookChangesTableName . ' (uri, synctoken, addressbookid, operation) SELECT ?, synctoken, ?, ? FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
|
||||
protected function addChange($addressBookId, $objectUri, $operation)
|
||||
{
|
||||
$stmt = $this->pdo->prepare('INSERT INTO '.$this->addressBookChangesTableName.' (uri, synctoken, addressbookid, operation) SELECT ?, synctoken, ?, ? FROM '.$this->addressBooksTableName.' WHERE id = ?');
|
||||
$stmt->execute([
|
||||
$objectUri,
|
||||
$addressBookId,
|
||||
$operation,
|
||||
$addressBookId
|
||||
$addressBookId,
|
||||
]);
|
||||
$stmt = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET synctoken = synctoken + 1 WHERE id = ?');
|
||||
$stmt = $this->pdo->prepare('UPDATE '.$this->addressBooksTableName.' SET synctoken = synctoken + 1 WHERE id = ?');
|
||||
$stmt->execute([
|
||||
$addressBookId
|
||||
$addressBookId,
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Backend;
|
||||
|
||||
/**
|
||||
|
|
@ -18,8 +20,8 @@ namespace Sabre\CardDAV\Backend;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface SyncSupport extends BackendInterface {
|
||||
|
||||
interface SyncSupport extends BackendInterface
|
||||
{
|
||||
/**
|
||||
* The getChanges method returns all the changes that have happened, since
|
||||
* the specified syncToken in the specified address book.
|
||||
|
|
@ -72,10 +74,10 @@ interface SyncSupport extends BackendInterface {
|
|||
*
|
||||
* @param string $addressBookId
|
||||
* @param string $syncToken
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
* @param int $syncLevel
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null);
|
||||
|
||||
public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,94 +1,96 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
use Sabre\DAVACL;
|
||||
|
||||
/**
|
||||
* The Card object represents a single Card from an addressbook
|
||||
* The Card object represents a single Card from an addressbook.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Card extends DAV\File implements ICard, DAVACL\IACL {
|
||||
|
||||
class Card extends DAV\File implements ICard, DAVACL\IACL
|
||||
{
|
||||
use DAVACL\ACLTrait;
|
||||
|
||||
/**
|
||||
* CardDAV backend
|
||||
* CardDAV backend.
|
||||
*
|
||||
* @var Backend\BackendInterface
|
||||
*/
|
||||
protected $carddavBackend;
|
||||
|
||||
/**
|
||||
* Array with information about this Card
|
||||
* Array with information about this Card.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $cardData;
|
||||
|
||||
/**
|
||||
* Array with information about the containing addressbook
|
||||
* Array with information about the containing addressbook.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $addressBookInfo;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param Backend\BackendInterface $carddavBackend
|
||||
* @param array $addressBookInfo
|
||||
* @param array $cardData
|
||||
* @param array $addressBookInfo
|
||||
* @param array $cardData
|
||||
*/
|
||||
function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo, array $cardData) {
|
||||
|
||||
public function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo, array $cardData)
|
||||
{
|
||||
$this->carddavBackend = $carddavBackend;
|
||||
$this->addressBookInfo = $addressBookInfo;
|
||||
$this->cardData = $cardData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uri for this object
|
||||
* Returns the uri for this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->cardData['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the VCard-formatted object
|
||||
* Returns the VCard-formatted object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get() {
|
||||
|
||||
public function get()
|
||||
{
|
||||
// Pre-populating 'carddata' is optional. If we don't yet have it
|
||||
// already, we fetch it from the backend.
|
||||
if (!isset($this->cardData['carddata'])) {
|
||||
$this->cardData = $this->carddavBackend->getCard($this->addressBookInfo['id'], $this->cardData['uri']);
|
||||
}
|
||||
return $this->cardData['carddata'];
|
||||
|
||||
return $this->cardData['carddata'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the VCard-formatted object
|
||||
* Updates the VCard-formatted object.
|
||||
*
|
||||
* @param string $cardData
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function put($cardData) {
|
||||
|
||||
if (is_resource($cardData))
|
||||
public function put($cardData)
|
||||
{
|
||||
if (is_resource($cardData)) {
|
||||
$cardData = stream_get_contents($cardData);
|
||||
}
|
||||
|
||||
// Converting to UTF-8, if needed
|
||||
$cardData = DAV\StringUtil::ensureUTF8($cardData);
|
||||
|
|
@ -98,92 +100,82 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
|
|||
$this->cardData['etag'] = $etag;
|
||||
|
||||
return $etag;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the card
|
||||
*
|
||||
* @return void
|
||||
* Deletes the card.
|
||||
*/
|
||||
function delete() {
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$this->carddavBackend->deleteCard($this->addressBookInfo['id'], $this->cardData['uri']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime content-type
|
||||
* Returns the mime content-type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getContentType() {
|
||||
|
||||
public function getContentType()
|
||||
{
|
||||
return 'text/vcard; charset=utf-8';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ETag for this object
|
||||
* Returns an ETag for this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getETag() {
|
||||
|
||||
public function getETag()
|
||||
{
|
||||
if (isset($this->cardData['etag'])) {
|
||||
return $this->cardData['etag'];
|
||||
} else {
|
||||
$data = $this->get();
|
||||
if (is_string($data)) {
|
||||
return '"' . md5($data) . '"';
|
||||
return '"'.md5($data).'"';
|
||||
} else {
|
||||
// We refuse to calculate the md5 if it's a stream.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last modification date as a unix timestamp
|
||||
* Returns the last modification date as a unix timestamp.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getLastModified() {
|
||||
|
||||
public function getLastModified()
|
||||
{
|
||||
return isset($this->cardData['lastmodified']) ? $this->cardData['lastmodified'] : null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this object in bytes
|
||||
* Returns the size of this object in bytes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function getSize() {
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
if (array_key_exists('size', $this->cardData)) {
|
||||
return $this->cardData['size'];
|
||||
} else {
|
||||
return strlen($this->get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
* Returns the owner principal.
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner() {
|
||||
|
||||
public function getOwner()
|
||||
{
|
||||
return $this->addressBookInfo['principaluri'];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of ACE's for this node.
|
||||
*
|
||||
|
|
@ -196,8 +188,8 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getACL() {
|
||||
|
||||
public function getACL()
|
||||
{
|
||||
// An alternative acl may be specified through the cardData array.
|
||||
if (isset($this->cardData['acl'])) {
|
||||
return $this->cardData['acl'];
|
||||
|
|
@ -210,7 +202,5 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
|
|||
'protected' => true,
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* AddressBook interface
|
||||
* AddressBook interface.
|
||||
*
|
||||
* Implement this interface to allow a node to be recognized as an addressbook.
|
||||
*
|
||||
|
|
@ -13,6 +15,6 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IAddressBook extends DAV\ICollection {
|
||||
|
||||
interface IAddressBook extends DAV\ICollection
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* Card interface
|
||||
* Card interface.
|
||||
*
|
||||
* Extend the ICard interface to allow your custom nodes to be picked up as
|
||||
* 'Cards'.
|
||||
|
|
@ -14,6 +16,6 @@ use Sabre\DAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface ICard extends DAV\IFile {
|
||||
|
||||
interface ICard extends DAV\IFile
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
/**
|
||||
* IDirectory interface
|
||||
* IDirectory interface.
|
||||
*
|
||||
* Implement this interface to have an addressbook marked as a 'directory'. A
|
||||
* directory is an (often) global addressbook.
|
||||
|
|
@ -15,6 +17,6 @@ namespace Sabre\CardDAV;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
interface IDirectory extends IAddressBook {
|
||||
|
||||
interface IDirectory extends IAddressBook
|
||||
{
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
|
@ -8,7 +10,7 @@ use Sabre\HTTP\ResponseInterface;
|
|||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* VCF Exporter
|
||||
* VCF Exporter.
|
||||
*
|
||||
* This plugin adds the ability to export entire address books as .vcf files.
|
||||
* This is useful for clients that don't support CardDAV yet. They often do
|
||||
|
|
@ -19,28 +21,27 @@ use Sabre\VObject;
|
|||
* @author Thomas Tanghus (http://tanghus.net/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class VCFExportPlugin extends DAV\ServerPlugin {
|
||||
|
||||
class VCFExportPlugin extends DAV\ServerPlugin
|
||||
{
|
||||
/**
|
||||
* Reference to Server class
|
||||
* Reference to Server class.
|
||||
*
|
||||
* @var DAV\Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Initializes the plugin and registers event handlers
|
||||
* Initializes the plugin and registers event handlers.
|
||||
*
|
||||
* @param DAV\Server $server
|
||||
* @return void
|
||||
*/
|
||||
function initialize(DAV\Server $server) {
|
||||
|
||||
public function initialize(DAV\Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$this->server->on('method:GET', [$this, 'httpGet'], 90);
|
||||
$server->on('browserButtonActions', function($path, $node, &$actions) {
|
||||
$server->on('browserButtonActions', function ($path, $node, &$actions) {
|
||||
if ($node instanceof IAddressBook) {
|
||||
$actions .= '<a href="' . htmlspecialchars($path, ENT_QUOTES, 'UTF-8') . '?export"><span class="oi" data-glyph="book"></span></a>';
|
||||
$actions .= '<a href="'.htmlspecialchars($path, ENT_QUOTES, 'UTF-8').'?export"><span class="oi" data-glyph="book"></span></a>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -48,20 +49,25 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
/**
|
||||
* Intercepts GET requests on addressbook urls ending with ?export.
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param RequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function httpGet(RequestInterface $request, ResponseInterface $response) {
|
||||
|
||||
public function httpGet(RequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$queryParams = $request->getQueryParameters();
|
||||
if (!array_key_exists('export', $queryParams)) return;
|
||||
if (!array_key_exists('export', $queryParams)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $request->getPath();
|
||||
|
||||
$node = $this->server->tree->getNodeForPath($path);
|
||||
|
||||
if (!($node instanceof IAddressBook)) return;
|
||||
if (!($node instanceof IAddressBook)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->server->transactionType = 'get-addressbook-export';
|
||||
|
||||
|
|
@ -71,7 +77,7 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
}
|
||||
|
||||
$nodes = $this->server->getPropertiesForPath($path, [
|
||||
'{' . Plugin::NS_CARDDAV . '}address-data',
|
||||
'{'.Plugin::NS_CARDDAV.'}address-data',
|
||||
], 1);
|
||||
|
||||
$format = 'text/directory';
|
||||
|
|
@ -91,9 +97,9 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
'',
|
||||
$node->getName()
|
||||
);
|
||||
$filename .= '-' . date('Y-m-d') . $filenameExtension;
|
||||
$filename .= '-'.date('Y-m-d').$filenameExtension;
|
||||
|
||||
$response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
|
||||
$response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"');
|
||||
$response->setHeader('Content-Type', $format);
|
||||
|
||||
$response->setStatus(200);
|
||||
|
|
@ -101,25 +107,24 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
|
||||
// Returning false to break the event chain
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges all vcard objects, and builds one big vcf export
|
||||
* Merges all vcard objects, and builds one big vcf export.
|
||||
*
|
||||
* @param array $nodes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function generateVCF(array $nodes) {
|
||||
|
||||
$output = "";
|
||||
public function generateVCF(array $nodes)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
|
||||
if (!isset($node[200]['{' . Plugin::NS_CARDDAV . '}address-data'])) {
|
||||
if (!isset($node[200]['{'.Plugin::NS_CARDDAV.'}address-data'])) {
|
||||
continue;
|
||||
}
|
||||
$nodeData = $node[200]['{' . Plugin::NS_CARDDAV . '}address-data'];
|
||||
$nodeData = $node[200]['{'.Plugin::NS_CARDDAV.'}address-data'];
|
||||
|
||||
// Parsing this node so VObject can clean up the output.
|
||||
$vcard = VObject\Reader::read($nodeData);
|
||||
|
|
@ -127,11 +132,9 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
|
||||
// Destroy circular references to PHP will GC the object.
|
||||
$vcard->destroy();
|
||||
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -142,10 +145,9 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPluginName() {
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'vcf-export';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,14 +161,12 @@ class VCFExportPlugin extends DAV\ServerPlugin {
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
function getPluginInfo() {
|
||||
|
||||
public function getPluginInfo()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getPluginName(),
|
||||
'name' => $this->getPluginName(),
|
||||
'description' => 'Adds the ability to export CardDAV addressbooks as a single vCard file.',
|
||||
'link' => 'http://sabre.io/dav/vcf-export-plugin/',
|
||||
'link' => 'http://sabre.io/dav/vcf-export-plugin/',
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Xml\Filter;
|
||||
|
||||
use Sabre\Xml\Reader;
|
||||
|
|
@ -21,8 +23,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class AddressData implements XmlDeserializable {
|
||||
|
||||
class AddressData implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -42,22 +44,25 @@ class AddressData implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'contentType' => $reader->getAttribute('content-type') ?: 'text/vcard',
|
||||
'version' => $reader->getAttribute('version') ?: '3.0',
|
||||
'version' => $reader->getAttribute('version') ?: '3.0',
|
||||
];
|
||||
|
||||
$elems = (array)$reader->parseInnerTree();
|
||||
$result['addressDataProperties'] = array_map(function($element) {
|
||||
$elems = (array) $reader->parseInnerTree();
|
||||
$elems = array_filter($elems, function ($element) {
|
||||
return '{urn:ietf:params:xml:ns:carddav}prop' === $element['name'] &&
|
||||
isset($element['attributes']['name']);
|
||||
});
|
||||
$result['addressDataProperties'] = array_map(function ($element) {
|
||||
return $element['attributes']['name'];
|
||||
}, $elems);
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CardDAV\Plugin;
|
||||
|
|
@ -21,8 +23,8 @@ use Sabre\Xml\Reader;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
abstract class ParamFilter implements Element {
|
||||
|
||||
abstract class ParamFilter implements Element
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -42,14 +44,15 @@ abstract class ParamFilter implements Element {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'name' => null,
|
||||
'name' => null,
|
||||
'is-not-defined' => false,
|
||||
'text-match' => null,
|
||||
'text-match' => null,
|
||||
];
|
||||
|
||||
$att = $reader->parseAttributes();
|
||||
|
|
@ -57,33 +60,29 @@ abstract class ParamFilter implements Element {
|
|||
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
if (is_array($elems)) foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CARDDAV . '}is-not-defined' :
|
||||
if (is_array($elems)) {
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
case '{'.Plugin::NS_CARDDAV.'}is-not-defined':
|
||||
$result['is-not-defined'] = true;
|
||||
break;
|
||||
case '{' . Plugin::NS_CARDDAV . '}text-match' :
|
||||
case '{'.Plugin::NS_CARDDAV.'}text-match':
|
||||
$matchType = isset($elem['attributes']['match-type']) ? $elem['attributes']['match-type'] : 'contains';
|
||||
|
||||
if (!in_array($matchType, ['contains', 'equals', 'starts-with', 'ends-with'])) {
|
||||
throw new BadRequest('Unknown match-type: ' . $matchType);
|
||||
throw new BadRequest('Unknown match-type: '.$matchType);
|
||||
}
|
||||
$result['text-match'] = [
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes',
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap',
|
||||
'value' => $elem['value'],
|
||||
'match-type' => $matchType,
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'],
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap',
|
||||
'value' => $elem['value'],
|
||||
'match-type' => $matchType,
|
||||
];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Xml\Filter;
|
||||
|
||||
use Sabre\CardDAV\Plugin;
|
||||
|
|
@ -21,8 +23,8 @@ use Sabre\Xml\XmlDeserializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class PropFilter implements XmlDeserializable {
|
||||
|
||||
class PropFilter implements XmlDeserializable
|
||||
{
|
||||
/**
|
||||
* The deserialize method is called during xml parsing.
|
||||
*
|
||||
|
|
@ -42,57 +44,54 @@ class PropFilter implements XmlDeserializable {
|
|||
* the next element.
|
||||
*
|
||||
* @param Reader $reader
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static function xmlDeserialize(Reader $reader) {
|
||||
|
||||
public static function xmlDeserialize(Reader $reader)
|
||||
{
|
||||
$result = [
|
||||
'name' => null,
|
||||
'test' => 'anyof',
|
||||
'name' => null,
|
||||
'test' => 'anyof',
|
||||
'is-not-defined' => false,
|
||||
'param-filters' => [],
|
||||
'text-matches' => [],
|
||||
'param-filters' => [],
|
||||
'text-matches' => [],
|
||||
];
|
||||
|
||||
$att = $reader->parseAttributes();
|
||||
$result['name'] = $att['name'];
|
||||
|
||||
if (isset($att['test']) && $att['test'] === 'allof') {
|
||||
if (isset($att['test']) && 'allof' === $att['test']) {
|
||||
$result['test'] = 'allof';
|
||||
}
|
||||
|
||||
$elems = $reader->parseInnerTree();
|
||||
|
||||
if (is_array($elems)) foreach ($elems as $elem) {
|
||||
|
||||
switch ($elem['name']) {
|
||||
|
||||
case '{' . Plugin::NS_CARDDAV . '}param-filter' :
|
||||
if (is_array($elems)) {
|
||||
foreach ($elems as $elem) {
|
||||
switch ($elem['name']) {
|
||||
case '{'.Plugin::NS_CARDDAV.'}param-filter':
|
||||
$result['param-filters'][] = $elem['value'];
|
||||
break;
|
||||
case '{' . Plugin::NS_CARDDAV . '}is-not-defined' :
|
||||
case '{'.Plugin::NS_CARDDAV.'}is-not-defined':
|
||||
$result['is-not-defined'] = true;
|
||||
break;
|
||||
case '{' . Plugin::NS_CARDDAV . '}text-match' :
|
||||
case '{'.Plugin::NS_CARDDAV.'}text-match':
|
||||
$matchType = isset($elem['attributes']['match-type']) ? $elem['attributes']['match-type'] : 'contains';
|
||||
|
||||
if (!in_array($matchType, ['contains', 'equals', 'starts-with', 'ends-with'])) {
|
||||
throw new BadRequest('Unknown match-type: ' . $matchType);
|
||||
throw new BadRequest('Unknown match-type: '.$matchType);
|
||||
}
|
||||
$result['text-matches'][] = [
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes',
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap',
|
||||
'value' => $elem['value'],
|
||||
'match-type' => $matchType,
|
||||
'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'],
|
||||
'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap',
|
||||
'value' => $elem['value'],
|
||||
'match-type' => $matchType,
|
||||
];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sabre\CardDAV\Xml\Property;
|
||||
|
||||
use Sabre\CardDAV\Plugin;
|
||||
|
|
@ -7,7 +9,7 @@ use Sabre\Xml\Writer;
|
|||
use Sabre\Xml\XmlSerializable;
|
||||
|
||||
/**
|
||||
* Supported-address-data property
|
||||
* Supported-address-data property.
|
||||
*
|
||||
* This property is a representation of the supported-address-data property
|
||||
* in the CardDAV namespace.
|
||||
|
|
@ -20,22 +22,22 @@ use Sabre\Xml\XmlSerializable;
|
|||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class SupportedAddressData implements XmlSerializable {
|
||||
|
||||
class SupportedAddressData implements XmlSerializable
|
||||
{
|
||||
/**
|
||||
* supported versions
|
||||
* supported versions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $supportedData = [];
|
||||
|
||||
/**
|
||||
* Creates the property
|
||||
* Creates the property.
|
||||
*
|
||||
* @param array|null $supportedData
|
||||
*/
|
||||
function __construct(array $supportedData = null) {
|
||||
|
||||
public function __construct(array $supportedData = null)
|
||||
{
|
||||
if (is_null($supportedData)) {
|
||||
$supportedData = [
|
||||
['contentType' => 'text/vcard', 'version' => '3.0'],
|
||||
|
|
@ -45,7 +47,6 @@ class SupportedAddressData implements XmlSerializable {
|
|||
}
|
||||
|
||||
$this->supportedData = $supportedData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -65,19 +66,16 @@ class SupportedAddressData implements XmlSerializable {
|
|||
* If you are opening new elements, you must also close them again.
|
||||
*
|
||||
* @param Writer $writer
|
||||
* @return void
|
||||
*/
|
||||
function xmlSerialize(Writer $writer) {
|
||||
|
||||
public function xmlSerialize(Writer $writer)
|
||||
{
|
||||
foreach ($this->supportedData as $supported) {
|
||||
$writer->startElement('{' . Plugin::NS_CARDDAV . '}address-data-type');
|
||||
$writer->startElement('{'.Plugin::NS_CARDDAV.'}address-data-type');
|
||||
$writer->writeAttributes([
|
||||
'content-type' => $supported['contentType'],
|
||||
'version' => $supported['version']
|
||||
'version' => $supported['version'],
|
||||
]);
|
||||
$writer->endElement(); // address-data-type
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue