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