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