1<?php
2
3namespace Sabre\DAV\Xml\Response;
4
5use Sabre\Xml\Element;
6use Sabre\Xml\Reader;
7use Sabre\Xml\Writer;
8
9/**
10 * WebDAV MultiStatus parser
11 *
12 * This class parses the {DAV:}multistatus response, as defined in:
13 * https://tools.ietf.org/html/rfc4918#section-14.16
14 *
15 * And it also adds the {DAV:}synctoken change from:
16 * http://tools.ietf.org/html/rfc6578#section-6.4
17 *
18 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
19 * @author Evert Pot (http://evertpot.com/)
20 * @license http://sabre.io/license/ Modified BSD License
21 */
22class MultiStatus implements Element {
23
24    /**
25     * The responses
26     *
27     * @var \Sabre\DAV\Xml\Element\Response[]
28     */
29    protected $responses;
30
31    /**
32     * A sync token (from RFC6578).
33     *
34     * @var string
35     */
36    protected $syncToken;
37
38    /**
39     * Constructor
40     *
41     * @param \Sabre\DAV\Xml\Element\Response[] $responses
42     * @param string $syncToken
43     */
44    function __construct(array $responses, $syncToken = null) {
45
46        $this->responses = $responses;
47        $this->syncToken = $syncToken;
48
49    }
50
51    /**
52     * Returns the response list.
53     *
54     * @return \Sabre\DAV\Xml\Element\Response[]
55     */
56    function getResponses() {
57
58        return $this->responses;
59
60    }
61
62    /**
63     * Returns the sync-token, if available.
64     *
65     * @return string|null
66     */
67    function getSyncToken() {
68
69        return $this->syncToken;
70
71    }
72
73    /**
74     * The serialize method is called during xml writing.
75     *
76     * It should use the $writer argument to encode this object into XML.
77     *
78     * Important note: it is not needed to create the parent element. The
79     * parent element is already created, and we only have to worry about
80     * attributes, child elements and text (if any).
81     *
82     * Important note 2: If you are writing any new elements, you are also
83     * responsible for closing them.
84     *
85     * @param Writer $writer
86     * @return void
87     */
88    function xmlSerialize(Writer $writer) {
89
90        foreach ($this->getResponses() as $response) {
91            $writer->writeElement('{DAV:}response', $response);
92        }
93        if ($syncToken = $this->getSyncToken()) {
94            $writer->writeElement('{DAV:}sync-token', $syncToken);
95        }
96
97    }
98
99    /**
100     * The deserialize method is called during xml parsing.
101     *
102     * This method is called statically, this is because in theory this method
103     * may be used as a type of constructor, or factory method.
104     *
105     * Often you want to return an instance of the current class, but you are
106     * free to return other data as well.
107     *
108     * You are responsible for advancing the reader to the next element. Not
109     * doing anything will result in a never-ending loop.
110     *
111     * If you just want to skip parsing for this element altogether, you can
112     * just call $reader->next();
113     *
114     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
115     * the next element.
116     *
117     * @param Reader $reader
118     * @return mixed
119     */
120    static function xmlDeserialize(Reader $reader) {
121
122        $elementMap = $reader->elementMap;
123        $elementMap['{DAV:}prop'] = 'Sabre\\DAV\\Xml\\Element\\Prop';
124        $elements = $reader->parseInnerTree($elementMap);
125
126        $responses = [];
127        $syncToken = null;
128
129        if ($elements) foreach ($elements as $elem) {
130            if ($elem['name'] === '{DAV:}response') {
131                $responses[] = $elem['value'];
132            }
133            if ($elem['name'] === '{DAV:}sync-token') {
134                $syncToken = $elem['value'];
135            }
136        }
137
138        return new self($responses, $syncToken);
139
140    }
141
142}
143