Hoa central
Concrete.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Xml\Element;
38 
39 use Hoa\Xml;
40 
49 class Concrete implements Element, \Countable, \IteratorAggregate, \ArrayAccess
50 {
56  protected static $_store = [];
57 
63  protected static $_superRoots = [];
64 
70  protected static $_multiton = [];
71 
77  protected $_name = null;
78 
84  protected $_children = [];
85 
91  protected $_iterator = [];
92 
98  protected $abstract = null;
99 
105  protected $_superRoot = null;
106 
107 
108 
119  final public function __construct(
121  Element $superRoot,
122  Array $rank = [],
123  $namespace = null
124  ) {
125  self::$_store[] = $abstract;
126  self::$_superRoots[] = $superRoot;
127  self::$_multiton[] = $this;
128 
129  if (null !== $namespace) {
130  $abstract->useNamespace($namespace);
131  }
132 
133  if (null === $this->_name) {
134  $this->_name = strtolower(get_class($this));
135 
136  if (false !== $po = strrpos($this->_name, '\\')) {
137  $this->_name = substr($this->_name, $po + 1);
138  }
139  }
140 
141  $this->abstract = $abstract;
142  $this->_superRoot = $superRoot;
143 
144  if ($this instanceof Model\Phrasing) {
145  $iterator = $abstract->readAsPhrasingModel($namespace);
146  } else {
147  $iterator = $abstract->selectChildElements();
148  }
149 
150  foreach ($iterator as $child) {
151  $name = $child->getName();
152 
153  if (!isset($rank[$name])) {
154  throw new Xml\Exception(
155  'Cannot build the concrete tree because the abstract ' .
156  'element <%s> has no ranked concrete element.',
157  0,
158  $name
159  );
160  }
161 
162  $c = $rank[$name];
163  $h = new $c($child, $superRoot, $rank, $namespace);
164 
165  $this->_children[$h->getName()][] = $h;
166  $this->_iterator[] = $h;
167  }
168 
169  $this->construct();
170 
171  return;
172  }
173 
179  public function construct()
180  {
181  return;
182  }
183 
190  public static function getAbstractElementId(Element $element)
191  {
192  return array_search($element, self::$_store);
193  }
194 
200  public function getAbstractElement()
201  {
202  return $this->abstract;
203  }
204 
212  public static function getConcreteElement(Element $element)
213  {
214  if (false === $id = self::getAbstractElementId($element)) {
215  throw new Xml\Exception(
216  'The basic element %s has no concrete equivalent.',
217  1,
218  $element->getName()
219  );
220  }
221 
222  return self::$_multiton[$id];
223  }
224 
230  public function getAbstractElementSuperRoot()
231  {
232  return $this->_superRoot;
233  }
234 
242  public static function getAbstractElementSuperRootOf(Element $element)
243  {
244  if (false === $id = self::getAbstractElementId($element)) {
245  throw new Xml\Exception(
246  'The concrete element %s has no concrete equivalent and we ' .
247  'cannot retrieve the super-root.',
248  2,
249  $element->getName()
250  );
251  }
252 
253  return self::$_superRoots[$id];
254  }
255 
261  public function getName()
262  {
263  return $this->_name;
264  }
265 
271  public function count()
272  {
273  return count($this->_iterator);
274  }
275 
281  public function getIterator()
282  {
283  return new \ArrayIterator($this->_iterator);
284  }
285 
293  public function __set($name, Concrete $value)
294  {
295  $this->_children[$name][] = $value;
296  $this->_iterator[] = $value;
297 
298  return;
299  }
300 
307  public function __get($name)
308  {
309  if (!isset($this->_children[$name])) {
310  return null;
311  }
312 
313  return $this->_children[$name];
314  }
315 
322  public function offsetExists($offset)
323  {
324  return isset($this->_iterator[$offset]);
325  }
326 
333  public function offsetGet($offset)
334  {
335  if (false === $this->offsetExists($offset)) {
336  return null;
337  }
338 
339  return $this->_iterator[$offset];
340  }
341 
349  public function offsetSet($offset, $element)
350  {
351  if (is_string($element)) {
352  $name = $element;
353  } else {
354  $name = $element->getName();
355  }
356 
357  if (!isset($this->_children[$name])) {
358  $this->_children[$name] = [];
359  }
360 
361  $this->_children[$name][$offset] = $element;
362  $this->_iterator[$offset] = $element;
363 
364  return;
365  }
366 
373  public function offsetUnset($offset)
374  {
375  if (!isset($this->_iterator[$offset])) {
376  return;
377  }
378 
379  $element = $this->_iterator[$offset];
380  $name = $element->getName();
381  $i = array_search($element, $this->_children[$name]);
382 
383  unset($this->_children[$name][$i]);
384  unset($this->_iterator[$offset]);
385 
386  return;
387  }
388 
396  public function __call($name, Array $arguments = [])
397  {
398  return call_user_func_array(
399  [$this->abstract, $name],
400  $arguments
401  );
402  }
403 }
__construct(Element $abstract, Element $superRoot, Array $rank=[], $namespace=null)
Definition: Concrete.php:119
static getAbstractElementSuperRootOf(Element $element)
Definition: Concrete.php:242
static getAbstractElementId(Element $element)
Definition: Concrete.php:190
__set($name, Concrete $value)
Definition: Concrete.php:293
static getConcreteElement(Element $element)
Definition: Concrete.php:212
__call($name, Array $arguments=[])
Definition: Concrete.php:396
offsetSet($offset, $element)
Definition: Concrete.php:349