Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?PHP
- NAMESPACE ILLI\Core;
- USE ILLI\Core\Object\tAdapter;
- USE ILLI\Core\Object\tFilter;
- USE ILLI\Core\Object\tInvoke;
- USE ILLI\Core\Object\tObserver;
- USE ILLI\Core\Object\tSignal;
- USE ILLI\Core\Object\tClass;
- USE ILLI\Core\Object\tTo;
- USE ILLI\Core\Object\tMethod;
- USE ILLI\Core\Object\tMethodFilter;
- USE ILLI\Core\Object\tMethodProto;
- USE ILLI\Core\iObject;
- USE ILLI\Core\Filter;
- CLASS Object IMPLEMENTS iObject
- {
- USE tMethodFilter
- {
- Core_Object_tMethodFilter_register as public applyMethodFilter;
- }
- USE tAdapter;
- USE tClass;
- USE tFilter;
- USE tMethod;
- USE tObserver;
- USE tSignal;
- USE tTo;
- USE tInvoke;
- USE tMethodProto;
- protected static $__parentClasses = [];
- protected static $__usedTraits = [];
- /**
- * used when item is not in initConfig and not in baseConfig
- * @configurable
- */
- protected $__defaultConfig = [];
- /**
- * define class-properties for env
- * @configurable
- */
- protected $__autoConfig = [];
- /**
- * property-value-pair by initConfig
- */
- protected $__env = [];
- /**
- * merged config: baseConfig + options-array from __construct
- */
- protected $__initConfig = [];
- /**
- * base config for object
- */
- private static $__baseConfig =
- [
- '__run' => TRUE, // excecute setup()
- '__main' => '__main', // onConstructEvent
- '__delegate' => NULL, // class-delegate: adapter for every method; instance or className
- '__adapter' => // trigger__FUNCTION__ => hook | trigger__FUNCTION__ => [event => hook]
- [
- //__FUNCTION__ => [] // 0 => class|instance, 1 => method | 0 => closure; overwrites methods from __delegate
- ],
- '__filter' => // trigger__FUNCTION__ => hook
- [
- //__FUNCTION__ => [] // [filter 1, filter 2, filter n ...] | [eventName => [filter 1, filter 2, filter n]]; default event is '*'
- ],
- '__proto' => // prototype defines the core of a method; default (class internal): methodname calls prototypeMethodname
- [
- //__FUNCTION__ => NULL // delegate;
- ],
- '__method' => // public virtual methods, called by __call
- [
- // name => closure
- // name => delegate
- ],
- '__observer' =>
- [
- //__FUNCTION__ => [] // event => [notify 1, notify 2, ...]
- ],
- '__signal' =>
- [
- //__FUNCTION__ => // trigger__FUNCTION__ => [event => hook]
- //[
- // 'PRE_EVENT' => [], // event => [signal 1, signal 2, ...]
- // 'POST_EVENT' => [] // event => [signal 1, signal 2, ...]
- //],
- ],
- '__class' => // class alias hook: new __class['Alias']() instead of new hardCodedClassName()
- [
- // 'ILLI\Core\Media' => 'My\Media'
- ],
- '__to' => // cast to: type => handler
- [
- 'string' => 'toString',
- 'array' => 'toArray'
- ],
- '__protoprefix' => 'prototype' // prefix for prototype-method
- ];
- public $__export = [];
- protected function __main()
- {
- }
- public static function __load()
- {
- }
- final public function __construct(array $__options = [])
- {
- $this->__initConfig = $this->extend(TRUE, self::$__baseConfig, $__options);
- if(TRUE === $this->__initConfig['__run'])
- $this->__run();
- return $this;
- }
- protected function __run()
- {
- $this->__configure();
- $class = get_called_class();
- $this->Core_Object_tMethod_install ($class, $this->__initConfig['__method']);
- $this->Core_Object_tMethodProto_install ($class, $this->__initConfig['__proto']);
- $this->Core_Object_tAdapter_install ($class, $this->__initConfig['__delegate']);
- $this->Core_Object_tAdapter_install ($class, $this->__initConfig['__adapter']);
- $this->Core_Object_tObserver_install ($class, $this->__initConfig['__observer']);
- $this->Core_Object_tSignal_install ($class, $this->__initConfig['__signal']);
- $this->Core_Object_tFilter_install ($class, $this->__initConfig['__filter']);
- $this->Core_Object_tTo_install ($class, $this->__initConfig['__to']);
- $this->Core_Object_tClass_install ($class, $this->__initConfig['__class']);
- $this->prototype('__construct', $this->__env);
- return $this;
- }
- protected function __configure()
- {
- $defaultConfig = &$this->__defaultConfig;
- $initConfig = &$this->__initConfig;
- $autoConfig = &$this->__autoConfig;
- $env = &$this->__env;
- foreach($autoConfig as $key => $flag)
- {
- // option not given. use default value
- if(!isset($initConfig[$key])
- && isset($defaultConfig[$key]))
- {
- $env[$key] = $defaultConfig[$key];
- continue;
- }
- if(!isset($initConfig[$flag])
- && isset($defaultConfig[$flag]))
- {
- $env[$flag] = $defaultConfig[$flag];
- continue;
- }
- if($flag === 'merge') // initConfig + defaultConfig
- {
- if(isset($defaultConfig[$key]))
- {
- if(is_array($initConfig[$key])
- && is_array($defaultConfig[$key]))
- {
- $env[$key] = $this->extend
- (
- TRUE,
- $initConfig[$key],
- $defaultConfig[$key]
- );
- }
- else
- {
- $env[$key] =
- $initConfig[$key]
- + $defaultConfig[$key];
- }
- }
- else
- {
- $env[$key] = $initConfig[$key];
- }
- }
- else // initConfig[${key}]
- if(isset($initConfig[$key]))
- {
- $env[$flag] = $initConfig[$flag];
- }
- else // initConfig[${flag}]
- if(isset($initConfig[$flag]))
- {
- $env[$flag] = $initConfig[$flag];
- }
- else // defaultConfig[${key}]
- if(isset($defaultConfig[$key]))
- {
- $env[$key] = $defaultConfig[$key];
- }
- else // default[${flag}]
- if(isset($defaultConfig[$flag]))
- {
- $env[$flag] = $defaultConfig[$flag];
- }
- else
- {
- $env[$flag] = NULL;
- }
- }
- // accessible as property
- foreach($env as $property => &$value)
- {
- $this->{$property} =& $value;
- // remove property from initConfig
- if(isset($initConfig[$property]))
- unset($initConfig[$property]);
- }
- return $this;
- }
- /**
- * allows you to replaace the core-function of a method without editing your class-file
- *
- * <code>
- * function myMethod()
- * {
- * // do additional stuff
- * $this->prototype('myMethod');
- * // do additional stuff
- * // return $whatever;
- * }
- * </code>
- *
- * 1. adapter-lookup
- *
- * 2.1 send signal PRE_EVENT with unfiltered parameters
- * 2.2 filter parameters
- * 2.3 run method-filters
- * 2.3.1 run outer-filters
- * 2.3.2 execute virtual method
- * 2.3.3 execute virtual proto or physical existing proto
- * 2.4 filter result
- * 2.5 observer notify with filtered result
- * 2.6 send signal POST_EVENT with filtered result
- * 2.7 return filtered result
- */
- protected function prototype($__function, $__parameters)
- {
- if(isset($__parameters['this']))
- unset($__parameters['this']);
- $class = get_called_class();
- $function = $__function;
- if(TRUE === $this->Core_Object_tAdapter_exists($class, $function))
- return $this->Core_Object_tAdapter_emit($class, $function, $__parameters);
- $this->Core_Object_tSignal_emit($class, $function, 'PRE_EVENT', $__parameters);
- $data = $this->Core_Object_tFilter_emit($class, $function, $__parameters, ['event' => 'DATA']);
- $result = $this->Core_Object_tMethodFilter_emit($class, $function, $data, function(array $__params) use ($function, $data)
- {
- $result = NULL;
- if(TRUE === $this->Core_Object_tMethod_exists($function))
- {
- $result = $__params = $this->Core_Object_tMethod_emit($function, $__params);
- }
- if(TRUE === $this->Core_Object_tMethodProto_exists($function))
- {
- $result = $this->Core_Object_tMethodProto_emit($function, $__params);
- }
- else
- {
- $proto = $function === '__construct'
- ? $this->__initConfig['__main']
- : $this->__initConfig['__protoprefix'].$function;
- if($proto === $function)
- {
- throw new \Exception('Proto is called method '.$function);
- return $__params;
- }
- if(method_exists($this, $proto))
- $result = $this->Core_Object_tInvoke_method($proto, $__params);
- }
- return $result;
- });
- $result = [$result];
- $result = $this->Core_Object_tFilter_emit($class, $function, $result, ['event' => 'RESULT']);
- $this->Core_Object_tObserver_emit($class, $function, $result);
- $this->Core_Object_tSignal_emit($class, $function, 'POST_EVENT', $result);
- return $result[0];
- }
- public static function parents($__className = NULL)
- {
- $parentClasses = &self::$__parentClasses;
- $class = NULL === $__className ? get_called_class() : $__className;
- if(isset($parentClasses[$class]))
- return $parentClasses[$class];
- $classes = [$class];
- while($class = get_parent_class($class))
- $classes[] = $class;
- $classes = array_reverse($classes);
- $parentClasses[$class] = $classes;
- return $classes;
- }
- public static function traits($__className = NULL)
- {
- $usedTraits = &self::$__usedTraits;
- $class = NULL === $__className ? get_called_class() : $__className;
- $classes = self::parents($class);
- if(isset($usedTraits[$class]))
- return $usedTraits[$class];
- $traits = [];
- foreach($classes as $class)
- foreach((new \ReflectionClass($class))->getTraits() as $trait)
- $traits[] = $trait->name;
- $usedTraits[$class] = $traits;
- return $traits;
- }
- /**
- * referenced runtime to create new object from called-class
- */
- public function link()
- {
- return $this->____construct($this->__runtimeConfig);
- }
- /**
- * dereference runtime and create new object from called-class
- */
- public function copy()
- {
- $class = get_called_class();
- $config = $this->__env; // config is a reference!
- unset($this->__env); // unlink
- $this->__env = $config; // re-reference original
- return new $class($config); // build
- }
- public function __clone()
- {
- if($this instanceOf iCopy)
- return $this->copy();
- if($this instanceOf iLink)
- return $this->link();
- throw new \Exception('Not supported');
- }
- public static function __set_state(array $__data = [])
- {
- $this->__export = $__data;
- $class = get_called_class();
- $object = new $class($__data);
- foreach($object as $property => $value)
- $object->{$property} = $value;
- return $object;
- }
- /**
- *
- *
- * replace:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(['myNewBar' => ['fob' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(1) {
- * ["fob"]=>
- * string(3) "baz"
- * }
- *
- *
- * extend:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(true, ['myNewBar' => ['fob' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(2) {
- * ["foo"]=>
- * string(4) "blop"
- * ["fob"]=>
- * string(3) "baz"
- * }
- *
- * extend multi:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(true, $c, ['myNewBar' => ['fob' => 'baz']], ['myNewBar' => ['bla' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(3) {
- * ["foo"]=>
- * string(4) "blop"
- * ["fob"]=>
- * string(3) "baz"
- * ["bla"]=>
- * string(3) "baz"
- * }
- *
- * @callable array $__data
- * @callable array $__target, array $__data
- * @callable bool $__recursive, array $__data
- * @callable bool $__recursive, array $__target, array $__data
- * @param mixed
- * @return array|this
- * @note $__target is not a referenced array
- */
- public function extend()
- {
- $args = func_get_args();
- $tar = $args[0];
- $i = 1;
- $length = count($args);
- $rec = false;
- if($tar === true || $tar === false)
- {
- $rec = $tar;
- $tar = isset($args[1]) ? $args[1] : [];
- $i = 2;
- }
- if(!is_array($tar) && !is_object($tar))
- $tar = [];
- if($length === $i)
- {
- if(FALSE === ($this instanceof \Iterator))
- throw new \Exception('Unable to iterate throw '.get_called_class());
- $tar = $this;
- --$i;
- }
- for( ; $i < $length; $i++)
- {
- if(NULL === ($opt = $args[$i]))
- continue;
- foreach($opt as $key => $value)
- {
- if(is_array($tar))
- {
- if(TRUE === $rec && is_array($value) && isset($tar[$key]) && is_array($tar[$key]))
- {
- $tar[$key] = $this->extend($rec, $tar[$key], $value);
- continue;
- }
- if(is_object($value))
- {
- //$tar[$key] = TRUE === $rec ? clone $value : $value;
- $tar[$key] = $value;
- continue;
- }
- $tar[$key] = $opt[$key];
- continue;
- }
- if(is_object($tar))
- {
- if(TRUE === $rec && is_array($value) && isset($tar->$key) && is_array($tar->$key))
- {
- $tar->$key = $this->extend($rec, $tar->$key, $value);
- continue;
- }
- if(is_object($value))
- {
- //$tar[$key] = TRUE === $rec ? clone $value : $value;
- $tar->$key = $value;
- continue;
- }
- $tar->$key = $opt[$key];
- continue;
- }
- }
- }
- return $tar;
- }
- public function __call($__name, array $__parameters = [])
- {
- if(FALSE === $this->Core_Object_tMethod_exists($__name))
- throw new \Exception(__CLASS__.'::'.$__name.'() is not a function.');
- return $this->prototype($__name, $__parameters);
- }
- public function to($__format, array $__options = [])
- {
- $__options +=
- [
- 'handlers' => []
- ];
- return $this->Core_Object_tTo_emit($__format, [], $__options);
- }
- public function toString(array $__options = [])
- {
- return get_called_class();
- }
- public function toArray(array $__options = [])
- {
- $result = [];
- foreach($this as $property => $value)
- {
- if(substr($property, 0, 2) === '__')
- continue;
- switch(true):
- case is_array($value):
- case (!is_object($property)):
- $result[$property] = $value;
- break;
- case (isset($__options['handlers'][$class = get_class($value)])):
- $result[$property] = $__options['handlers'][$class]($value);
- break;
- case (method_exists($property, 'to')):
- $result[$property] = $value->to('array', $__options);
- break;
- case ($vars = get_object_vars($value)):
- $result[$property] = $vars;
- break;
- case (method_exists($value, '__toString')):
- $result[$property] = (string) $value;
- break;
- default:
- $result[$property] = $value;
- break;
- endswitch;
- }
- return $result;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement