1<?php
2
3namespace Sabre\VObject;
4
5use Sabre\Xml;
6
7/**
8 * A node is the root class for every element in an iCalendar of vCard object.
9 *
10 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
11 * @author Evert Pot (http://evertpot.com/)
12 * @license http://sabre.io/license/ Modified BSD License
13 */
14abstract class Node
15    implements \IteratorAggregate,
16               \ArrayAccess,
17               \Countable,
18               \JsonSerializable,
19               Xml\XmlSerializable {
20
21    /**
22     * The following constants are used by the validate() method.
23     *
24     * If REPAIR is set, the validator will attempt to repair any broken data
25     * (if possible).
26     */
27    const REPAIR = 1;
28
29    /**
30     * If this option is set, the validator will operate on the vcards on the
31     * assumption that the vcards need to be valid for CardDAV.
32     *
33     * This means for example that the UID is required, whereas it is not for
34     * regular vcards.
35     */
36    const PROFILE_CARDDAV = 2;
37
38    /**
39     * If this option is set, the validator will operate on iCalendar objects
40     * on the assumption that the vcards need to be valid for CalDAV.
41     *
42     * This means for example that calendars can only contain objects with
43     * identical component types and UIDs.
44     */
45    const PROFILE_CALDAV = 4;
46
47    /**
48     * Reference to the parent object, if this is not the top object.
49     *
50     * @var Node
51     */
52    public $parent;
53
54    /**
55     * Iterator override.
56     *
57     * @var ElementList
58     */
59    protected $iterator = null;
60
61    /**
62     * The root document.
63     *
64     * @var Component
65     */
66    protected $root;
67
68    /**
69     * Serializes the node into a mimedir format.
70     *
71     * @return string
72     */
73    abstract function serialize();
74
75    /**
76     * This method returns an array, with the representation as it should be
77     * encoded in JSON. This is used to create jCard or jCal documents.
78     *
79     * @return array
80     */
81    abstract function jsonSerialize();
82
83    /**
84     * This method serializes the data into XML. This is used to create xCard or
85     * xCal documents.
86     *
87     * @param Xml\Writer $writer  XML writer.
88     *
89     * @return void
90     */
91    abstract function xmlSerialize(Xml\Writer $writer);
92
93    /**
94     * Call this method on a document if you're done using it.
95     *
96     * It's intended to remove all circular references, so PHP can easily clean
97     * it up.
98     *
99     * @return void
100     */
101    function destroy() {
102
103        $this->parent = null;
104        $this->root = null;
105
106    }
107
108    /* {{{ IteratorAggregator interface */
109
110    /**
111     * Returns the iterator for this object.
112     *
113     * @return ElementList
114     */
115    function getIterator() {
116
117        if (!is_null($this->iterator)) {
118            return $this->iterator;
119        }
120
121        return new ElementList([$this]);
122
123    }
124
125    /**
126     * Sets the overridden iterator.
127     *
128     * Note that this is not actually part of the iterator interface
129     *
130     * @param ElementList $iterator
131     *
132     * @return void
133     */
134    function setIterator(ElementList $iterator) {
135
136        $this->iterator = $iterator;
137
138    }
139
140    /**
141     * Validates the node for correctness.
142     *
143     * The following options are supported:
144     *   Node::REPAIR - May attempt to automatically repair the problem.
145     *
146     * This method returns an array with detected problems.
147     * Every element has the following properties:
148     *
149     *  * level - problem level.
150     *  * message - A human-readable string describing the issue.
151     *  * node - A reference to the problematic node.
152     *
153     * The level means:
154     *   1 - The issue was repaired (only happens if REPAIR was turned on)
155     *   2 - An inconsequential issue
156     *   3 - A severe issue.
157     *
158     * @param int $options
159     *
160     * @return array
161     */
162    function validate($options = 0) {
163
164        return [];
165
166    }
167
168    /* }}} */
169
170    /* {{{ Countable interface */
171
172    /**
173     * Returns the number of elements.
174     *
175     * @return int
176     */
177    function count() {
178
179        $it = $this->getIterator();
180        return $it->count();
181
182    }
183
184    /* }}} */
185
186    /* {{{ ArrayAccess Interface */
187
188
189    /**
190     * Checks if an item exists through ArrayAccess.
191     *
192     * This method just forwards the request to the inner iterator
193     *
194     * @param int $offset
195     *
196     * @return bool
197     */
198    function offsetExists($offset) {
199
200        $iterator = $this->getIterator();
201        return $iterator->offsetExists($offset);
202
203    }
204
205    /**
206     * Gets an item through ArrayAccess.
207     *
208     * This method just forwards the request to the inner iterator
209     *
210     * @param int $offset
211     *
212     * @return mixed
213     */
214    function offsetGet($offset) {
215
216        $iterator = $this->getIterator();
217        return $iterator->offsetGet($offset);
218
219    }
220
221    /**
222     * Sets an item through ArrayAccess.
223     *
224     * This method just forwards the request to the inner iterator
225     *
226     * @param int $offset
227     * @param mixed $value
228     *
229     * @return void
230     */
231    function offsetSet($offset, $value) {
232
233        $iterator = $this->getIterator();
234        $iterator->offsetSet($offset, $value);
235
236    // @codeCoverageIgnoreStart
237    //
238    // This method always throws an exception, so we ignore the closing
239    // brace
240    }
241    // @codeCoverageIgnoreEnd
242
243    /**
244     * Sets an item through ArrayAccess.
245     *
246     * This method just forwards the request to the inner iterator
247     *
248     * @param int $offset
249     *
250     * @return void
251     */
252    function offsetUnset($offset) {
253
254        $iterator = $this->getIterator();
255        $iterator->offsetUnset($offset);
256
257    // @codeCoverageIgnoreStart
258    //
259    // This method always throws an exception, so we ignore the closing
260    // brace
261    }
262    // @codeCoverageIgnoreEnd
263
264    /* }}} */
265}
266