diff options
Diffstat (limited to 'vendor/sabre/dav/lib/CalDAV/Xml')
21 files changed, 2610 insertions, 0 deletions
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php new file mode 100644 index 000000000..9babcf15c --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php @@ -0,0 +1,84 @@ +<?php + +namespace Sabre\CalDAV\Xml\Filter; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\DAV\Exception\BadRequest; +use Sabre\CalDAV\Plugin; +use Sabre\VObject\DateTimeParser; + +/** + * CalendarData parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-data XML + * element, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-9.6 + * + * This element is used in three distinct places in the caldav spec, but in + * this case, this element class only implements the calendar-data element as + * it appears in a DAV:prop element, in a calendar-query or calendar-multiget + * REPORT request. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class CalendarData 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) { + + $result = [ + 'contentType' => $reader->getAttribute('content-type') ?: 'text/calendar', + 'version' => $reader->getAttribute('version') ?: '2.0', + ]; + + $elems = (array)$reader->parseInnerTree(); + foreach ($elems as $elem) { + + switch ($elem['name']) { + 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, + ]; + + if (!$result['expand']['start'] || !$result['expand']['end']) { + throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data'); + } + if ($result['expand']['end'] <= $result['expand']['start']) { + throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data'); + } + break; + } + + } + + return $result; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php new file mode 100644 index 000000000..c9b27dbfd --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php @@ -0,0 +1,97 @@ +<?php + +namespace Sabre\CalDAV\Xml\Filter; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\DAV\Exception\BadRequest; +use Sabre\CalDAV\Plugin; +use Sabre\VObject\DateTimeParser; + +/** + * CompFilter parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}comp-filter XML + * element, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-9.6 + * + * The result will be spit out as an array. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class CompFilter 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) { + + $result = [ + 'name' => null, + 'is-not-defined' => false, + 'comp-filters' => [], + 'prop-filters' => [], + 'time-range' => false, + ]; + + $att = $reader->parseAttributes(); + $result['name'] = $att['name']; + + $elems = $reader->parseInnerTree(); + + 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' : + $result['prop-filters'][] = $elem['value']; + break; + case '{' . Plugin::NS_CALDAV . '}is-not-defined' : + $result['is-not-defined'] = true; + break; + case '{' . Plugin::NS_CALDAV . '}time-range' : + if ($result['name'] === 'VCALENDAR') { + 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, + ]; + 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; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php new file mode 100644 index 000000000..eb7f564df --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php @@ -0,0 +1,82 @@ +<?php + +namespace Sabre\CalDAV\Xml\Filter; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\CalDAV\Plugin; + +/** + * PropFilter parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}param-filter XML + * element, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-9.7.3 + * + * The result will be spit out as an array. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class ParamFilter 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. + * + * 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) { + + $result = [ + 'name' => null, + 'is-not-defined' => false, + 'text-match' => null, + ]; + + $att = $reader->parseAttributes(); + $result['name'] = $att['name']; + + $elems = $reader->parseInnerTree(); + + 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' : + $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'], + ]; + break; + + } + + } + + return $result; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php new file mode 100644 index 000000000..4c2e1b172 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php @@ -0,0 +1,98 @@ +<?php + +namespace Sabre\CalDAV\Xml\Filter; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\DAV\Exception\BadRequest; +use Sabre\CalDAV\Plugin; +use Sabre\VObject\DateTimeParser; + +/** + * PropFilter parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}prop-filter XML + * element, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-9.7.2 + * + * The result will be spit out as an array. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class PropFilter 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) { + + $result = [ + 'name' => null, + 'is-not-defined' => false, + 'param-filters' => [], + 'text-match' => null, + 'time-range' => false, + ]; + + $att = $reader->parseAttributes(); + $result['name'] = $att['name']; + + $elems = $reader->parseInnerTree(); + + 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' : + $result['is-not-defined'] = true; + break; + 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, + ]; + 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' : + $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'], + ]; + break; + + } + + } + + return $result; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php new file mode 100644 index 000000000..7fb022e33 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php @@ -0,0 +1,307 @@ +<?php + +namespace Sabre\CalDAV\Xml\Notification; + +use Sabre\Xml\Writer; +use Sabre\CalDAV\SharingPlugin as SharingPlugin; +use Sabre\CalDAV; + +/** + * This class represents the cs:invite-notification notification element. + * + * This element is defined here: + * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.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 NotificationInterface { + + /** + * A unique id for the message + * + * @var string + */ + protected $id; + + /** + * Timestamp of the notification + * + * @var DateTime + */ + protected $dtStamp; + + /** + * A url to the recipient of the notification. This can be an email + * address (mailto:), or a principal url. + * + * @var string + */ + protected $href; + + /** + * The type of message, see the SharingPlugin::STATUS_* constants. + * + * @var int + */ + protected $type; + + /** + * True if access to a calendar is read-only. + * + * @var bool + */ + protected $readOnly; + + /** + * A url to the shared calendar. + * + * @var string + */ + protected $hostUrl; + + /** + * Url to the sharer of the calendar + * + * @var string + */ + protected $organizer; + + /** + * The name of the sharer. + * + * @var string + */ + protected $commonName; + + /** + * The name of the sharer. + * + * @var string + */ + protected $firstName; + + /** + * The name of the sharer. + * + * @var string + */ + protected $lastName; + + /** + * A description of the share request + * + * @var string + */ + protected $summary; + + /** + * The Etag for the notification + * + * @var string + */ + protected $etag; + + /** + * The list of supported components + * + * @var Sabre\CalDAV\Property\SupportedCalendarComponentSet + */ + protected $supportedComponents; + + /** + * Creates the Invite notification. + * + * This constructor receives an array with the following elements: + * + * * id - A unique id + * * etag - The etag + * * dtStamp - A DateTime object with a timestamp for the notification. + * * type - The type of notification, see SharingPlugin::STATUS_* + * constants for details. + * * readOnly - This must be set to true, if this is an invite for + * read-only access to a calendar. + * * hostUrl - A url to the shared calendar. + * * organizer - Url to the sharer principal. + * * commonName - The real name of the sharer (optional). + * * firstName - The first name of the sharer (optional). + * * lastName - The last name of the sharer (optional). + * * summary - Description of the share, can be the same as the + * calendar, but may also be modified (optional). + * * supportedComponents - An instance of + * Sabre\CalDAV\Property\SupportedCalendarComponentSet. + * This allows the client to determine which components + * will be supported in the shared calendar. This is + * also optional. + * + * @param array $values All the options + */ + function __construct(array $values) { + + $required = [ + 'id', + 'etag', + 'href', + 'dtStamp', + 'type', + 'readOnly', + 'hostUrl', + 'organizer', + ]; + foreach ($required as $item) { + if (!isset($values[$item])) { + 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); + } + $this->$key = $value; + } + + } + + /** + * 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('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-notification'); + + } + + /** + * This method serializes the entire notification, as it is used in the + * response body. + * + * @param Writer $writer + * @return void + */ + function xmlSerializeFull(Writer $writer) { + + $cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}'; + + $this->dtStamp->setTimezone(new \DateTimezone('GMT')); + $writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z')); + + $writer->startElement($cs . 'invite-notification'); + + $writer->writeElement($cs . 'uid', $this->id); + $writer->writeElement('{DAV:}href', $this->href); + + switch ($this->type) { + + case SharingPlugin::STATUS_ACCEPTED : + $writer->writeElement($cs . 'invite-accepted'); + break; + case SharingPlugin::STATUS_DECLINED : + $writer->writeElement($cs . 'invite-declined'); + break; + case SharingPlugin::STATUS_DELETED : + $writer->writeElement($cs . 'invite-deleted'); + break; + case SharingPlugin::STATUS_NORESPONSE : + $writer->writeElement($cs . 'invite-noresponse'); + break; + + } + + $writer->writeElement($cs . 'hosturl', [ + '{DAV:}href' => $writer->contextUri . $this->hostUrl + ]); + + if ($this->summary) { + $writer->writeElement($cs . 'summary', $this->summary); + } + + $writer->startElement($cs . 'access'); + if ($this->readOnly) { + $writer->writeElement($cs . 'read'); + } else { + $writer->writeElement($cs . 'read-write'); + } + $writer->endElement(); // access + + $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:') { + $writer->writeElement('{DAV:}href', $this->organizer); + } else { + $writer->writeElement('{DAV:}href', $writer->contextUri . $this->organizer); + } + if ($this->commonName) { + $writer->writeElement($cs . 'common-name', $this->commonName); + } + if ($this->firstName) { + $writer->writeElement($cs . 'first-name', $this->firstName); + } + if ($this->lastName) { + $writer->writeElement($cs . 'last-name', $this->lastName); + } + $writer->endElement(); // organizer + + if ($this->commonName) { + $writer->writeElement($cs . 'organizer-cn', $this->commonName); + } + if ($this->firstName) { + $writer->writeElement($cs . 'organizer-first', $this->firstName); + } + if ($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->endElement(); // invite-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() { + + return $this->id; + + } + + /** + * Returns the ETag for this notification. + * + * The ETag must be surrounded by literal double-quotes. + * + * @return string + */ + function getETag() { + + return $this->etag; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php new file mode 100644 index 000000000..945323fed --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php @@ -0,0 +1,212 @@ +<?php + +namespace Sabre\CalDAV\Xml\Notification; + +use Sabre\Xml\Writer; +use Sabre\CalDAV; +use Sabre\CalDAV\SharingPlugin; + +/** + * This class represents the cs:invite-reply notification element. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class InviteReply implements NotificationInterface { + + /** + * A unique id for the message + * + * @var string + */ + protected $id; + + /** + * Timestamp of the notification + * + * @var DateTime + */ + protected $dtStamp; + + /** + * The unique id of the notification this was a reply to. + * + * @var string + */ + protected $inReplyTo; + + /** + * A url to the recipient of the original (!) notification. + * + * @var string + */ + protected $href; + + /** + * The type of message, see the SharingPlugin::STATUS_ constants. + * + * @var int + */ + protected $type; + + /** + * A url to the shared calendar. + * + * @var string + */ + protected $hostUrl; + + /** + * A description of the share request + * + * @var string + */ + protected $summary; + + /** + * Notification Etag + * + * @var string + */ + protected $etag; + + /** + * Creates the Invite Reply Notification. + * + * This constructor receives an array with the following elements: + * + * * id - A unique id + * * etag - The etag + * * dtStamp - A DateTime object with a timestamp for the notification. + * * inReplyTo - This should refer to the 'id' of the notification + * this is a reply to. + * * type - The type of notification, see SharingPlugin::STATUS_* + * constants for details. + * * hostUrl - A url to the shared calendar. + * * summary - Description of the share, can be the same as the + * calendar, but may also be modified (optional). + * + * @param array $values + */ + function __construct(array $values) { + + $required = [ + 'id', + 'etag', + 'href', + 'dtStamp', + 'inReplyTo', + 'type', + 'hostUrl', + ]; + foreach ($required as $item) { + if (!isset($values[$item])) { + 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); + } + $this->$key = $value; + } + + } + + /** + * 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('{' . CalDAV\Plugin::NS_CALENDARSERVER . '}invite-reply'); + + } + + /** + * This method serializes the entire notification, as it is used in the + * response body. + * + * @param Writer $writer + * @return void + */ + function xmlSerializeFull(Writer $writer) { + + $cs = '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}'; + + $this->dtStamp->setTimezone(new \DateTimezone('GMT')); + $writer->writeElement($cs . 'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z')); + + $writer->startElement($cs . 'invite-reply'); + + $writer->writeElement($cs . 'uid', $this->id); + $writer->writeElement($cs . 'in-reply-to', $this->inReplyTo); + $writer->writeElement('{DAV:}href', $this->href); + + switch ($this->type) { + + case SharingPlugin::STATUS_ACCEPTED : + $writer->writeElement($cs . 'invite-accepted'); + break; + case SharingPlugin::STATUS_DECLINED : + $writer->writeElement($cs . 'invite-declined'); + break; + + } + + $writer->writeElement($cs . 'hosturl', [ + '{DAV:}href' => $writer->contextUri . $this->hostUrl + ]); + + if ($this->summary) { + $writer->writeElement($cs . 'summary', $this->summary); + } + $writer->endElement(); // invite-reply + + } + + /** + * 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() { + + return $this->id; + + } + + /** + * Returns the ETag for this notification. + * + * The ETag must be surrounded by literal double-quotes. + * + * @return string + */ + function getETag() { + + return $this->etag; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php new file mode 100644 index 000000000..1c08f12fd --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php @@ -0,0 +1,45 @@ +<?php + +namespace Sabre\CalDAV\Xml\Notification; + +use Sabre\Xml\XmlSerializable; +use Sabre\Xml\Writer; + +/** + * This interface reflects a single notification type. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +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); + + /** + * 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(); + + /** + * Returns the ETag for this notification. + * + * The ETag must be surrounded by literal double-quotes. + * + * @return string + */ + function getETag(); + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php new file mode 100644 index 000000000..d41702e07 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php @@ -0,0 +1,182 @@ +<?php + +namespace Sabre\CalDAV\Xml\Notification; + +use Sabre\Xml\Writer; +use Sabre\CalDAV\Plugin; + +/** + * SystemStatus notification + * + * This notification can be used to indicate to the user that the system is + * down. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class SystemStatus implements NotificationInterface { + + const TYPE_LOW = 1; + const TYPE_MEDIUM = 2; + const TYPE_HIGH = 3; + + /** + * A unique id + * + * @var string + */ + protected $id; + + /** + * The type of alert. This should be one of the TYPE_ constants. + * + * @var int + */ + protected $type; + + /** + * A human-readable description of the problem. + * + * @var string + */ + protected $description; + + /** + * A url to a website with more information for the user. + * + * @var string + */ + protected $href; + + /** + * Notification Etag + * + * @var string + */ + protected $etag; + + /** + * Creates the notification. + * + * Some kind of unique id should be provided. This is used to generate a + * url. + * + * @param string $id + * @param string $etag + * @param int $type + * @param string $description + * @param string $href + */ + 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; + + } + + /** + * The serialize method is called during xml writing. + * + * It should use the $writer argument to encode this object into XML. + * + * Important note: it is not needed to create the parent element. The + * parent element is already created, and we only have to worry about + * attributes, child elements and text (if any). + * + * Important note 2: If you are writing any new elements, you are also + * responsible for closing them. + * + * @param Writer $writer + * @return void + */ + function xmlSerialize(Writer $writer) { + + switch ($this->type) { + case self::TYPE_LOW : + $type = 'low'; + break; + case self::TYPE_MEDIUM : + $type = 'medium'; + break; + default : + case self::TYPE_HIGH : + $type = 'high'; + break; + } + + $writer->startElement('{' . Plugin::NS_CALENDARSERVER . '}systemstatus'); + $writer->writeAttribute('type', $type); + $writer->endElement(); + + } + + /** + * This method serializes the entire notification, as it is used in the + * response body. + * + * @param Writer $writer + * @return void + */ + function xmlSerializeFull(Writer $writer) { + + $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; + switch ($this->type) { + case self::TYPE_LOW : + $type = 'low'; + break; + case self::TYPE_MEDIUM : + $type = 'medium'; + break; + default : + case self::TYPE_HIGH : + $type = 'high'; + break; + } + + $writer->startElement($cs . 'systemstatus'); + $writer->writeAttribute('type', $type); + + + if ($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 + * + * This is just the base url. This should generally be some kind of unique + * id. + * + * @return string + */ + function getId() { + + return $this->id; + + } + + /* + * Returns the ETag for this notification. + * + * The ETag must be surrounded by literal double-quotes. + * + * @return string + */ + function getETag() { + + return $this->etag; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php new file mode 100644 index 000000000..c2a2d565e --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php @@ -0,0 +1,87 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\XmlSerializable; +use Sabre\Xml\Writer; +use Sabre\CalDAV\Plugin; + +/** + * AllowedSharingModes + * + * This property encodes the 'allowed-sharing-modes' property, as defined by + * the 'caldav-sharing-02' spec, in the http://calendarserver.org/ns/ + * namespace. + * + * This property is a representation of the supported-calendar_component-set + * property in the CalDAV namespace. It simply requires an array of components, + * 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 { + + /** + * Whether or not a calendar can be shared with another user + * + * @var bool + */ + protected $canBeShared; + + /** + * Whether or not the calendar can be placed on a public url. + * + * @var bool + */ + protected $canBePublished; + + /** + * Constructor + * + * @param bool $canBeShared + * @param bool $canBePublished + * @return void + */ + function __construct($canBeShared, $canBePublished) { + + $this->canBeShared = $canBeShared; + $this->canBePublished = $canBePublished; + + } + + /** + * 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) { + + if ($this->canBeShared) { + $writer->writeElement('{' . Plugin::NS_CALENDARSERVER . '}can-be-shared'); + } + if ($this->canBePublished) { + $writer->writeElement('{' . Plugin::NS_CALENDARSERVER . '}can-be-published'); + } + + } + + + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php new file mode 100644 index 000000000..f577a9919 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php @@ -0,0 +1,80 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\Writer; +use Sabre\Xml\XmlSerializable; + +/** + * email-address-set property + * + * This property represents the email-address-set property in the + * http://calendarserver.org/ns/ namespace. + * + * It's a list of email addresses associated with a user. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class EmailAddressSet implements XmlSerializable { + + /** + * emails + * + * @var array + */ + private $emails; + + /** + * __construct + * + * @param array $emails + */ + function __construct(array $emails) { + + $this->emails = $emails; + + } + + /** + * Returns the email addresses + * + * @return array + */ + function getValue() { + + return $this->emails; + + } + + /** + * 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->emails as $email) { + + $writer->writeElement('{http://calendarserver.org/ns/}email-address', $email); + + } + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php new file mode 100644 index 000000000..3ee053214 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php @@ -0,0 +1,252 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\Element; +use Sabre\Xml\Reader; +use Sabre\Xml\Writer; +use Sabre\CalDAV\Plugin; +use Sabre\CalDAV\SharingPlugin; + +/** + * 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 Element { + + /** + * The list of users a calendar has been shared to. + * + * @var array + */ + protected $users; + + /** + * The organizer contains information about the person who shared the + * object. + * + * @var array + */ + protected $organizer; + + /** + * Creates the property. + * + * Users is an array. Each element of the array has the following + * properties: + * + * * href - Often a mailto: address + * * commonName - Optional, for example a first and lastname for a user. + * * status - One of the SharingPlugin::STATUS_* constants. + * * readOnly - true or false + * * summary - Optional, description of the share + * + * The organizer key is optional to specify. It's only useful when a + * 'sharee' requests the sharing information. + * + * The organizer may have the following properties: + * * href - Often a mailto: address. + * * commonName - Optional human-readable name. + * * firstName - Optional first name. + * * lastName - Optional last name. + * + * If you wonder why these two structures are so different, I guess a + * valid answer is that the current spec is still a draft. + * + * @param array $users + */ + function __construct(array $users, array $organizer = null) { + + $this->users = $users; + $this->organizer = $organizer; + + } + + /** + * Returns the list of users, as it was passed to the constructor. + * + * @return array + */ + function getValue() { + + return $this->users; + + } + + /** + * 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) { + + $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; + + if (!is_null($this->organizer)) { + + $writer->startElement($cs . 'organizer'); + $writer->writeElement('{DAV:}href', $this->organizer['href']); + + if (isset($this->organizer['commonName']) && $this->organizer['commonName']) { + $writer->writeElement($cs . 'common-name', $this->organizer['commonName']); + } + if (isset($this->organizer['firstName']) && $this->organizer['firstName']) { + $writer->writeElement($cs . 'first-name', $this->organizer['firstName']); + } + if (isset($this->organizer['lastName']) && $this->organizer['lastName']) { + $writer->writeElement($cs . 'last-name', $this->organizer['lastName']); + } + $writer->endElement(); // organizer + + } + + foreach ($this->users as $user) { + + $writer->startElement($cs . 'user'); + $writer->writeElement('{DAV:}href', $user['href']); + if (isset($user['commonName']) && $user['commonName']) { + $writer->writeElement($cs . 'common-name', $user['commonName']); + } + switch ($user['status']) { + + case SharingPlugin::STATUS_ACCEPTED : + $writer->writeElement($cs . 'invite-accepted'); + break; + case SharingPlugin::STATUS_DECLINED : + $writer->writeElement($cs . 'invite-declined'); + break; + case SharingPlugin::STATUS_NORESPONSE : + $writer->writeElement($cs . 'invite-noresponse'); + break; + case SharingPlugin::STATUS_INVALID : + $writer->writeElement($cs . 'invite-invalid'); + break; + } + + $writer->startElement($cs . 'access'); + if ($user['readOnly']) { + $writer->writeElement($cs . 'read'); + } else { + $writer->writeElement($cs . 'read-write'); + } + $writer->endElement(); // access + + if (isset($user['summary']) && $user['summary']) { + $writer->writeElement($cs . 'summary', $user['summary']); + } + + $writer->endElement(); //user + + } + + } + + /** + * 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) { + + $cs = '{' . Plugin::NS_CALENDARSERVER . '}'; + + $users = []; + + foreach ($reader->parseInnerTree() as $elem) { + + if ($elem['name'] !== $cs . 'user') + continue; + + $user = [ + 'href' => null, + 'commonName' => null, + 'readOnly' => null, + 'summary' => null, + 'status' => null, + ]; + + foreach ($elem['value'] as $userElem) { + + switch ($userElem['name']) { + case $cs . 'invite-accepted' : + $user['status'] = SharingPlugin::STATUS_ACCEPTED; + break; + case $cs . 'invite-declined' : + $user['status'] = SharingPlugin::STATUS_DECLINED; + break; + case $cs . 'invite-noresponse' : + $user['status'] = SharingPlugin::STATUS_NORESPONSE; + break; + case $cs . 'invite-invalid' : + $user['status'] = SharingPlugin::STATUS_INVALID; + break; + case '{DAV:}href' : + $user['href'] = $userElem['value']; + break; + case $cs . 'common-name' : + $user['commonName'] = $userElem['value']; + break; + case $cs . 'access' : + foreach ($userElem['value'] as $accessHref) { + if ($accessHref['name'] === $cs . 'read') { + $user['readOnly'] = true; + } + } + break; + case $cs . 'summary' : + $user['summary'] = $userElem['value']; + break; + + } + + } + if (!$user['status']) { + throw new \InvalidArgumentException('Every user must have one of cs:invite-accepted, cs:invite-declined, cs:invite-noresponse or cs:invite-invalid'); + } + + $users[] = $user; + + } + + return new self($users); + + } +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php new file mode 100644 index 000000000..4a253e008 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php @@ -0,0 +1,140 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\Element; +use Sabre\Xml\Reader; +use Sabre\Xml\Writer; +use Sabre\Xml\Element\Elements; +use Sabre\CalDAV\Plugin; + +/** + * schedule-calendar-transp property. + * + * This property is a representation of the schedule-calendar-transp property. + * This property is defined in: + * + * http://tools.ietf.org/html/rfc6638#section-9.1 + * + * Its values are either 'transparent' or 'opaque'. If it's transparent, it + * means that this calendar will not be taken into consideration when a + * different user queries for free-busy information. If it's 'opaque', it will. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class ScheduleCalendarTransp implements Element { + + const TRANSPARENT = 'transparent'; + const OPAQUE = 'opaque'; + + /** + * value + * + * @var string + */ + protected $value; + + /** + * Creates the property + * + * @param string $value + */ + function __construct($value) { + + if ($value !== self::TRANSPARENT && $value !== self::OPAQUE) { + throw new \InvalidArgumentException('The value must either be specified as "transparent" or "opaque"'); + } + $this->value = $value; + + } + + /** + * Returns the current value + * + * @return string + */ + function getValue() { + + return $this->value; + + } + + /** + * 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->value) { + case self::TRANSPARENT : + $writer->writeElement('{' . Plugin::NS_CALDAV . '}transparent'); + break; + case self::OPAQUE : + $writer->writeElement('{' . Plugin::NS_CALDAV . '}opaque'); + break; + } + + } + + /** + * 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 = Elements::xmlDeserialize($reader); + + $value = null; + + foreach ($elems as $elem) { + switch ($elem) { + case '{' . Plugin::NS_CALDAV . '}opaque' : + $value = self::OPAQUE; + break; + case '{' . Plugin::NS_CALDAV . '}transparent' : + $value = self::TRANSPARENT; + break; + } + } + if (is_null($value)) + return null; + + return new self($value); + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php new file mode 100644 index 000000000..7a26e767e --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php @@ -0,0 +1,129 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\Element; +use Sabre\Xml\ParseException; +use Sabre\Xml\Reader; +use Sabre\Xml\Writer; +use Sabre\CalDAV\Plugin; + +/** + * SupportedCalendarComponentSet property. + * + * This class represents the + * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set property, as + * defined in: + * + * https://tools.ietf.org/html/rfc4791#section-5.2.3 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class SupportedCalendarComponentSet implements Element { + + /** + * List of supported components. + * + * This array will contain values such as VEVENT, VTODO and VJOURNAL. + * + * @var array + */ + protected $components = []; + + /** + * Creates the property. + * + * @param array $components + */ + function __construct(array $components) { + + $this->components = $components; + + } + + /** + * Returns the list of supported components + * + * @return array + */ + function getValue() { + + return $this->components; + + } + + /** + * 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->components as $component) { + + $writer->startElement('{' . Plugin::NS_CALDAV . '}comp'); + $writer->writeAttributes(['name' => $component]); + $writer->endElement(); + + } + + } + + /** + * 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(); + + $components = []; + + foreach ((array)$elems as $elem) { + if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}comp') { + $components[] = $elem['attributes']['name']; + } + } + + if (!$components) { + throw new ParseException('supported-calendar-component-set must have at least one CALDAV:comp element'); + } + + return new self($components); + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php new file mode 100644 index 000000000..b0c407fd6 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php @@ -0,0 +1,60 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\XmlSerializable; +use Sabre\Xml\Writer; +use Sabre\CalDAV\Plugin; + +/** + * 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 + * so the value is currently hardcoded. + * + * This property is defined in: + * http://tools.ietf.org/html/rfc4791#section-5.2.4 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class SupportedCalendarData 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->startElement('{' . Plugin::NS_CALDAV . '}calendar-data'); + $writer->writeAttributes([ + 'content-type' => 'text/calendar', + 'version' => '2.0', + ]); + $writer->endElement(); // calendar-data + $writer->startElement('{' . Plugin::NS_CALDAV . '}calendar-data'); + $writer->writeAttributes([ + 'content-type' => 'application/calendar+json', + ]); + $writer->endElement(); // calendar-data + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php new file mode 100644 index 000000000..71de25a62 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php @@ -0,0 +1,57 @@ +<?php + +namespace Sabre\CalDAV\Xml\Property; + +use Sabre\Xml\Writer; +use Sabre\Xml\XmlSerializable; +use Sabre\CalDAV\Plugin; + +/** + * supported-collation-set property + * + * This property is a representation of the supported-collation-set property + * in the CalDAV namespace. + * + * This property is defined in: + * http://tools.ietf.org/html/rfc4791#section-7.5.1 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class SupportedCollationSet 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) { + + $collations = [ + 'i;ascii-casemap', + 'i;octet', + 'i;unicode-casemap' + ]; + + foreach ($collations as $collation) { + $writer->writeElement('{' . Plugin::NS_CALDAV . '}supported-collation', $collation); + } + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php new file mode 100644 index 000000000..79b3bb3ac --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php @@ -0,0 +1,124 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\Xml\XmlDeserializable; +use Sabre\Xml\Reader; +use Sabre\CalDAV\Plugin; +use Sabre\Uri; + +/** + * CalendarMultiGetReport request parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-multiget + * REPORT, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-7.9 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class CalendarMultiGetReport implements XmlDeserializable { + + /** + * An array with requested properties. + * + * @var array + */ + public $properties; + + /** + * This is an array with the urls that are being requested. + * + * @var array + */ + public $hrefs; + + /** + * If the calendar data must be expanded, this will contain an array with 2 + * elements: start and end. + * + * Each may be a DateTime or null. + * + * @var array|null + */ + public $expand = null; + + /** + * The mimetype of the content that should be returend. Usually + * text/calendar. + * + * @var string + */ + public $contentType = null; + + /** + * The version of calendar-data that should be returned. Usually '2.0', + * referring to iCalendar 2.0. + * + * @var string + */ + public $version = null; + + /** + * 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([ + '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', + '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', + ]); + + $newProps = [ + 'hrefs' => [], + 'properties' => [], + ]; + + foreach ($elems as $elem) { + + switch ($elem['name']) { + + 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']; + } + break; + case '{DAV:}href' : + $newProps['hrefs'][] = Uri\resolve($reader->contextUri, $elem['value']); + break; + + } + + } + + $obj = new self(); + foreach ($newProps as $key => $value) { + $obj->$key = $value; + } + + return $obj; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php new file mode 100644 index 000000000..848a4dc46 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php @@ -0,0 +1,139 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\Xml\XmlDeserializable; +use Sabre\Xml\Reader; +use Sabre\DAV\Exception\BadRequest; +use Sabre\CalDAV\Plugin; + +/** + * CalendarQueryReport request parser. + * + * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-query + * REPORT, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-7.9 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://sabre.io/license/ Modified BSD License + */ +class CalendarQueryReport implements XmlDeserializable { + + /** + * An array with requested properties. + * + * @var array + */ + public $properties; + + /** + * List of property/component filters. + * + * @var array + */ + public $filters; + + /** + * If the calendar data must be expanded, this will contain an array with 2 + * elements: start and end. + * + * Each may be a DateTime or null. + * + * @var array|null + */ + public $expand = null; + + /** + * The mimetype of the content that should be returend. Usually + * text/calendar. + * + * @var string + */ + public $contentType = null; + + /** + * The version of calendar-data that should be returned. Usually '2.0', + * referring to iCalendar 2.0. + * + * @var string + */ + public $version = null; + + /** + * 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([ + '{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', + ]); + + $newProps = [ + 'filters' => null, + 'properties' => [], + ]; + + if (!is_array($elems)) $elems = []; + + foreach ($elems as $elem) { + + switch ($elem['name']) { + + 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']; + } + break; + case '{' . Plugin::NS_CALDAV . '}filter' : + foreach ($elem['value'] as $subElem) { + 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'); + } + $newProps['filters'] = $subElem['value']; + } + } + break; + + } + + } + + if (is_null($newProps['filters'])) { + 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; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php new file mode 100644 index 000000000..e3b27d08e --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php @@ -0,0 +1,91 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\CalDAV\Plugin; +use Sabre\DAV\Exception\BadRequest; +use Sabre\VObject\DateTimeParser; +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; + +/** + * FreeBusyQueryReport + * + * This class parses the {DAV:}free-busy-query 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 FreeBusyQueryReport implements XmlDeserializable { + + /** + * Starttime of report + * + * @var DateTime|null + */ + public $start; + + /** + * End time of report + * + * @var DateTime|null + */ + public $end; + + /** + * 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) { + + $timeRange = '{' . Plugin::NS_CALDAV . '}time-range'; + + $start = null; + $end = null; + + 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'); + } + if ($start) { + $start = DateTimeParser::parseDateTime($start); + } + if ($end) { + $end = DateTimeParser::parseDateTime($end); + } + $result = new self(); + $result->start = $start; + $result->end = $end; + + return $result; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php new file mode 100644 index 000000000..ec627156f --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php @@ -0,0 +1,149 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\Xml\Element\KeyValue; +use Sabre\DAV\Exception\BadRequest; +use Sabre\CalDAV\Plugin; +use Sabre\CalDAV\SharingPlugin; + +/** + * Invite-reply POST request parser + * + * This class parses the invite-reply POST request, as defined in: + * + * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class InviteReply implements XmlDeserializable { + + /** + * The sharee calendar user address. + * + * This is the address that the original invite was set to + * + * @var string + */ + public $href; + + /** + * The uri to the calendar that was being shared. + * + * @var string + */ + public $calendarUri; + + /** + * The id of the invite message that's being responded to + * + * @var string + */ + public $inReplyTo; + + /** + * An optional message + * + * @var string + */ + public $summary; + + /** + * Either SharingPlugin::STATUS_ACCEPTED or SharingPlugin::STATUS_DECLINED. + * + * @var int + */ + public $status; + + /** + * Constructor + * + * @param string $href + * @param string $calendarUri + * @param string $inReplyTo + * @param string $summary + * @param int $status + */ + function __construct($href, $calendarUri, $inReplyTo, $summary, $status) { + + $this->href = $href; + $this->calendarUri = $calendarUri; + $this->inReplyTo = $inReplyTo; + $this->summary = $summary; + $this->status = $status; + + } + + /** + * 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 = KeyValue::xmlDeserialize($reader); + + $href = null; + $calendarUri = null; + $inReplyTo = null; + $summary = null; + $status = null; + + foreach ($elems as $name => $value) { + + switch ($name) { + + case '{' . Plugin::NS_CALENDARSERVER . '}hosturl' : + foreach ($value as $bla) { + if ($bla['name'] === '{DAV:}href') { + $calendarUri = $bla['value']; + } + } + break; + case '{' . Plugin::NS_CALENDARSERVER . '}invite-accepted' : + $status = SharingPlugin::STATUS_ACCEPTED; + break; + case '{' . Plugin::NS_CALENDARSERVER . '}invite-declined' : + $status = SharingPlugin::STATUS_DECLINED; + break; + case '{' . Plugin::NS_CALENDARSERVER . '}in-reply-to' : + $inReplyTo = $value; + break; + case '{' . Plugin::NS_CALENDARSERVER . '}summary' : + $summary = $value; + break; + 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); + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php new file mode 100644 index 000000000..7b745db55 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php @@ -0,0 +1,79 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; + +/** + * MKCALENDAR parser. + * + * This class parses the MKCALENDAR request, as defined in: + * + * https://tools.ietf.org/html/rfc4791#section-5.3.1 + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class MkCalendar implements XmlDeserializable { + + /** + * The list of properties that will be set. + * + * @var array + */ + public $properties = []; + + /** + * Returns the list of properties the calendar will be initialized with. + * + * @return array + */ + function getProperties() { + + return $this->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) { + + $self = new self(); + + $elementMap = $reader->elementMap; + $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop'; + $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue'; + $elems = $reader->parseInnerTree($elementMap); + + foreach ($elems as $elem) { + if ($elem['name'] === '{DAV:}set') { + $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']); + } + } + + return $self; + + } + +} diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php new file mode 100644 index 000000000..dacc5dc94 --- /dev/null +++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php @@ -0,0 +1,116 @@ +<?php + +namespace Sabre\CalDAV\Xml\Request; + +use Sabre\Xml\Reader; +use Sabre\Xml\XmlDeserializable; +use Sabre\CalDAV\Plugin; + +/** + * Share POST request parser + * + * This class parses the share POST request, as defined in: + * + * http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class Share implements XmlDeserializable { + + /** + * The list of new people added or updated. + * + * Every element has the following keys: + * 1. href - An email address + * 2. commonName - Some name + * 3. summary - An optional description of the share + * 4. readOnly - true or false + * + * @var array + */ + public $set = []; + + /** + * List of people removed from the share list. + * + * The list is a flat list of email addresses (including mailto:). + * + * @var array + */ + public $remove = []; + + /** + * Constructor + * + * @param array $set + * @param array $remove + */ + function __construct(array $set, array $remove) { + + $this->set = $set; + $this->remove = $remove; + + } + + /** + * 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([ + '{' . Plugin::NS_CALENDARSERVER . '}set' => 'Sabre\\Xml\\Element\\KeyValue', + '{' . Plugin::NS_CALENDARSERVER . '}remove' => 'Sabre\\Xml\\Element\\KeyValue', + ]); + + $set = []; + $remove = []; + + foreach ($elems as $elem) { + switch ($elem['name']) { + + case '{' . Plugin::NS_CALENDARSERVER . '}set' : + $sharee = $elem['value']; + + $sumElem = '{' . Plugin::NS_CALENDARSERVER . '}summary'; + $commonName = '{' . Plugin::NS_CALENDARSERVER . '}common-name'; + + $set[] = [ + 'href' => $sharee['{DAV:}href'], + 'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null, + 'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, + 'readOnly' => !array_key_exists('{' . Plugin::NS_CALENDARSERVER . '}read-write', $sharee), + ]; + break; + + case '{' . Plugin::NS_CALENDARSERVER . '}remove' : + $remove[] = $elem['value']['{DAV:}href']; + break; + + } + } + + return new self($set, $remove); + + } + +} |