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