1<?php
2
3namespace Sabre\CalDAV\Xml\Property;
4
5use Sabre\Xml\Element;
6use Sabre\Xml\ParseException;
7use Sabre\Xml\Reader;
8use Sabre\Xml\Writer;
9use Sabre\CalDAV\Plugin;
10
11/**
12 * SupportedCalendarComponentSet property.
13 *
14 * This class represents the
15 * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set property, as
16 * defined in:
17 *
18 * https://tools.ietf.org/html/rfc4791#section-5.2.3
19 *
20 * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
21 * @author Evert Pot (http://evertpot.com/)
22 * @license http://sabre.io/license/ Modified BSD License
23 */
24class SupportedCalendarComponentSet implements Element {
25
26    /**
27     * List of supported components.
28     *
29     * This array will contain values such as VEVENT, VTODO and VJOURNAL.
30     *
31     * @var array
32     */
33    protected $components = [];
34
35    /**
36     * Creates the property.
37     *
38     * @param array $components
39     */
40    function __construct(array $components) {
41
42        $this->components = $components;
43
44    }
45
46    /**
47     * Returns the list of supported components
48     *
49     * @return array
50     */
51    function getValue() {
52
53        return $this->components;
54
55    }
56
57    /**
58     * The xmlSerialize metod is called during xml writing.
59     *
60     * Use the $writer argument to write its own xml serialization.
61     *
62     * An important note: do _not_ create a parent element. Any element
63     * implementing XmlSerializble should only ever write what's considered
64     * its 'inner xml'.
65     *
66     * The parent of the current element is responsible for writing a
67     * containing element.
68     *
69     * This allows serializers to be re-used for different element names.
70     *
71     * If you are opening new elements, you must also close them again.
72     *
73     * @param Writer $writer
74     * @return void
75     */
76    function xmlSerialize(Writer $writer) {
77
78        foreach ($this->components as $component) {
79
80            $writer->startElement('{' . Plugin::NS_CALDAV . '}comp');
81            $writer->writeAttributes(['name' => $component]);
82            $writer->endElement();
83
84        }
85
86    }
87
88    /**
89     * The deserialize method is called during xml parsing.
90     *
91     * This method is called statictly, this is because in theory this method
92     * may be used as a type of constructor, or factory method.
93     *
94     * Often you want to return an instance of the current class, but you are
95     * free to return other data as well.
96     *
97     * You are responsible for advancing the reader to the next element. Not
98     * doing anything will result in a never-ending loop.
99     *
100     * If you just want to skip parsing for this element altogether, you can
101     * just call $reader->next();
102     *
103     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
104     * the next element.
105     *
106     * @param Reader $reader
107     * @return mixed
108     */
109    static function xmlDeserialize(Reader $reader) {
110
111        $elems = $reader->parseInnerTree();
112
113        $components = [];
114
115        foreach ((array)$elems as $elem) {
116            if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}comp') {
117                $components[] = $elem['attributes']['name'];
118            }
119        }
120
121        if (!$components) {
122            throw new ParseException('supported-calendar-component-set must have at least one CALDAV:comp element');
123        }
124
125        return new self($components);
126
127    }
128
129}
130