1<?php 2 3namespace Sabre\CalDAV\Xml\Request; 4 5use Sabre\CalDAV\Plugin; 6use Sabre\DAV\Exception\BadRequest; 7use Sabre\Xml\Reader; 8use Sabre\Xml\XmlDeserializable; 9 10/** 11 * CalendarQueryReport request parser. 12 * 13 * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-query 14 * REPORT, as defined in: 15 * 16 * https://tools.ietf.org/html/rfc4791#section-7.9 17 * 18 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 19 * @author Evert Pot (http://www.rooftopsolutions.nl/) 20 * @license http://sabre.io/license/ Modified BSD License 21 */ 22class CalendarQueryReport implements XmlDeserializable { 23 24 /** 25 * An array with requested properties. 26 * 27 * @var array 28 */ 29 public $properties; 30 31 /** 32 * List of property/component filters. 33 * 34 * @var array 35 */ 36 public $filters; 37 38 /** 39 * If the calendar data must be expanded, this will contain an array with 2 40 * elements: start and end. 41 * 42 * Each may be a DateTime or null. 43 * 44 * @var array|null 45 */ 46 public $expand = null; 47 48 /** 49 * The mimetype of the content that should be returend. Usually 50 * text/calendar. 51 * 52 * @var string 53 */ 54 public $contentType = null; 55 56 /** 57 * The version of calendar-data that should be returned. Usually '2.0', 58 * referring to iCalendar 2.0. 59 * 60 * @var string 61 */ 62 public $version = null; 63 64 /** 65 * The deserialize method is called during xml parsing. 66 * 67 * This method is called statically, this is because in theory this method 68 * may be used as a type of constructor, or factory method. 69 * 70 * Often you want to return an instance of the current class, but you are 71 * free to return other data as well. 72 * 73 * You are responsible for advancing the reader to the next element. Not 74 * doing anything will result in a never-ending loop. 75 * 76 * If you just want to skip parsing for this element altogether, you can 77 * just call $reader->next(); 78 * 79 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to 80 * the next element. 81 * 82 * @param Reader $reader 83 * @return mixed 84 */ 85 static function xmlDeserialize(Reader $reader) { 86 87 $elems = $reader->parseInnerTree([ 88 '{urn:ietf:params:xml:ns:caldav}comp-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter', 89 '{urn:ietf:params:xml:ns:caldav}prop-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter', 90 '{urn:ietf:params:xml:ns:caldav}param-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter', 91 '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', 92 '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', 93 ]); 94 95 $newProps = [ 96 'filters' => null, 97 'properties' => [], 98 ]; 99 100 if (!is_array($elems)) $elems = []; 101 102 foreach ($elems as $elem) { 103 104 switch ($elem['name']) { 105 106 case '{DAV:}prop' : 107 $newProps['properties'] = array_keys($elem['value']); 108 if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) { 109 $newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']; 110 } 111 break; 112 case '{' . Plugin::NS_CALDAV . '}filter' : 113 foreach ($elem['value'] as $subElem) { 114 if ($subElem['name'] === '{' . Plugin::NS_CALDAV . '}comp-filter') { 115 if (!is_null($newProps['filters'])) { 116 throw new BadRequest('Only one top-level comp-filter may be defined'); 117 } 118 $newProps['filters'] = $subElem['value']; 119 } 120 } 121 break; 122 123 } 124 125 } 126 127 if (is_null($newProps['filters'])) { 128 throw new BadRequest('The {' . Plugin::NS_CALDAV . '}filter element is required for this request'); 129 } 130 131 $obj = new self(); 132 foreach ($newProps as $key => $value) { 133 $obj->$key = $value; 134 } 135 return $obj; 136 137 } 138 139} 140