1<?php
2
3namespace Sabre\CalDAV\Xml\Filter;
4
5use Sabre\Xml\Reader;
6use Sabre\Xml\XmlDeserializable;
7use Sabre\DAV\Exception\BadRequest;
8use Sabre\CalDAV\Plugin;
9use Sabre\VObject\DateTimeParser;
10
11/**
12 * CalendarData parser.
13 *
14 * This class parses the {urn:ietf:params:xml:ns:caldav}calendar-data XML
15 * element, as defined in:
16 *
17 * https://tools.ietf.org/html/rfc4791#section-9.6
18 *
19 * This element is used in three distinct places in the caldav spec, but in
20 * this case, this element class only implements the calendar-data element as
21 * it appears in a DAV:prop element, in a calendar-query or calendar-multiget
22 * REPORT request.
23 *
24 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
25 * @author Evert Pot (http://www.rooftopsolutions.nl/)
26 * @license http://sabre.io/license/ Modified BSD License
27 */
28class CalendarData implements XmlDeserializable {
29
30    /**
31     * The deserialize method is called during xml parsing.
32     *
33     * This method is called statictly, this is because in theory this method
34     * may be used as a type of constructor, or factory method.
35     *
36     * Often you want to return an instance of the current class, but you are
37     * free to return other data as well.
38     *
39     * You are responsible for advancing the reader to the next element. Not
40     * doing anything will result in a never-ending loop.
41     *
42     * If you just want to skip parsing for this element altogether, you can
43     * just call $reader->next();
44     *
45     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
46     * the next element.
47     *
48     * @param Reader $reader
49     * @return mixed
50     */
51    static function xmlDeserialize(Reader $reader) {
52
53        $result = [
54            'contentType' => $reader->getAttribute('content-type') ?: 'text/calendar',
55            'version'     => $reader->getAttribute('version') ?: '2.0',
56        ];
57
58        $elems = (array)$reader->parseInnerTree();
59        foreach ($elems as $elem) {
60
61            switch ($elem['name']) {
62                case '{' . Plugin::NS_CALDAV . '}expand' :
63
64                    $result['expand'] = [
65                        'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null,
66                        'end'   => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null,
67                    ];
68
69                    if (!$result['expand']['start'] || !$result['expand']['end']) {
70                        throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data');
71                    }
72                    if ($result['expand']['end'] <= $result['expand']['start']) {
73                        throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data');
74                    }
75                    break;
76            }
77
78        }
79
80        return $result;
81
82    }
83
84}
85