getData(); } final public static function getEntity ( $id ) { if ( !empty(self::$entities[$id]) ) return self::$entities[$id]; $path = explode(':', $id); $type = $path[0]; return $type::get($path[1]); } final public static function get ( $fullName ) { $ctype = static::getType(); $id = $ctype . ':' . $fullName; //~ echo sprintf( //~ '%1$s::%2$s(%3$s)' . "\n", //~ get_called_class(), //~ __METHOD__, //~ $fullName //~ ); if ( !empty(self::$entities[$id]) ) return self::$entities[$id]; if ( !( $instance = $ctype::getInstance($fullName) ) ) return null; self::$entities[$instance->getId()] = $instance; self::$entities[$instance->getId(1)] = $instance; return $instance; } protected static function getInstance ( $fullName ) { //~ echo sprintf( //~ '%1$s::%2$s(%3$s)' . "\n", //~ get_called_class(), //~ __METHOD__, //~ $fullName //~ ); $path = explode('.', $fullName); $name = array_pop($path); $type = static::getType(); $parentType = $type::getParentType(); $parent = $parentType::get(implode('.', $path)); $data = $parent->getChildrenData($type, $name); if ( !$data ) return null; $data['name'] = $name; $subType = $data['type']; if ( !$subType ) $subType = static::getSubType(); return new $subType( $data, $parent ); } protected $collections = array(), $names = array(), $ids = array(), $parent, $data, $root; protected function __construct ( $data, $parent = null ) { $this->data = $data; $this->parent = $parent; } public function __destruct () { unset(self::$entities[$this->getId()]); unset(self::$entities[$this->getId(1)]); foreach ( $this->data as $k => $v ) unset($this->data[$k]); } final public function __get ( $type ) { $type = $type::getType(); if ( !empty($this->collections[$type]) ) return $this->collections[$type]; return $this->collections[$type] = new ChildrenTypeEntityIteratorAggregate($this, $type); } final public function __toString () { return $this->getId(1); } final public function getName ( $full = false ) { if ( !empty($this->names[$full]) ) return $this->names[$full]; if ( empty($this->data['name'])) print_r($this); return $this->names[$full] = ( $full && ( $parent = $this->getParent() ) ? $parent->getName(1) . '.' : '' ) . $this->data['name']; } final public function getId ( $canonical = false ) { if ( !empty($this->ids[$canonical]) ) return $this->ids[$canonical]; return $this->ids[$canonical] = sprintf( '%1$s:%2$s', $canonical ? static::getType() : static::getSubType(), $this->getName(true) ); } final public function getData ( $offset = null ) { if ( $offset && array_key_exists($offset, $this->data) ) return $this->data[$offset]; elseif ( $offset ) return null; return $this->data; } final public function getParent ( $root = false ) { if ( !$root ) return $this->parent; elseif ( $this->root ) return $this->root; return $this->root = $this->parent ? $this->parent->getParent(1) : $this; } final public function getChild ( $type, $name ) { return $type::get($this->getName(1) . '.' . $name); } final public function getChildrenData ( $type = null, $name = null ) { //~ echo sprintf( //~ '%1$s::%2$s(%3$s, %4$s)' . "\n", //~ get_called_class(), //~ __METHOD__, //~ $type, //~ $name //~ ); if ( !$type ) return !empty($this->data['children']) ? $this->data['children'] : null; elseif ( $name && !empty($this->data['children'][$type][$name]) ) return $this->data['children'][$type][$name]; elseif ( $name ) return null; return !empty($this->data['children'][$type]) ? $this->data['children'][$type] : array(); } final protected function setCache ( $offset, $value ) { self::$cache[$this->getId(1)][$offset] = $value; return $this; } final protected function getCache ( $offset ) { return self::$cache[$this->getId(1)][$offset]; } final public function getChildrenIterator () { return new ChildrenEntityIterator($this); } final public function getParentIterator () { return new ParenEntityIterator($this); } } ?>