1<?php
2
3namespace Sabre\DAV\Xml\Request;
4
5use Sabre\Xml\Reader;
6use Sabre\Xml\XmlDeserializable;
7use Sabre\Xml\Element\KeyValue;
8use Sabre\DAV\Exception\BadRequest;
9
10/**
11 * SyncCollection request parser.
12 *
13 * This class parses the {DAV:}sync-collection reprot, as defined in:
14 *
15 * http://tools.ietf.org/html/rfc6578#section-3.2
16 *
17 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
18 * @author Evert Pot (http://www.rooftopsolutions.nl/)
19 * @license http://sabre.io/license/ Modified BSD License
20 */
21class SyncCollectionReport implements XmlDeserializable {
22
23    /**
24     * The sync-token the client supplied for the report.
25     *
26     * @var string|null
27     */
28    public $syncToken;
29
30    /**
31     * The 'depth' of the sync the client is interested in.
32     *
33     * @var int
34     */
35    public $syncLevel;
36
37    /**
38     * Maximum amount of items returned.
39     *
40     * @var int|null
41     */
42    public $limit;
43
44    /**
45     * The list of properties that are being requested for every change.
46     *
47     * @var null|array
48     */
49    public $properties;
50
51    /**
52     * The deserialize method is called during xml parsing.
53     *
54     * This method is called statictly, this is because in theory this method
55     * may be used as a type of constructor, or factory method.
56     *
57     * Often you want to return an instance of the current class, but you are
58     * free to return other data as well.
59     *
60     * You are responsible for advancing the reader to the next element. Not
61     * doing anything will result in a never-ending loop.
62     *
63     * If you just want to skip parsing for this element altogether, you can
64     * just call $reader->next();
65     *
66     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
67     * the next element.
68     *
69     * @param Reader $reader
70     * @return mixed
71     */
72    static function xmlDeserialize(Reader $reader) {
73
74        $self = new self();
75
76        $reader->pushContext();
77
78        $reader->elementMap['{DAV:}prop']   = 'Sabre\Xml\Element\Elements';
79        $elems = KeyValue::xmlDeserialize($reader);
80
81        $reader->popContext();
82
83        $required = [
84            '{DAV:}sync-token',
85            '{DAV:}prop',
86            ];
87
88        foreach ($required as $elem) {
89            if (!array_key_exists($elem, $elems)) {
90                throw new BadRequest('The ' . $elem . ' element in the {DAV:}sync-collection report is required');
91            }
92        }
93
94
95        $self->properties = $elems['{DAV:}prop'];
96        $self->syncToken = $elems['{DAV:}sync-token'];
97
98        if (isset($elems['{DAV:}limit'])) {
99            $nresults = null;
100            foreach ($elems['{DAV:}limit'] as $child) {
101                if ($child['name'] === '{DAV:}nresults') {
102                    $nresults = (int)$child['value'];
103                }
104            }
105            $self->limit = $nresults;
106        }
107
108        if (isset($elems['{DAV:}sync-level'])) {
109
110            $value = $elems['{DAV:}sync-level'];
111            if ($value === 'infinity') {
112                $value = \Sabre\DAV\Server::DEPTH_INFINITY;
113            }
114            $self->syncLevel = $value;
115
116        }
117
118        return $self;
119
120    }
121
122}
123