<?PHP
NAMESPACE ILLI\Core;
USE ILLI\Core\StaticObject\iAdapter;
USE ILLI\Core\StaticObject\iClass;
USE ILLI\Core\StaticObject\iFilter;
USE ILLI\Core\StaticObject\iMethod;
USE ILLI\Core\StaticObject\iMethodFacade;
USE ILLI\Core\StaticObject\iMethodProto;
USE ILLI\Core\StaticObject\iObserver;
USE ILLI\Core\StaticObject\iSignal;
USE ILLI\Core\StaticObject\iTo;
USE ILLI\Core\StaticObject\tAdapter;
USE ILLI\Core\StaticObject\tFilter;
USE ILLI\Core\StaticObject\tInvoke;
USE ILLI\Core\StaticObject\tObserver;
USE ILLI\Core\StaticObject\tSignal;
USE ILLI\Core\StaticObject\tClass;
USE ILLI\Core\StaticObject\tTo;
USE ILLI\Core\StaticObject\tMethod;
USE ILLI\Core\StaticObject\tMethodFacade;
USE ILLI\Core\StaticObject\tMethodProto;
USE ILLI\Core\Filter;
INTERFACE iStaticObject EXTENDS iAdapter, iClass, iFilter, iMethod, iMethodFacade, iMethodProto, iObserver, iSignal, iTo
{
public static function __load();
public static function parents($__className = NULL);
public static function traits($__className = NULL);
public static function construct(array $__options = []);
public static function __callstatic($__name, array $__parameters = []);
public static function env(array $__options = []);
public static function extend();
public static function to($__format, array $__options = []);
}
CLASS StaticObject IMPLEMENTS iStaticObject
{
USE tMethodFacade
{
Core_StaticObject_tMethodFacade_register AS public registerMethodFacade;
Core_StaticObject_tMethodFacade_unregister AS public unregisterMethodFacade;
Core_StaticObject_tMethodFacade_exists AS public isMethodFacade;
}
USE tAdapter
{
Core_StaticObject_tAdapter_register AS public registerAdapter;
Core_StaticObject_tAdapter_unregister AS public unregisterAdapter;
Core_StaticObject_tAdapter_exists AS public isAdapter;
}
USE tClass
{
Core_StaticObject_tClass_register AS public registerClass;
Core_StaticObject_tClass_unregister AS public unregisterClass;
Core_StaticObject_tClass_exists AS public isClass;
}
USE tFilter
{
Core_StaticObject_tFilter_register AS public registerFilter;
Core_StaticObject_tFilter_unregister AS public unregisterFilter;
Core_StaticObject_tFilter_exists AS public isFilter;
}
USE tMethod
{
Core_StaticObject_tMethod_register AS public registerMethod;
Core_StaticObject_tMethod_unregister AS public unregisterMethod;
Core_StaticObject_tMethod_exists AS public isMethod;
}
USE tObserver
{
Core_StaticObject_tObserver_register AS public registerObserver;
Core_StaticObject_tObserver_unregister AS public unregisterObserver;
Core_StaticObject_tObserver_exists AS public isObserver;
}
USE tSignal
{
Core_StaticObject_tSignal_register AS public registerSignal;
Core_StaticObject_tSignal_unregister AS public unregisterSignal;
Core_StaticObject_tSignal_exists AS public isSignal;
}
USE tTo
{
Core_StaticObject_tTo_register AS public registerTo;
Core_StaticObject_tTo_unregister AS public unregisterTo;
Core_StaticObject_tTo_exists AS public isTo;
}
USE tMethodProto
{
Core_StaticObject_tMethodProto_register AS public registerMethodProto;
Core_StaticObject_tMethodProto_unregister AS public unregisterMethodProto;
Core_StaticObject_tMethodProto_exists AS public isMethodProto;
}
USE tInvoke;
protected static $__defaultConfig = [];
protected static $__autoConfig = [];
protected static $__defaultOptions = [];
protected static $__env = [];
protected static $__initConfig = [];
protected static $__parentClasses = [];
protected static $__usedTraits = [];
private static $__baseOptions =
[
'__run' => TRUE,
'__main' => '__main',
'__delegate' => NULL,
'__adapter' => [],
'__filter' => [],
'__proto' => [],
'__method' => [],
'__observer' => [],
'__signal' => [],
'__class' => [],
'__to' =>
[
'string' => 'toString',
'array' => 'toArray'
],
'__protoprefix' => 'prototype'
];
protected static function __main()
{
var_dump(__METHOD__);
}
public static function __load()
{
$class = get_called_class();
self::$__env[$class] = [];
self::$__initConfig[$class] = [];
}
private function __construct()
{
}
final public static function construct(array $__options = [])
{
$class = get_called_class();
var_dump(__METHOD__);
self::$__initConfig[$class] = static::extend(TRUE, self::$__baseOptions, static::$__defaultOptions, $__options);
if(TRUE === self::$__initConfig[$class]['__run'])
static::__run();
}
public static function env(array $__env = [])
{
$class = get_called_class();
foreach(self::$__env[$class] as $passable => $val)
{
if(FALSE === isset($__env[$passable]))
continue;
self::$__env[$class][$passable] = is_array(self::$__env[$class][$passable]) && is_array($__env[$passable])
? static::extend(TRUE, self::$__env[$class][$passable], $__env[$passable])
: $__env[$passable];
$key = "{$passable}";
if(TRUE === isset(static::${$key}))
static::${$key} = &self::$__env[$class][$passable];
}
}
protected static function __run()
{
$class = get_called_class();
static::__configure();
var_dump(__METHOD__);
static::Core_StaticObject_tMethod_install (self::$__initConfig[$class]['__method']);
static::Core_StaticObject_tMethodProto_install (self::$__initConfig[$class]['__proto']);
static::Core_StaticObject_tAdapter_install (self::$__initConfig[$class]['__delegate']);
static::Core_StaticObject_tAdapter_install (self::$__initConfig[$class]['__adapter']);
static::Core_StaticObject_tObserver_install (self::$__initConfig[$class]['__observer']);
static::Core_StaticObject_tSignal_install (self::$__initConfig[$class]['__signal']);
static::Core_StaticObject_tFilter_install (self::$__initConfig[$class]['__filter']);
static::Core_StaticObject_tTo_install (self::$__initConfig[$class]['__to']);
static::Core_StaticObject_tClass_install (self::$__initConfig[$class]['__class']);
static::prototype('construct', self::$__env[$class]);
}
protected static function __configure()
{
var_dump(__METHOD__);
$class = get_called_class();
$defaultConfig =& static::$__defaultConfig;
$autoConfig =& static::$__autoConfig;
$initConfig =& self::$__initConfig[$class];
$env =& self::$__env[$class];
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] = static::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[$key] = $initConfig[$key];
}
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 $passable => &$value)
{
$key = "{$passable}";
if(FALSE === isset(static::${$key}))
continue;
static::${$key} = &$value;
if(isset($initConfig[$passable]))
unset($initConfig[$passable]);
}
}
protected static function prototype($__function, array $__parameters = [])
{
var_dump(__METHOD__);
$__class = get_called_class();
if(isset($__parameters['this']))
unset($__parameters['this']);
if(TRUE === static::Core_StaticObject_tAdapter_exists($__function))
return static::Core_StaticObject_tAdapter_emit($__function, $__parameters);
$__parameters = static::Core_StaticObject_tFilter_emit($__function, 'PARAMS', $__parameters, ['return' => $__parameters]);
static::Core_StaticObject_tSignal_emit($__function, 'PRE_EVENT', [$__parameters], ['return' => $__parameters]);
$__result = static::Core_StaticObject_tMethodFacade_emit($__function, $__parameters, function(array $__params) use ($__class, $__function)
{
$result = NULL;
if(TRUE === static::Core_StaticObject_tMethodProto_exists($__function))
{
$result = static::Core_StaticObject_tMethodProto_emit($__function, $params);
}
else
{
$proto = $__function === 'construct'
? self::$__initConfig[$__class]['__main']
: self::$__initConfig[$__class]['__protoprefix'].$__function;
if($proto === $__function)
{
}
else
if(method_exists($__class, $proto))
{
$result = static::Core_StaticObject_tInvoke_method($proto, $__params);
}
}
return $result;
});
$__result = static::Core_StaticObject_tFilter_emit($__function, 'RETURN', $__result, ['return' => $__result]);
static::Core_StaticObject_tObserver_emit($__function, [$__result, $__parameters]);
static::Core_StaticObject_tSignal_emit($__function, 'POST_EVENT', [$__result, $__parameters], ['return' => $__result]);
return $__result;
}
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;
}
public static function extend()
{
$class = get_called_class();
$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 = $class;
--$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] = static::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 = static::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_string($tar))
{
if(isset(self::$__env[$class][$key]))
{
static::env([$key => $value]);
continue;
}
if(TRUE === $rec && is_array($value) && isset(static::${$key}) && is_array(static::${$key}))
{
static::${$key} = static::extend($rec, static::${$key}, $value);
continue;
}
if(is_object($value))
{
//static::${$key} = TRUE === $rec ? clone $value : $value;
static::${$key} = $value;
continue;
}
static::${$key} = $opt[$key];
}
}
}
return $tar;
}
public static function __callstatic($__name, array $__parameters = [])
{
if(FALSE === static::Core_StaticObject_tMethod_exists($__name))
throw new \Exception(get_called_class().'::'.$__name.'() is not a function.');
return static::Core_StaticObject_tMethod_emit($__name, $__parameters);
}
public static function to($__format, array $__options = [])
{
$__options +=
[
'handlers' => []
];
return static::Core_StaticObject_tTo_emit($__format, [$__options]);
}
protected static function toString(array $__options = [])
{
return get_called_class();
}
protected static function toArray(array $__options = [])
{
$__options +=
[
'filter' => function($__propertyName, $__value)
{
return !(substr($__propertyName, 0, 2) === '__');
}
];
$props = [];
$lookup = $class = get_called_class();
do
{
foreach((new \ReflectionClass($lookup))->getStaticProperties() as $property => $value)
{
// normalize $space[ClassName] => $data to $space => $data
if(isset(self::${$property})
&& is_array(self::${$property})
&& in_array($property, ['__initConfig', '__env'])
&& isset(self::${$property}[$class]))
$value = self::${$property}[$class];
$props[$property] = (is_array($value) && TRUE === isset($props[$property]))
? array_merge($value, $props[$property])
: $value;
}
}
while($lookup = get_parent_class($lookup));
$result = [];
foreach($props as $property => $value)
{
if(is_callable($__options['filter'])
&& FALSE === $__options['filter']($property, $value))
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($value, '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 [$class => $result];
}
}
Comments