xref: /plugin/davcal/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAV\Xml\Element;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV\Xml\Property\Complex;
6*a1a3b679SAndreas Boehleruse Sabre\Xml\XmlDeserializable;
7*a1a3b679SAndreas Boehleruse Sabre\Xml\Reader;
8*a1a3b679SAndreas Boehler
9*a1a3b679SAndreas Boehler/**
10*a1a3b679SAndreas Boehler * This class is responsible for decoding the {DAV:}prop element as it appears
11*a1a3b679SAndreas Boehler * in {DAV:}property-update.
12*a1a3b679SAndreas Boehler *
13*a1a3b679SAndreas Boehler * This class doesn't return an instance of itself. It just returns a
14*a1a3b679SAndreas Boehler * key->value array.
15*a1a3b679SAndreas Boehler *
16*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/)
17*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/)
18*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License
19*a1a3b679SAndreas Boehler */
20*a1a3b679SAndreas Boehlerclass Prop implements XmlDeserializable {
21*a1a3b679SAndreas Boehler
22*a1a3b679SAndreas Boehler    /**
23*a1a3b679SAndreas Boehler     * The deserialize method is called during xml parsing.
24*a1a3b679SAndreas Boehler     *
25*a1a3b679SAndreas Boehler     * This method is called statictly, this is because in theory this method
26*a1a3b679SAndreas Boehler     * may be used as a type of constructor, or factory method.
27*a1a3b679SAndreas Boehler     *
28*a1a3b679SAndreas Boehler     * Often you want to return an instance of the current class, but you are
29*a1a3b679SAndreas Boehler     * free to return other data as well.
30*a1a3b679SAndreas Boehler     *
31*a1a3b679SAndreas Boehler     * You are responsible for advancing the reader to the next element. Not
32*a1a3b679SAndreas Boehler     * doing anything will result in a never-ending loop.
33*a1a3b679SAndreas Boehler     *
34*a1a3b679SAndreas Boehler     * If you just want to skip parsing for this element altogether, you can
35*a1a3b679SAndreas Boehler     * just call $reader->next();
36*a1a3b679SAndreas Boehler     *
37*a1a3b679SAndreas Boehler     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
38*a1a3b679SAndreas Boehler     * the next element.
39*a1a3b679SAndreas Boehler     *
40*a1a3b679SAndreas Boehler     * @param Reader $reader
41*a1a3b679SAndreas Boehler     * @return mixed
42*a1a3b679SAndreas Boehler     */
43*a1a3b679SAndreas Boehler    static function xmlDeserialize(Reader $reader) {
44*a1a3b679SAndreas Boehler
45*a1a3b679SAndreas Boehler        // If there's no children, we don't do anything.
46*a1a3b679SAndreas Boehler        if ($reader->isEmptyElement) {
47*a1a3b679SAndreas Boehler            $reader->next();
48*a1a3b679SAndreas Boehler            return [];
49*a1a3b679SAndreas Boehler        }
50*a1a3b679SAndreas Boehler
51*a1a3b679SAndreas Boehler        $values = [];
52*a1a3b679SAndreas Boehler
53*a1a3b679SAndreas Boehler        $reader->read();
54*a1a3b679SAndreas Boehler        do {
55*a1a3b679SAndreas Boehler
56*a1a3b679SAndreas Boehler            if ($reader->nodeType === Reader::ELEMENT) {
57*a1a3b679SAndreas Boehler
58*a1a3b679SAndreas Boehler                $clark = $reader->getClark();
59*a1a3b679SAndreas Boehler                $values[$clark] = self::parseCurrentElement($reader)['value'];
60*a1a3b679SAndreas Boehler
61*a1a3b679SAndreas Boehler            } else {
62*a1a3b679SAndreas Boehler                $reader->read();
63*a1a3b679SAndreas Boehler            }
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler        } while ($reader->nodeType !== Reader::END_ELEMENT);
66*a1a3b679SAndreas Boehler
67*a1a3b679SAndreas Boehler        $reader->read();
68*a1a3b679SAndreas Boehler
69*a1a3b679SAndreas Boehler        return $values;
70*a1a3b679SAndreas Boehler
71*a1a3b679SAndreas Boehler    }
72*a1a3b679SAndreas Boehler
73*a1a3b679SAndreas Boehler    /**
74*a1a3b679SAndreas Boehler     * This function behaves similar to Sabre\Xml\Reader::parseCurrentElement,
75*a1a3b679SAndreas Boehler     * but instead of creating deep xml array structures, it will turn any
76*a1a3b679SAndreas Boehler     * top-level element it doesn't recognize into either a string, or an
77*a1a3b679SAndreas Boehler     * XmlFragment class.
78*a1a3b679SAndreas Boehler     *
79*a1a3b679SAndreas Boehler     * This method returns arn array with 2 properties:
80*a1a3b679SAndreas Boehler     *   * name - A clark-notation XML element name.
81*a1a3b679SAndreas Boehler     *   * value - The parsed value.
82*a1a3b679SAndreas Boehler     *
83*a1a3b679SAndreas Boehler     * @param Reader $reader
84*a1a3b679SAndreas Boehler     * @return array
85*a1a3b679SAndreas Boehler     */
86*a1a3b679SAndreas Boehler    private static function parseCurrentElement(Reader $reader) {
87*a1a3b679SAndreas Boehler
88*a1a3b679SAndreas Boehler        $name = $reader->getClark();
89*a1a3b679SAndreas Boehler
90*a1a3b679SAndreas Boehler        if (array_key_exists($name, $reader->elementMap)) {
91*a1a3b679SAndreas Boehler            $deserializer = $reader->elementMap[$name];
92*a1a3b679SAndreas Boehler            if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) {
93*a1a3b679SAndreas Boehler                $value = call_user_func([ $deserializer, 'xmlDeserialize' ], $reader);
94*a1a3b679SAndreas Boehler            } elseif (is_callable($deserializer)) {
95*a1a3b679SAndreas Boehler                $value = call_user_func($deserializer, $reader);
96*a1a3b679SAndreas Boehler            } else {
97*a1a3b679SAndreas Boehler                $type = gettype($deserializer);
98*a1a3b679SAndreas Boehler                if ($type === 'string') {
99*a1a3b679SAndreas Boehler                    $type .= ' (' . $deserializer . ')';
100*a1a3b679SAndreas Boehler                } elseif ($type === 'object') {
101*a1a3b679SAndreas Boehler                    $type .= ' (' . get_class($deserializer) . ')';
102*a1a3b679SAndreas Boehler                }
103*a1a3b679SAndreas Boehler                throw new \LogicException('Could not use this type as a deserializer: ' . $type);
104*a1a3b679SAndreas Boehler            }
105*a1a3b679SAndreas Boehler        } else {
106*a1a3b679SAndreas Boehler            $value = Complex::xmlDeserialize($reader);
107*a1a3b679SAndreas Boehler        }
108*a1a3b679SAndreas Boehler
109*a1a3b679SAndreas Boehler        return [
110*a1a3b679SAndreas Boehler            'name'  => $name,
111*a1a3b679SAndreas Boehler            'value' => $value,
112*a1a3b679SAndreas Boehler        ];
113*a1a3b679SAndreas Boehler
114*a1a3b679SAndreas Boehler    }
115*a1a3b679SAndreas Boehler
116*a1a3b679SAndreas Boehler}
117