aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/lib/DAVACL/Xml
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/lib/DAVACL/Xml')
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php277
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php45
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php159
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php196
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php159
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php103
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php127
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php58
8 files changed, 1124 insertions, 0 deletions
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php
new file mode 100644
index 000000000..9f5e40df1
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php
@@ -0,0 +1,277 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Property;
+
+use Sabre\DAV;
+use Sabre\DAV\Browser\HtmlOutput;
+use Sabre\DAV\Browser\HtmlOutputHelper;
+use Sabre\Xml\Element;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * This class represents the {DAV:}acl property.
+ *
+ * The {DAV:}acl property is a full list of access control entries for a
+ * resource.
+ *
+ * {DAV:}acl is used as a WebDAV property, but it is also used within the body
+ * of the ACL request.
+ *
+ * See:
+ * http://tools.ietf.org/html/rfc3744#section-5.5
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Acl implements Element, HtmlOutput {
+
+ /**
+ * List of privileges
+ *
+ * @var array
+ */
+ protected $privileges;
+
+ /**
+ * Whether or not the server base url is required to be prefixed when
+ * serializing the property.
+ *
+ * @var bool
+ */
+ protected $prefixBaseUrl;
+
+ /**
+ * Constructor
+ *
+ * This object requires a structure similar to the return value from
+ * Sabre\DAVACL\Plugin::getACL().
+ *
+ * Each privilege is a an array with at least a 'privilege' property, and a
+ * 'principal' property. A privilege may have a 'protected' property as
+ * well.
+ *
+ * The prefixBaseUrl should be set to false, if the supplied principal urls
+ * are already full urls. If this is kept to true, the servers base url
+ * will automatically be prefixed.
+ *
+ * @param array $privileges
+ * @param bool $prefixBaseUrl
+ */
+ function __construct(array $privileges, $prefixBaseUrl = true) {
+
+ $this->privileges = $privileges;
+ $this->prefixBaseUrl = $prefixBaseUrl;
+
+ }
+
+ /**
+ * Returns the list of privileges for this property
+ *
+ * @return array
+ */
+ function getPrivileges() {
+
+ return $this->privileges;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ foreach ($this->privileges as $ace) {
+
+ $this->serializeAce($writer, $ace);
+
+ }
+
+ }
+
+ /**
+ * Generate html representation for this value.
+ *
+ * The html output is 100% trusted, and no effort is being made to sanitize
+ * it. It's up to the implementor to sanitize user provided values.
+ *
+ * The output must be in UTF-8.
+ *
+ * The baseUri parameter is a url to the root of the application, and can
+ * be used to construct local links.
+ *
+ * @param HtmlOutputHelper $html
+ * @return string
+ */
+ function toHtml(HtmlOutputHelper $html) {
+
+ ob_start();
+ echo "<table>";
+ echo "<tr><th>Principal</th><th>Privilege</th><th></th></tr>";
+ foreach ($this->privileges as $privilege) {
+
+ echo '<tr>';
+ // if it starts with a {, it's a special principal
+ if ($privilege['principal'][0] === '{') {
+ echo '<td>', $html->xmlName($privilege['principal']), '</td>';
+ } else {
+ echo '<td>', $html->link($privilege['principal']), '</td>';
+ }
+ echo '<td>', $html->xmlName($privilege['privilege']), '</td>';
+ echo '<td>';
+ if (!empty($privilege['protected'])) echo '(protected)';
+ echo '</td>';
+ echo '</tr>';
+
+ }
+ echo "</table>";
+ return ob_get_clean();
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * Important note 2: You are responsible for advancing the reader to the
+ * next element. Not doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $elementMap = [
+ '{DAV:}ace' => 'Sabre\Xml\Element\KeyValue',
+ '{DAV:}privilege' => 'Sabre\Xml\Element\Elements',
+ '{DAV:}principal' => 'Sabre\DAVACL\Xml\Property\Principal',
+ ];
+
+ $privileges = [];
+
+ foreach ((array)$reader->parseInnerTree($elementMap) as $element) {
+
+ if ($element['name'] !== '{DAV:}ace') {
+ continue;
+ }
+ $ace = $element['value'];
+
+ if (empty($ace['{DAV:}principal'])) {
+ throw new DAV\Exception\BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
+ }
+ $principal = $ace['{DAV:}principal'];
+
+ switch ($principal->getType()) {
+ case Principal::HREF :
+ $principal = $principal->getHref();
+ break;
+ case Principal::AUTHENTICATED :
+ $principal = '{DAV:}authenticated';
+ break;
+ case Principal::UNAUTHENTICATED :
+ $principal = '{DAV:}unauthenticated';
+ break;
+ case Principal::ALL :
+ $principal = '{DAV:}all';
+ break;
+
+ }
+
+ $protected = array_key_exists('{DAV:}protected', $ace);
+
+ if (!isset($ace['{DAV:}grant'])) {
+ throw new DAV\Exception\NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
+ }
+ foreach ($ace['{DAV:}grant'] as $elem) {
+ if ($elem['name'] !== '{DAV:}privilege') {
+ continue;
+ }
+
+ foreach ($elem['value'] as $priv) {
+ $privileges[] = [
+ 'principal' => $principal,
+ 'protected' => $protected,
+ 'privilege' => $priv,
+ ];
+ }
+
+ }
+
+ }
+
+ return new self($privileges);
+
+ }
+
+ /**
+ * Serializes a single access control entry.
+ *
+ * @param Writer $writer
+ * @param array $ace
+ * @return void
+ */
+ private function serializeAce(Writer $writer, array $ace) {
+
+ $writer->startElement('{DAV:}ace');
+
+ switch ($ace['principal']) {
+ case '{DAV:}authenticated' :
+ $principal = new Principal(Principal::AUTHENTICATED);
+ break;
+ case '{DAV:}unauthenticated' :
+ $principal = new Principal(Principal::UNAUTHENTICATED);
+ break;
+ case '{DAV:}all' :
+ $principal = new Principal(Principal::ALL);
+ break;
+ default:
+ $principal = new Principal(Principal::HREF, $ace['principal']);
+ break;
+ }
+
+ $writer->writeElement('{DAV:}principal', $principal);
+ $writer->startElement('{DAV:}grant');
+ $writer->startElement('{DAV:}privilege');
+
+ $writer->writeElement($ace['privilege']);
+
+ $writer->endElement(); // privilege
+ $writer->endElement(); // grant
+
+ if (!empty($ace['protected'])) {
+ $writer->writeElement('{DAV:}protected');
+ }
+
+ $writer->endElement(); // ace
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php
new file mode 100644
index 000000000..f669cc5e1
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Property;
+
+use Sabre\Xml\XmlSerializable;
+use Sabre\Xml\Writer;
+
+/**
+ * AclRestrictions property
+ *
+ * This property represents {DAV:}acl-restrictions, as defined in RFC3744.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class AclRestrictions implements XmlSerializable {
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ $writer->writeElement('{DAV:}grant-only');
+ $writer->writeElement('{DAV:}no-invert');
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php
new file mode 100644
index 000000000..0a95eb2b7
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Property;
+
+use Sabre\DAV\Browser\HtmlOutput;
+use Sabre\DAV\Browser\HtmlOutputHelper;
+use Sabre\Xml\Element;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * CurrentUserPrivilegeSet
+ *
+ * This class represents the current-user-privilege-set property. When
+ * requested, it contain all the privileges a user has on a specific node.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class CurrentUserPrivilegeSet implements Element, HtmlOutput {
+
+ /**
+ * List of privileges
+ *
+ * @var array
+ */
+ private $privileges;
+
+ /**
+ * Creates the object
+ *
+ * Pass the privileges in clark-notation
+ *
+ * @param array $privileges
+ */
+ function __construct(array $privileges) {
+
+ $this->privileges = $privileges;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ foreach ($this->privileges as $privName) {
+
+ $writer->startElement('{DAV:}privilege');
+ $writer->writeElement($privName);
+ $writer->endElement();
+
+ }
+
+
+ }
+
+ /**
+ * Returns true or false, whether the specified principal appears in the
+ * list.
+ *
+ * @param string $privilegeName
+ * @return bool
+ */
+ function has($privilegeName) {
+
+ return in_array($privilegeName, $this->privileges);
+
+ }
+
+ /**
+ * Returns the list of privileges.
+ *
+ * @return array
+ */
+ function getValue() {
+
+ return $this->privileges;
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $result = [];
+
+ $tree = $reader->parseInnerTree(['{DAV:}privilege' => 'Sabre\\Xml\\Element\\Elements']);
+ foreach ($tree as $element) {
+ if ($element['name'] !== '{DAV:}privilege') {
+ continue;
+ }
+ $result[] = $element['value'][0];
+ }
+ return new self($result);
+
+ }
+
+ /**
+ * Generate html representation for this value.
+ *
+ * The html output is 100% trusted, and no effort is being made to sanitize
+ * it. It's up to the implementor to sanitize user provided values.
+ *
+ * The output must be in UTF-8.
+ *
+ * The baseUri parameter is a url to the root of the application, and can
+ * be used to construct local links.
+ *
+ * @param HtmlOutputHelper $html
+ * @return string
+ */
+ function toHtml(HtmlOutputHelper $html) {
+
+ return implode(
+ ', ',
+ array_map([$html, 'xmlName'], $this->getValue())
+ );
+
+ }
+
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php
new file mode 100644
index 000000000..d32249d8b
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php
@@ -0,0 +1,196 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Property;
+
+use Sabre\DAV;
+use Sabre\DAV\Browser\HtmlOutputHelper;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * Principal property
+ *
+ * The principal property represents a principal from RFC3744 (ACL).
+ * The property can be used to specify a principal or pseudo principals.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Principal extends DAV\Xml\Property\Href {
+
+ /**
+ * To specify a not-logged-in user, use the UNAUTHENTICATED principal
+ */
+ const UNAUTHENTICATED = 1;
+
+ /**
+ * To specify any principal that is logged in, use AUTHENTICATED
+ */
+ const AUTHENTICATED = 2;
+
+ /**
+ * Specific principals can be specified with the HREF
+ */
+ const HREF = 3;
+
+ /**
+ * Everybody, basically
+ */
+ const ALL = 4;
+
+ /**
+ * Principal-type
+ *
+ * Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
+ *
+ * @var int
+ */
+ protected $type;
+
+ /**
+ * Creates the property.
+ *
+ * The 'type' argument must be one of the type constants defined in this class.
+ *
+ * 'href' is only required for the HREF type.
+ *
+ * @param int $type
+ * @param string|null $href
+ */
+ function __construct($type, $href = null) {
+
+ $this->type = $type;
+ if ($type === self::HREF && is_null($href)) {
+ throw new DAV\Exception('The href argument must be specified for the HREF principal type.');
+ }
+ if ($href) {
+ $href = rtrim($href, '/') . '/';
+ parent::__construct($href);
+ }
+
+ }
+
+ /**
+ * Returns the principal type
+ *
+ * @return int
+ */
+ function getType() {
+
+ return $this->type;
+
+ }
+
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ switch ($this->type) {
+
+ case self::UNAUTHENTICATED :
+ $writer->writeElement('{DAV:}unauthenticated');
+ break;
+ case self::AUTHENTICATED :
+ $writer->writeElement('{DAV:}authenticated');
+ break;
+ case self::HREF :
+ parent::xmlSerialize($writer);
+ break;
+ case self::ALL :
+ $writer->writeElement('{DAV:}all');
+ break;
+ }
+
+ }
+
+ /**
+ * Generate html representation for this value.
+ *
+ * The html output is 100% trusted, and no effort is being made to sanitize
+ * it. It's up to the implementor to sanitize user provided values.
+ *
+ * The output must be in UTF-8.
+ *
+ * The baseUri parameter is a url to the root of the application, and can
+ * be used to construct local links.
+ *
+ * @param HtmlOutputHelper $html
+ * @return string
+ */
+ function toHtml(HtmlOutputHelper $html) {
+
+ switch ($this->type) {
+
+ case self::UNAUTHENTICATED :
+ return '<em>unauthenticated</em>';
+ case self::AUTHENTICATED :
+ return '<em>authenticated</em>';
+ case self::HREF :
+ return parent::toHtml($html);
+ case self::ALL :
+ return '<em>all</em>';
+ }
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called staticly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * Important note 2: You are responsible for advancing the reader to the
+ * next element. Not doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $tree = $reader->parseInnerTree()[0];
+
+ switch ($tree['name']) {
+ case '{DAV:}unauthenticated' :
+ return new self(self::UNAUTHENTICATED);
+ case '{DAV:}authenticated' :
+ return new self(self::AUTHENTICATED);
+ case '{DAV:}href':
+ return new self(self::HREF, $tree['value']);
+ case '{DAV:}all':
+ return new self(self::ALL);
+ default :
+ throw new BadRequest('Unknown or unsupported principal type: ' . $tree['name']);
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
new file mode 100644
index 000000000..572bed4dd
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Property;
+
+use Sabre\DAV\Browser\HtmlOutput;
+use Sabre\DAV\Browser\HtmlOutputHelper;
+use Sabre\Xml\XmlSerializable;
+use Sabre\Xml\Writer;
+
+/**
+ * SupportedPrivilegeSet property
+ *
+ * This property encodes the {DAV:}supported-privilege-set property, as defined
+ * in rfc3744. Please consult the rfc for details about it's structure.
+ *
+ * This class expects a structure like the one given from
+ * Sabre\DAVACL\Plugin::getSupportedPrivilegeSet as the argument in its
+ * constructor.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
+
+ /**
+ * privileges
+ *
+ * @var array
+ */
+ protected $privileges;
+
+ /**
+ * Constructor
+ *
+ * @param array $privileges
+ */
+ function __construct(array $privileges) {
+
+ $this->privileges = $privileges;
+
+ }
+
+ /**
+ * Returns the privilege value.
+ *
+ * @return array
+ */
+ function getValue() {
+
+ return $this->privileges;
+
+ }
+
+ /**
+ * The xmlSerialize metod is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ $this->serializePriv($writer, $this->privileges);
+
+ }
+
+ /**
+ * Generate html representation for this value.
+ *
+ * The html output is 100% trusted, and no effort is being made to sanitize
+ * it. It's up to the implementor to sanitize user provided values.
+ *
+ * The output must be in UTF-8.
+ *
+ * The baseUri parameter is a url to the root of the application, and can
+ * be used to construct local links.
+ *
+ * @param HtmlOutputHelper $html
+ * @return string
+ */
+ function toHtml(HtmlOutputHelper $html) {
+
+ $traverse = function($priv) use (&$traverse, $html) {
+ echo "<li>";
+ echo $html->xmlName($priv['privilege']);
+ if (isset($priv['abstract']) && $priv['abstract']) {
+ echo " <i>(abstract)</i>";
+ }
+ if (isset($priv['description'])) {
+ echo " " . $html->h($priv['description']);
+ }
+ if (isset($priv['aggregates'])) {
+ echo "\n<ul>\n";
+ foreach ($priv['aggregates'] as $subPriv) {
+ $traverse($subPriv);
+ }
+ echo "</ul>";
+ }
+ echo "</li>\n";
+ };
+
+ ob_start();
+ echo "<ul class=\"tree\">";
+ $traverse($this->getValue());
+ echo "</ul>\n";
+
+ return ob_get_clean();
+
+ }
+
+
+
+ /**
+ * Serializes a property
+ *
+ * This is a recursive function.
+ *
+ * @param Writer $writer
+ * @param array $privilege
+ * @return void
+ */
+ private function serializePriv(Writer $writer, $privilege) {
+
+ $writer->startElement('{DAV:}supported-privilege');
+
+ $writer->startElement('{DAV:}privilege');
+ $writer->writeElement($privilege['privilege']);
+ $writer->endElement(); // privilege
+
+ if (!empty($privilege['abstract'])) {
+ $writer->writeElement('{DAV:}abstract');
+ }
+ if (!empty($privilege['description'])) {
+ $writer->writeElement('{DAV:}description', $privilege['description']);
+ }
+ if (isset($privilege['aggregates'])) {
+ foreach ($privilege['aggregates'] as $subPrivilege) {
+ $this->serializePriv($writer, $subPrivilege);
+ }
+ }
+
+ $writer->endElement(); // supported-privilege
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php b/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php
new file mode 100644
index 000000000..3f535e301
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Request;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+
+/**
+ * ExpandProperty request parser.
+ *
+ * This class parses the {DAV:}expand-property REPORT, as defined in:
+ *
+ * http://tools.ietf.org/html/rfc3253#section-3.8
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class ExpandPropertyReport implements XmlDeserializable {
+
+ /**
+ * An array with requested properties.
+ *
+ * The requested properties will be used as keys in this array. The value
+ * is normally null.
+ *
+ * If the value is an array though, it means the property must be expanded.
+ * Within the array, the sub-properties, which themselves may be null or
+ * arrays.
+ *
+ * @var array
+ */
+ public $properties;
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $elems = $reader->parseInnerTree();
+
+ $obj = new self();
+ $obj->properties = self::traverse($elems);
+
+ return $obj;
+
+ }
+
+ /**
+ * This method is used by deserializeXml, to recursively parse the
+ * {DAV:}property elements.
+ *
+ * @param array $elems
+ * @return void
+ */
+ private static function traverse($elems) {
+
+ $result = [];
+
+ foreach ($elems as $elem) {
+
+ if ($elem['name'] !== '{DAV:}property') {
+ continue;
+ }
+
+ $namespace = isset($elem['attributes']['namespace']) ?
+ $elem['attributes']['namespace'] :
+ 'DAV:';
+
+ $propName = '{' . $namespace . '}' . $elem['attributes']['name'];
+
+ $value = null;
+ if (is_array($elem['value'])) {
+ $value = self::traverse($elem['value']);
+ }
+
+ $result[$propName] = $value;
+
+ }
+
+ return $result;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php
new file mode 100644
index 000000000..1e7aa4481
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Request;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\DAV\Exception\BadRequest;
+
+/**
+ * PrincipalSearchPropertySetReport request parser.
+ *
+ * This class parses the {DAV:}principal-property-search REPORT, as defined
+ * in:
+ *
+ * https://tools.ietf.org/html/rfc3744#section-9.4
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class PrincipalPropertySearchReport implements XmlDeserializable {
+
+ /**
+ * The requested properties.
+ *
+ * @var array|null
+ */
+ public $properties;
+
+ /**
+ * searchProperties
+ *
+ * @var array
+ */
+ public $searchProperties = [];
+
+ /**
+ * By default the property search will be conducted on the url of the http
+ * request. If this is set to true, it will be applied to the principal
+ * collection set instead.
+ *
+ * @var bool
+ */
+ public $applyToPrincipalCollectionSet = false;
+
+ /**
+ * Search for principals matching ANY of the properties (OR) or a ALL of
+ * the properties (AND).
+ *
+ * This property is either "anyof" or "allof".
+ *
+ * @var string
+ */
+ public $test;
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $self = new self();
+
+ $foundSearchProp = false;
+ $self->test = 'allof';
+ if ($reader->getAttribute('test') === 'anyof') {
+ $self->test = 'anyof';
+ }
+
+ $elemMap = [
+ '{DAV:}property-search' => 'Sabre\\Xml\\Element\\KeyValue',
+ '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue',
+ ];
+
+ foreach ($reader->parseInnerTree($elemMap) as $elem) {
+
+ switch ($elem['name']) {
+
+ case '{DAV:}prop' :
+ $self->properties = array_keys($elem['value']);
+ break;
+ case '{DAV:}property-search' :
+ $foundSearchProp = true;
+ // This property has two sub-elements:
+ // {DAV:}prop - The property to be searched on. This may
+ // also be more than one
+ // {DAV:}match - The value to match with
+ if (!isset($elem['value']['{DAV:}prop']) || !isset($elem['value']['{DAV:}match'])) {
+ throw new BadRequest('The {DAV:}property-search element must contain one {DAV:}match and one {DAV:}prop element');
+ }
+ foreach ($elem['value']['{DAV:}prop'] as $propName => $discard) {
+ $self->searchProperties[$propName] = $elem['value']['{DAV:}match'];
+ }
+ break;
+ case '{DAV:}apply-to-principal-collection-set' :
+ $self->applyToPrincipalCollectionSet = true;
+ break;
+
+ }
+
+ }
+ if (!$foundSearchProp) {
+ throw new BadRequest('The {DAV:}principal-property-search report must contain at least 1 {DAV:}property-search element');
+ }
+
+ return $self;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php
new file mode 100644
index 000000000..ade157b19
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Request;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\DAV\Exception\BadRequest;
+
+/**
+ * PrincipalSearchPropertySetReport request parser.
+ *
+ * This class parses the {DAV:}principal-search-property-set REPORT, as defined
+ * in:
+ *
+ * https://tools.ietf.org/html/rfc3744#section-9.5
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class PrincipalSearchPropertySetReport implements XmlDeserializable {
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ if (!$reader->isEmptyElement) {
+ throw new BadRequest('The {DAV:}principal-search-property-set element must be empty');
+ }
+
+ // The element is actually empty, so there's not much to do.
+ $reader->next();
+
+ $self = new self();
+ return $self;
+
+ }
+
+}