1<?php
2
3namespace Sabre\DAV\Xml\Property;
4
5use Sabre\Xml\Element\XmlFragment;
6use Sabre\Xml\Reader;
7
8/**
9 * This class represents a 'complex' property that didn't have a default
10 * decoder.
11 *
12 * It's basically a container for an xml snippet.
13 *
14 * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/)
15 * @author Evert Pot (http://evertpot.com/)
16 * @license http://sabre.io/license/ Modified BSD License
17 */
18class Complex extends XmlFragment {
19
20    /**
21     * The deserialize method is called during xml parsing.
22     *
23     * This method is called statictly, this is because in theory this method
24     * may be used as a type of constructor, or factory method.
25     *
26     * Often you want to return an instance of the current class, but you are
27     * free to return other data as well.
28     *
29     * You are responsible for advancing the reader to the next element. Not
30     * doing anything will result in a never-ending loop.
31     *
32     * If you just want to skip parsing for this element altogether, you can
33     * just call $reader->next();
34     *
35     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
36     * the next element.
37     *
38     * @param Reader $reader
39     * @return mixed
40     */
41    static function xmlDeserialize(Reader $reader) {
42
43        $xml = $reader->readInnerXml();
44
45        if ($reader->nodeType === Reader::ELEMENT && $reader->isEmptyElement) {
46            // Easy!
47            $reader->next();
48            return null;
49        }
50        // Now we have a copy of the inner xml, we need to traverse it to get
51        // all the strings. If there's no non-string data, we just return the
52        // string, otherwise we return an instance of this class.
53        $reader->read();
54
55        $nonText = false;
56        $text = '';
57
58        while (true) {
59
60            switch ($reader->nodeType) {
61                case Reader::ELEMENT :
62                    $nonText = true;
63                    $reader->next();
64                    continue 2;
65                case Reader::TEXT :
66                case Reader::CDATA :
67                    $text .= $reader->value;
68                    break;
69                case Reader::END_ELEMENT :
70                    break 2;
71            }
72            $reader->read();
73
74        }
75
76        // Make sure we advance the cursor one step further.
77        $reader->read();
78
79        if ($nonText) {
80            $new = new self($xml);
81            return $new;
82        } else {
83            return $text;
84        }
85
86    }
87
88
89}
90