Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?PHP
- NAMESPACE ILLI\Core;
- USE ILLI\Core\Exception;
- USE ILLI\Util\Inflector;
- USE ILLI\Util\String;
- USE ILLI\Core\Proto\I_Boot;
- CLASS Proto EXTENDS \ILLI\Core\A_Proto IMPLEMENTS \ILLI\Core\I_Proto
- {
- private static $__defaultOptions =
- [
- I_Proto::DI_RUN => TRUE,
- I_Proto::DI_MAIN => '__main',
- I_Proto::DI_CLASS => [],
- I_Proto::DI_DELEGATE => [],
- I_Proto::DI_FILTER => [],
- I_Proto::DI_METHOD => [],
- I_Proto::DI_OBSERVER => [],
- I_Proto::DI_METHOD_PROTO => [],
- I_Proto::DI_SIGNAL => [],
- I_Proto::DI_TO =>
- [
- 'string' => 'toString',
- 'array' => 'toArray'
- ]
- ];
- protected $__initConfig = [];
- USE \ILLI\Core\Proto\T_Boot;
- /**
- * bootstrap static protected vars and store default class-setup in a static dict
- * default strapping:
- * ::$propertyConfigurable: a list of accessible/configurable properties including constructor-options
- * ::$propertyDefaults: the default Values of defined class-properties
- * ::$propertyAspectable: a list of injectable class-properties (observer, signal, facade, strategy etc.)
- *
- * @discus: diff for constructor-configurable and runtime-configurable:
- * unset from whitelist on @__exec() ??
- */
- final public function __construct(array $__options = [])
- {
- // $obj->$prop not exist:
- // bypass property... public $obj->$commonProp is evil: the value is avail in __initConfig and never modifiable from outside
- // modify prop:
- // not defined as CONFIGURABLE -> not public -> not modifiable
- // __construct(array $__options):
- // not defined as CONFIGURABLE: $__options[prop] is stored in __initConfig[prop] -> bypass $obj->$prop
- // DEFAULT VALUE, construct $__options, modify prop:
- // not defined as ASPECTABLE: use direct access
- // @__boot
- // ON_LOOKUP | ON_COMPLETE => static results
- // ON_INIT $obj::__construct-event
- $__boot =
- [
- // DEFAULT VALUE
- // the default values
- // static $obj::$__DEFINE_propDef
- I_Proto::DEFINE_DEFAULTS =>
- [
- // merge DEF -> value: called class overwrites base-class except $__defaultOptions (extend)
- // write $c to static cache
- I_Boot::ON_LOOKUP => function($c, $n, array $l)
- {
- array_walk($l, function($v, $p) use (&$c, $n)
- {
- $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
- [
- I_Proto::BOOT_IDX_DEFAULT_VALUE => $v
- ];
- $m = &$c[$p][I_Proto::BOOT_IDX_DEFAULT_VALUE];
- if(isset($m)
- && isset(self::$__defaultOptions[$p])
- && is_array($m)
- && is_array($v))
- $m = $this->extend(TRUE, $v, $m);
- });
- return $c;
- },
- // load $c from static cache
- // save merged defaults in __initConfig on __construct()
- I_Boot::ON_INIT => function($c)
- {
- array_walk($c, function($s, $p)
- {
- $this->__initConfig[$p] = $s[I_Proto::BOOT_IDX_DEFAULT_VALUE];
- });
- return $c;
- }
- ],
- // ASPECTABLE PROP
- // aspProperty is injectable
- // [$prop => false] overwrites parent::$prop to bypass asp
- // [$prop => flag] overwrites parent::$prop: 'array', 'property' OR ['myFunc1', 'myFunc2'] OR 'myFunc1|myFunc2'
- // inject-accessor is the camelized version of property-name + event-name: aspectable{:Event}{:Property}() -> aspectableSetParam
- // protected accessor is property({:event}, {:property}[, {:value}])
- // public accessor is property{:Event}([{:property}, {:value}]) @see CONFIGURABLE
- // to apply asp-events for DEFAULT-values register all events before calling @__exec()! ($__option[__run] = FALSE)
- // static $obj::$__DEFINE_propAsp
- I_Proto::DEFINE_ASPECTABLE =>
- [
- // merge ASP -> flag: called class extends base-class
- // write $c to static cache
- I_Boot::ON_LOOKUP => function($c, $n, $l)
- {
- $d =
- [
- I_Proto::ASP_TYPE_PROP => [I_Proto::ASP_FN_PRFX_SET, I_Proto::ASP_FN_PRFX_RESTORE],
- I_Proto::ASP_TYPE_ARRAY => [I_Proto::ASP_FN_PRFX_SET, I_Proto::ASP_FN_PRFX_RESTORE, I_Proto::ASP_FN_PRFX_ADD, I_Proto::ASP_FN_PRFX_REMOVE, I_Proto::ASP_FN_PRFX_CLEAR],
- ];
- array_walk($l, function($v, $p) use (&$c, $n, $d)
- {
- if(is_integer($p))
- {
- $p = $v;
- $v = TRUE;
- }
- $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
- [
- I_Proto::BOOT_IDX_ASP_ENABLED => is_string($v) ? TRUE : $v,
- I_Proto::BOOT_IDX_ASP_DI_LIST => $a = is_string($u = is_bool($v) ? I_Proto::ASP_TYPE_PROP : $v) ? isset($d[$u]) ? $d[$u] : explode('|', $u) : $u,
- I_Proto::BOOT_IDX_ASP_DI_INIT_NAME => !isset($a[0]) ? isset($d[$u]) ? $d[$u][0] : I_Proto::ASP_FN_PRFX_SET : $a[0],
- I_Proto::BOOT_IDX_ASP_DI_NAMES => [],
- I_Proto::BOOT_IDX_ASP_DI_DISABLED => [],
- I_Proto::BOOT_IDX_ASP_DI_ENABLED => []
- ];
- });
- return $c;
- },
- // create accessor tuplet
- // write $c to static cache
- I_Boot::ON_COMPLETE => function($c)
- {
- array_walk($c, function(&$s, $p)
- {
- if(FALSE === $s[I_Boot::BOOT_IDX_EXISTS]
- || FALSE === $s[I_Proto::BOOT_IDX_ASP_ENABLED])
- return;
- array_walk($s[I_Proto::BOOT_IDX_ASP_DI_LIST], function($a) use (&$s, $p)
- {
- $s[I_Proto::BOOT_IDX_ASP_DI_NAMES] += [$a => $m = String::insert(I_Proto::ASP_TPL_FN_NAME, ['aspFnPrefix' => Inflector::camelize($a), 'propertyName' => Inflector::camelize($p)])];
- $s[(($e = method_exists($this, $m)) ? I_Proto::BOOT_IDX_ASP_DI_ENABLED : I_Proto::BOOT_IDX_ASP_DI_DISABLED)] += [$a => ($e ? $m : $p)];
- });
- });
- return $c;
- }
- ],
- // CONFIGURABLE
- // comProperty is a runtimeProperty
- // accessible from public scope
- // accessibble from __construct
- // [$prop => flag] overwrites parent::$prop: behavior (merge, extend...)
- // public accessor is property{:Event}([{:property}, {:value}])
- // static $obj::$__DEFINE_propCom
- I_Proto::DEFINE_CONFIGURABLE =>
- [
- // merge CONFIGURABLE -> flag: called class extends base-class
- // write $c to static cache
- I_Boot::ON_LOOKUP => function($c, $n, array $l)
- {
- array_walk($l, function($v, $p) use (&$c, $n)
- {
- if(is_integer($p))
- {
- $p = $v;
- $v = FALSE;
- }
- $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
- [
- I_Proto::BOOT_IDX_CONFIG_FLAG => $v
- ];
- });
- return $c;
- }
- ]
- ];
- // @__dest
- // finalizer
- $__dest = function()
- {
- $this->__initConfig[I_Proto::DI_RUN] = TRUE;
- unset($this->__initConfig[I_Proto::DI_BOOT_EXEC]);
- };
- // @__init
- // write property-value
- $__init = isset($__options[I_Proto::DI_BOOT_INIT]) && is_callable($__options[I_Proto::DI_BOOT_INIT])
- ? function($p, $v) use ($__options)
- {
- $__options[I_Proto::DI_BOOT_INIT]($p, $v, self::$__Core_Proto_T_Boot_Static[get_called_class()]);
- }
- // write $obj->$prop when prop is not defined as ASP
- // write $obj->$prop when prop is defined as direct-access
- // write $obj->$prop when prop ASP is disabled
- // delegate to $obj->property{:Event}($value)
- : function($p, $v)
- {
- $a = self::$__Core_Proto_T_Boot_Static[get_called_class()][I_Proto::DEFINE_ASPECTABLE];
- if(!isset($a[$p]))
- return $this->$p = $v;
- $s = $a[$p];
- if(FALSE === $s[I_Proto::BOOT_IDX_ASP_ENABLED])
- return $this->$p = $v;
- if(!isset($s[I_Proto::BOOT_IDX_ASP_DI_INIT_NAME]))
- throw new Exception('The default handle is "set". No handler found.');
- $u = $s[I_Proto::BOOT_IDX_ASP_DI_INIT_NAME];
- if(isset($s[I_Proto::BOOT_IDX_ASP_DI_DISABLED][$u]))
- return $this->$p = $v;
- if(isset($s[I_Proto::BOOT_IDX_ASP_DI_ENABLED][$u]))
- return $this->$s[I_Proto::BOOT_IDX_ASP_DI_ENABLED][$u]($v);
- throw new Exception('Setter {:u} not avail.', compact('u'));
- };
- // @__exec
- // load default property-values from DEFAULTS
- // load accessible properties from CONFIGURABLE
- // handle data by CONFIGURABLE-flag
- // write initial property-values using @__init
- // unset accessible properties from __initConfig
- $__exec = isset($__options[I_Proto::DI_BOOT_EXEC]) && is_callable($__options[I_Proto::DI_BOOT_EXEC])
- ? function() use ($__init, $__dest, $__options)
- {
- $__options[I_Proto::DI_BOOT_EXEC]($__init, self::$__Core_Proto_T_Boot_Static[get_called_class()]);
- $__dest();
- }
- : function() use ($__init, $__dest)
- {
- $_ = self::$__Core_Proto_T_Boot_Static[get_called_class()];
- $c = $_[I_Proto::DEFINE_CONFIGURABLE];
- $d = $_[I_Proto::DEFINE_DEFAULTS];
- $i = &$this->__initConfig;
- $t = [];
- // load DEFAULT VALUE when prop exists as $obj->$prop
- array_walk($d, function($s, $p) use (&$t)
- {
- if(FALSE === $s[I_Boot::BOOT_IDX_EXISTS])
- return;
- $t[$p] = $s[I_Proto::BOOT_IDX_DEFAULT_VALUE];
- });
- // load CONFIGURABLE when prop exists in __initConfig
- // load CONFIGURABLE when prop exists as $obj->$prop
- // handle __initConfig[prop] by CONFIGURABLE-flag
- array_walk($c, function($s, $p) use (&$i, &$t)
- {
- if(FALSE === isset($i[$p])
- || FALSE === $s[I_Boot::BOOT_IDX_EXISTS])
- return;
- $v = $i[$p];
- switch(TRUE):
- case is_array($v) && is_array($this->$p):
- switch($s[I_Proto::BOOT_IDX_CONFIG_FLAG]):
- case I_Proto::CONFIG_HANDLE_ARR_ADD:
- $v = $this->$p + $v;
- break;
- case I_Proto::CONFIG_HANDLE_ARR_EXTEND:
- $v = $this->extend($this->$p, $v);
- break;
- case I_Proto::CONFIG_HANDLE_ARR_MERGE:
- $v = array_merge($this->$p, $v);
- break;
- case I_Proto::CONFIG_HANDLE_ARR_RECURSIVE:
- $v = $this->extend(TRUE, $this->$p, $v);
- break;
- endswitch;
- break;
- case is_string($v) && is_string($this->$p):
- switch($s[I_Proto::BOOT_IDX_CONFIG_FLAG]):
- case I_Proto::CONFIG_HANDLE_STR_APPEND:
- $v = $this->$p.$v;
- break;
- case I_Proto::CONFIG_HANDLE_STR_PREPEND:
- $v = $v.$this->$p;
- break;
- endswitch;
- break;
- endswitch;
- $t[$p] = &$v;
- });
- // $__init()
- array_walk($t, function(&$v, $p) use (&$i, $__init)
- {
- unset($i[$p]);
- $__init($p, $v);
- });
- $__dest();
- };
- // *magic*
- $this->Core_Proto_T_Boot_emit($this->extend(TRUE, (isset($__options[I_Proto::DI_BOOT_LOAD]) ? $__options[I_Proto::DI_BOOT_LOAD] : []), $__boot));
- unset($__options[I_Proto::DI_BOOT_LOAD]);
- unset($__options[I_Proto::DI_BOOT_EXEC]);
- unset($__options[I_Proto::DI_BOOT_INIT]);
- $this->__initConfig = $this->extend(TRUE, $this->__initConfig, self::$__defaultOptions, $__options);
- TRUE === $this->__initConfig[I_Proto::DI_RUN]
- ? $__exec()
- : $this->__initConfig[I_Proto::DI_BOOT_EXEC] = $__exec; // @see ::run()
- unset($__boot);
- unset($__init);
- unset($__exec);
- unset($__dest);
- }
- public function run()
- {
- if(isset($this->__initConfig[I_Proto::DI_BOOT_EXEC]))
- $this->__initConfig[I_Proto::DI_BOOT_EXEC]();
- return $this;
- }
- public function extend()
- {
- $a = func_get_args();
- $t = $a[0];
- $i = 1;
- $l = count($a);
- $r = FALSE;
- if(is_bool($t))
- {
- $r = $t;
- $t = isset($a[1]) ? $a[1] : [];
- $i = 2;
- }
- if(FALSE === is_array($t)
- && FALSE === is_object($t)
- && FALSE === is_string($t))
- $t = [];
- if($l === $i)
- {
- $t = $this;
- --$i;
- }
- for( ; $i < $l; $i++)
- {
- if(NULL === ($o = $a[$i]))
- continue;
- foreach($o as $p => $v)
- {
- switch(TRUE):
- case is_array($t):
- $t[$p] = (TRUE === $r && is_array($v) && isset($t[$p]) && is_array($t[$p]))
- ? $this->extend($r, $t[$p], $v)
- : $v;
- break;
- case is_object($t):
- $t->$p = (TRUE === $r && is_array($v) && isset($t->$p) && is_array($t->$p))
- ? $this->extend($r, $t->$p, $v)
- : $v;
- break;
- case is_string($t):
- if(FALSE === class_exists($t))
- throw new Exception('Class {:t} not found.', compact('t'));
- if(FALSE === property_exists($t, $p))
- throw new Exception('Property {:t}::${:p} not found.', compact('t', 'p'));
- $t::$$p = (TRUE === $r && is_array($v) && is_array($t::${$p}))
- ? $this->extend($r, $t::$$p, $v)
- : $v;
- break;
- default:
- throw new Exception('Target not writable.');
- endswitch;
- }
- }
- return $t;
- }
- // test
- public function propertySet($property, $value)
- {
- $_ = self::$__Core_Proto_T_Boot_Static[get_called_class()];
- $c = $_[I_Proto::DEFINE_CONFIGURABLE];
- if(!isset($c[$property]))
- throw new Exception('{:property} is not public.', compact('property'));
- $this->$property = $value; // stub
- return $this;
- }
- public function dump()
- {
- return self::$__Core_Proto_T_Boot_Static;
- }
- }
- <?PHP
- NAMESPACE ILLI\Core\Proto;
- USE ILLI\Core\Exception;
- USE ILLI\Core\Proto\I_Boot;
- USE SplFixedArray;
- TRAIT T_Boot
- {
- private static $__Core_Proto_T_Boot_Static = [];
- protected function Core_Proto_T_Boot_handleLookup($propertyName, $lookupClassName, $classCache)
- {
- if(FALSE === isset($classCache[$propertyName]))
- return
- [
- I_Boot::BOOT_IDX_EXISTS => isset($this->$propertyName) || property_exists($this, $propertyName),
- I_Boot::BOOT_IDX_DEFINED => $lookupClassName,
- I_Boot::BOOT_IDX_REDEFINED => FALSE,
- I_Boot::BOOT_IDX_INSPECT => $lookupClassName.'::$'.$propertyName
- ];
- $r = $classCache[$propertyName];
- if(FALSE === $r[I_Boot::BOOT_IDX_REDEFINED])
- {
- $r[I_Boot::BOOT_IDX_REDEFINED] = $r[I_Boot::BOOT_IDX_DEFINED];
- $r[I_Boot::BOOT_IDX_INSPECT] = $r[I_Boot::BOOT_IDX_DEFINED].'::$'.$propertyName;
- }
- $r[I_Boot::BOOT_IDX_DEFINED] = $lookupClassName;
- return $r;
- }
- protected function Core_Proto_T_Boot_emit(array $__lookupTable = [])
- {
- array_walk($__lookupTable, function($t, $p)
- {
- if(is_integer($p))
- {
- $p = $t;
- $t = [];
- }
- $l = get_called_class();
- $s = &self::$__Core_Proto_T_Boot_Static[$l][$p];
- if(isset($s))
- goto _init;
- $c = [];
- do
- {
- if(FALSE === isset($l::$$p))
- continue;
- $c = is_callable($h = isset($t[I_Boot::ON_LOOKUP]) ? $t[I_Boot::ON_LOOKUP] : NULL)
- ? $h($c, $l, $l::$$p)
- : $l::$$p;
- }
- while($l = get_parent_class($l));
- $c = is_callable($h = isset($t[I_Boot::ON_COMPLETE]) ? $t[I_Boot::ON_COMPLETE] : NULL)
- ? $h($c)
- : $c;
- array_walk($c, function($v, $p) use (&$s)
- {
- $s[$p] = SplFixedArray::fromArray($v, TRUE);
- });
- _init:
- if(is_callable($h = isset($t[I_Boot::ON_INIT]) ? $t[I_Boot::ON_INIT] : NULL))
- $h($s);
- });
- return $this;
- }
- }
- <?PHP
- NAMESPACE ILLI\Core\Proto;
- INTERFACE I_Boot
- {
- // offsets in SplFixedArray
- CONST BOOT_IDX_EXISTS = 0;
- CONST BOOT_IDX_DEFINED = 1;
- CONST BOOT_IDX_REDEFINED = 2;
- CONST BOOT_IDX_INSPECT = 3;
- // events
- CONST ON_LOOKUP = 'ILLI\Core\Proto\I_Boot::ON_LOOKUP';
- CONST ON_COMPLETE = 'ILLI\Core\Proto\I_Boot::ON_COMPLETE';
- CONST ON_INIT = 'ILLI\Core\Proto\I_Boot::ON_INIT';
- }
- <?PHP
- NAMESPACE ILLI\Core;
- INTERFACE I_Proto
- {
- // offsets in SplFixedArray
- CONST BOOT_IDX_ASP_DI_LIST = 4;
- CONST BOOT_IDX_ASP_ENABLED = 5;
- CONST BOOT_IDX_ASP_DI_INIT_NAME = 6;
- CONST BOOT_IDX_ASP_DI_NAMES = 7;
- CONST BOOT_IDX_ASP_DI_DISABLED = 8;
- CONST BOOT_IDX_ASP_DI_ENABLED = 9;
- CONST BOOT_IDX_CONFIG_FLAG = 4;
- CONST BOOT_IDX_DEFAULT_VALUE = 4;
- // bootstrapping properties
- CONST DEFINE_ASPECTABLE = '__DEFINE_propAsp';
- CONST DEFINE_CONFIGURABLE = '__DEFINE_propCom';
- CONST DEFINE_DEFAULTS = '__DEFINE_propDef';
- // default options
- CONST DI_BOOT_LOAD = 'ILLI\Core\I_Proto::DI_BOOT_LOAD';
- CONST DI_BOOT_INIT = 'ILLI\Core\I_Proto::DI_BOOT_INIT';
- CONST DI_BOOT_EXEC = 'ILLI\Core\I_Proto::DI_BOOT_EXEC';
- CONST DI_RUN = 'ILLI\Core\I_Proto::DI_RUN';
- CONST DI_MAIN = 'ILLI\Core\I_Proto::DI_MAIN';
- CONST DI_CLASS = 'ILLI\Core\I_Proto::DI_CLASS';
- CONST DI_DELEGATE = 'ILLI\Core\I_Proto::DI_DELEGATE';
- CONST DI_FILTER = 'ILLI\Core\I_Proto::DI_FILTER';
- CONST DI_METHOD = 'ILLI\Core\I_Proto::DI_METHOD';
- CONST DI_METHOD_FACADE = 'ILLI\Core\I_Proto::DI_METHOD_FACADE';
- CONST DI_METHOD_PROTO = 'ILLI\Core\I_Proto::DI_METHOD_PROTO';
- CONST DI_OBSERVER = 'ILLI\Core\I_Proto::DI_OBSERVER';
- CONST DI_SIGNAL = 'ILLI\Core\I_Proto::DI_SIGNAL';
- CONST DI_TO = 'ILLI\Core\I_Proto::DI_TO';
- // asp type handle def
- CONST ASP_TYPE_ARRAY = 'ILLI\Core\I_Proto::ASP_TYPE_ARRAY';
- CONST ASP_TYPE_PROP = 'ILLI\Core\I_Proto::ASP_TYPE_PROP';
- // asp method handle names
- CONST ASP_FN_PRFX_ADD = 'add';
- CONST ASP_FN_PRFX_CLEAR = 'clear';
- CONST ASP_FN_PRFX_GET = 'get';
- CONST ASP_FN_PRFX_REMOVE = 'remove';
- CONST ASP_FN_PRFX_RESTORE = 'restore';
- CONST ASP_FN_PRFX_SET = 'set';
- // default aspectable method name
- CONST ASP_TPL_FN_NAME = 'aspectable{:aspFnPrefix}{:propertyName}';
- // config flag handle names
- CONST CONFIG_HANDLE_ARR_ADD = 'ILLI\Core\I_Proto::CONFIG_HANDLE_ARR_ADD';
- CONST CONFIG_HANDLE_ARR_EXTEND = 'ILLI\Core\I_Proto::CONFIG_HANDLE_ARR_EXTEND';
- CONST CONFIG_HANDLE_ARR_MERGE = 'ILLI\Core\I_Proto::CONFIG_HANDLE_ARR_MERGE';
- CONST CONFIG_HANDLE_ARR_RECURSIVE = 'ILLI\Core\I_Proto::CONFIG_HANDLE_ARR_RECURSIVE';
- CONST CONFIG_HANDLE_STR_APPEND = 'ILLI\Core\I_Proto::CONFIG_HANDLE_STR_APPEND';
- CONST CONFIG_HANDLE_STR_PREPEND = 'ILLI\Core\I_Proto::CONFIG_HANDLE_STR_PREPEND';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement