284 lines
5.4 KiB
PHP
Executable File
284 lines
5.4 KiB
PHP
Executable File
<?php
|
|
|
|
abstract class Entity {
|
|
|
|
protected static
|
|
$type,
|
|
$subType,
|
|
$rootType,
|
|
$parentType,
|
|
$cache = array(),
|
|
$entities = array();
|
|
|
|
final public static function getType ( $root = false ) {
|
|
|
|
if ( !empty(static::$type) )
|
|
return static::$type;
|
|
|
|
$class = static::getSubType();
|
|
|
|
return static::$type =
|
|
( $parent = get_parent_class($class) ) && ( __CLASS__ !== $parent ) ?
|
|
$parent::getType() :
|
|
$class;
|
|
|
|
}
|
|
|
|
final public static function getSubType () {
|
|
|
|
if ( static::$subType )
|
|
return static::$subType;
|
|
|
|
$class = get_called_class();
|
|
|
|
if ( $class === __CLASS__ )
|
|
throw new Exception('Cannot call static method on Entity !');
|
|
|
|
return static::$subType = $class;
|
|
|
|
}
|
|
|
|
final public static function getParentType ( $root = false ) {
|
|
|
|
if ( !$root )
|
|
return static::$parentType;
|
|
|
|
elseif ( static::$rootType )
|
|
return static::$rootType;
|
|
|
|
return static::$rootType =
|
|
( $parent = static::$parentType ) ?
|
|
$parent::getParentType($root) :
|
|
static::getSubType();
|
|
|
|
}
|
|
|
|
final public static function getEntityData ( $id ) {
|
|
|
|
return static::getEntity($id)->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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|