Advertisement
fruffl

not a joke

Feb 4th, 2013
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.79 KB | None | 0 0
  1. <?PHP
  2.     NAMESPACE ILLI\Core;
  3.     USE ILLI\Core\Exception;
  4.     USE ILLI\Util\Inflector;
  5.     USE ILLI\Util\String;
  6.     USE ILLI\Core\Proto\I_Boot;
  7.    
  8.     CLASS Proto EXTENDS \ILLI\Core\A_Proto IMPLEMENTS \ILLI\Core\I_Proto
  9.     {
  10.         USE \ILLI\Core\Proto\T_Boot;
  11.        
  12.         private static $__defaultOptions =
  13.         [
  14.             I_Proto::DI_RUN         => TRUE,
  15.             I_Proto::DI_MAIN        => '__main',
  16.             I_Proto::DI_CLASS       => [],
  17.             I_Proto::DI_DELEGATE        => [],
  18.             I_Proto::DI_FILTER      => [],
  19.             I_Proto::DI_METHOD      => [],
  20.             I_Proto::DI_OBSERVER        => [],
  21.             I_Proto::DI_METHOD_PROTO    => [],
  22.             I_Proto::DI_SIGNAL      => [],
  23.             I_Proto::DI_TO  =>
  24.             [
  25.                 'string'        => 'toString',
  26.                 'array'         => 'toArray'
  27.             ]
  28.         ];
  29.        
  30.         protected $__initConfig = [];
  31.        
  32.         public function __construct(array $__options = [])
  33.         {
  34.             $__boot =
  35.             [
  36.                 I_Proto::PROP_DEFINE_DEFAULTS =>
  37.                 [
  38.                     I_Boot::ON_LOOKUP => function(array $c, $n, array $l)
  39.                     {
  40.                         array_walk($l, function($v, $p) use (&$c, $n)
  41.                         {
  42.                             $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
  43.                             [
  44.                                 I_Proto::DEFAULT_VALUE => $v
  45.                             ];
  46.                            
  47.                             $value = &$c[$p][I_Proto::DEFAULT_VALUE];
  48.                            
  49.                             if(isset($value)
  50.                             && is_array($value)
  51.                             && is_array($v)
  52.                             && in_array($p, ['class'])) // I_Object namespaces
  53.                                 $value = $this->extend(TRUE, $v, $value);
  54.                         });
  55.                        
  56.                         return $c;
  57.                     },
  58.                     I_Boot::ON_INIT => function(array $c)
  59.                     {
  60.                         array_walk($c, function($s, $p)
  61.                         {
  62.                             $this->__initConfig[$p] = $s[I_Proto::DEFAULT_VALUE];
  63.                         });
  64.                        
  65.                         return $c;
  66.                     }
  67.                 ],
  68.                 I_Proto::PROP_DEFINE_ASP =>
  69.                 [
  70.                     I_Boot::ON_LOOKUP => function(array $c, $n, array $l)
  71.                     {
  72.                         $d =
  73.                         [
  74.                             I_Proto::ASP_TYPE_DEF   => [I_Proto::ASP_FN_PRFX_SET, I_Proto::ASP_FN_PRFX_RESTORE],
  75.                             I_Proto::ASP_TYPE_OBJ   => [I_Proto::ASP_FN_PRFX_SET, I_Proto::ASP_FN_PRFX_RESTORE],
  76.                             I_Proto::ASP_TYPE_ARR   => [I_Proto::ASP_FN_PRFX_SET, I_Proto::ASP_FN_PRFX_RESTORE,
  77.                                             I_Proto::ASP_FN_PRFX_ADD, I_Proto::ASP_FN_PRFX_REMOVE, I_Proto::ASP_FN_PRFX_CLEAR],
  78.                         ];
  79.                        
  80.                         array_walk($l, function($v, $p) use (&$c, $n, $d)
  81.                         {
  82.                             if(is_integer($p))
  83.                             {
  84.                                 $p = $v;
  85.                                 $v = TRUE;
  86.                             }
  87.                            
  88.                             $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
  89.                             [
  90.                                 I_Proto::ASP_AVAIL  => $a = is_string($u = is_bool($v)
  91.                                                 ? I_Proto::ASP_TYPE_DEF : $v) ? isset($d[$u]) ? $d[$u] : explode('|', $u) : $u,
  92.                                 I_Proto::ASP_USE    => !isset($a[0]) ? isset($d[$u]) ? $d[$u][0] : I_Proto::ASP_FN_PRFX_SET : $a[0],
  93.                                 I_Proto::ASP_HANDLE => is_string($v) ? TRUE : $v
  94.                             ];
  95.                         });
  96.                        
  97.                         return $c;
  98.                     },
  99.                     I_Boot::ON_COMPLETE => function(array $c)
  100.                     {
  101.                         array_walk($c, function(&$s, $p)
  102.                         {
  103.                             if(FALSE === $s[I_Boot::EXISTS]
  104.                             || FALSE === $s[I_Proto::ASP_HANDLE])
  105.                                 return;
  106.                            
  107.                             array_walk($s[I_Proto::ASP_AVAIL], function($a) use (&$s, $p)
  108.                             {
  109.                                 $m = String::insert(I_Proto::TPL_ASP_FN_NAME, [
  110.                                     'aspFnPrfx' => Inflector::camelize($a),
  111.                                     'propertyName'  => Inflector::camelize($p)]);
  112.                                
  113.                                 $s += [I_Proto::ASP_ACCESS_ALL.$a => $m];
  114.                                 $s += [(($e = method_exists($this, $m))
  115.                                     ? I_Proto::ASP_ACCESS_ASP : I_Proto::ASP_ACCESS_DIR).$a => ($e ? $m : $p)];
  116.                             });
  117.                         });
  118.                        
  119.                         return $c;
  120.                     }
  121.                 ],
  122.                 I_Proto::PROP_DEFINE_CONFIGURABLE =>
  123.                 [
  124.                     I_Boot::ON_LOOKUP => function(array $c, $n, array $l)
  125.                     {
  126.                         array_walk($l, function($v, $p) use (&$c, $n)
  127.                         {
  128.                             if(is_integer($p))
  129.                             {
  130.                                 $p = $v;
  131.                                 $v = FALSE;
  132.                             }
  133.                            
  134.                             $c[$p] = $this->Core_Proto_T_Boot_handleLookup($p, $n, $c) +
  135.                             [
  136.                                 I_Proto::CONFIG_HANDLE => $v
  137.                             ];
  138.                         });
  139.                        
  140.                         return $c;
  141.                     }
  142.                 ]
  143.             ];
  144.            
  145.             $__init = isset($__options[I_Proto::DI_BOOT_INIT]) && is_callable($__options[I_Proto::DI_BOOT_INIT])
  146.                 ? function($p, $v) use ($__options)
  147.                 {
  148.                     $__options[I_Proto::DI_BOOT_INIT]($p, $v, self::$__Core_Proto_T_Boot_Static[get_called_class()]);
  149.                 }
  150.                 : function($p, $v)
  151.                 {
  152.                     $a = self::$__Core_Proto_T_Boot_Static[get_called_class()][I_Proto::PROP_DEFINE_ASP];
  153.                    
  154.                     if(!isset($a[$p]))
  155.                         return $this->$p = $v;
  156.                    
  157.                     $s = $a[$p];
  158.                    
  159.                     if(FALSE === $s[I_Proto::ASP_HANDLE])
  160.                         return $this->$p = $v;
  161.                    
  162.                     $u = &$s[I_Proto::ASP_USE];
  163.                        
  164.                     if(!isset($u))
  165.                         throw new Exception('The default handle is "set". No handler found.');
  166.                    
  167.                     $d = &$s[I_Proto::ASP_ACCESS_DIR.$u];
  168.                     $m = &$s[I_Proto::ASP_ACCESS_ASP.$u];
  169.                    
  170.                     if(isset($d))
  171.                         return $this->$p = $v;
  172.                        
  173.                     if(isset($m))
  174.                         return $this->$m($v);
  175.                        
  176.                     $m = I_Proto::ASP_ACCESS_ASP.$u;
  177.                     throw new Exception('Setter {:m} not avail.', compact('m'));
  178.                 };
  179.            
  180.             $__exec = isset($__options[I_Proto::DI_BOOT_EXEC]) && is_callable($__options[I_Proto::DI_BOOT_EXEC])
  181.                 ? function() use ($__init, $__options)
  182.                 {
  183.                     $__options[I_Proto::DI_BOOT_EXEC]($__init, self::$__Core_Proto_T_Boot_Static[get_called_class()]);
  184.                    
  185.                     $this->__initConfig[I_Proto::DI_RUN] = TRUE;
  186.                     unset($this->__initConfig[I_Proto::DI_BOOT_EXEC]);
  187.                 }
  188.                 : function() use ($__init)
  189.                 {
  190.                     $_ = self::$__Core_Proto_T_Boot_Static[get_called_class()];
  191.                     $c = $_[I_Proto::PROP_DEFINE_CONFIGURABLE];
  192.                     $d = $_[I_Proto::PROP_DEFINE_DEFAULTS];
  193.                     $i = &$this->__initConfig;
  194.                     $t = [];
  195.            
  196.                     array_walk($d, function($s, $p) use (&$t)
  197.                     {
  198.                         if(FALSE === $s[I_Boot::EXISTS])
  199.                             return;
  200.                            
  201.                         $t[$p] = &$s[I_Proto::DEFAULT_VALUE];
  202.                     });
  203.                    
  204.                     array_walk($c, function($s, $p) use (&$i, &$t)
  205.                     {
  206.                         if(FALSE === isset($i[$p]))
  207.                             return;
  208.                        
  209.                         $value = $i[$p];
  210.                        
  211.                         if(FALSE === $s[I_Boot::EXISTS])
  212.                             return;
  213.                        
  214.                         switch(TRUE):
  215.                             case is_array($value) && is_array($this->$p):
  216.                                 switch($s[I_Boot::CONFIG_HANDLE]):
  217.                                     case I_Proto::CONFIG_HANDLE_ARR_ADD:
  218.                                         $value = $this->$p + $value;
  219.                                         break;
  220.                                     case I_Proto::CONFIG_HANDLE_ARR_EXTEND:
  221.                                         $value = $this->extend($this->$p, $value);
  222.                                         break;
  223.                                     case I_Proto::CONFIG_HANDLE_ARR_MERGE:
  224.                                         $value = array_merge($this->$p, $value);
  225.                                         break;
  226.                                     case I_Proto::CONFIG_HANDLE_ARR_RECURSIVE:
  227.                                         $value = $this->extend(TRUE, $this->$p, $value);
  228.                                         break;
  229.                                 endswitch;
  230.                                 break;
  231.                             case is_string($value) && is_string($this->$p):
  232.                                 switch($s[I_Boot::CONFIG_HANDLE]):
  233.                                     case I_Proto::CONFIG_HANDLE_STR_APPEND:
  234.                                         $value = $this->$p.$value;
  235.                                         break;
  236.                                     case I_Proto::CONFIG_HANDLE_STR_PREPEND:
  237.                                         $value = $value.$this->$p;
  238.                                         break;
  239.                                 endswitch;
  240.                                 break;
  241.                         endswitch;
  242.                        
  243.                         $t[$p] = &$value;
  244.                     });
  245.                    
  246.                     array_walk($t, function(&$v, $p) use (&$i, $__init)
  247.                     {
  248.                         unset($i[$p]);
  249.                         $__init($p, $v);
  250.                     });
  251.                    
  252.                     $this->__initConfig[I_Proto::DI_RUN] = TRUE;
  253.                     unset($this->__initConfig[I_Proto::DI_BOOT_EXEC]);
  254.                 };
  255.            
  256.             $this->Core_Proto_T_Boot_emit
  257.             (
  258.                 $this->extend(TRUE, (isset($__options[I_Proto::DI_BOOT_LOAD])
  259.                     ? $__options[I_Proto::DI_BOOT_LOAD]
  260.                     : []), $__boot)
  261.             );
  262.            
  263.             unset($__options[I_Proto::DI_BOOT_LOAD]);
  264.             unset($__options[I_Proto::DI_BOOT_EXEC]);
  265.             unset($__options[I_Proto::DI_BOOT_INIT]);
  266.            
  267.             $this->__initConfig = $this->extend(TRUE, $this->__initConfig, self::$__defaultOptions, $__options);
  268.            
  269.             TRUE === $this->__initConfig[I_Proto::DI_RUN]
  270.                 ? $__exec()
  271.                 : $this->__initConfig[I_Proto::DI_BOOT_EXEC] = $__exec;
  272.            
  273.             unset($__boot);
  274.             unset($__init);
  275.             unset($__exec);
  276.         }
  277.        
  278.         public function run()
  279.         {
  280.             if(isset($this->__initConfig[I_Proto::DI_BOOT_EXEC]))
  281.                 $this->__initConfig[I_Proto::DI_BOOT_EXEC]();
  282.                
  283.             return $this;
  284.         }
  285.        
  286.         public function propertySet($property, $value)
  287.         {
  288.             $_ = self::$__Core_Proto_T_Boot_Static[get_called_class()];
  289.             $c = $_[I_Proto::PROP_DEFINE_CONFIGURABLE];
  290.            
  291.             if(!isset($c[$property]))
  292.                 throw new Exception('{:property} is not public.', compact('property'));
  293.                
  294.             $this->$property = $value;
  295.             return $this;
  296.         }
  297.        
  298.         public function extend()
  299.         {
  300.             $a = func_get_args();
  301.             $t = $a[0];
  302.             $i = 1;
  303.             $l = count($a);
  304.             $r = FALSE;
  305.            
  306.             if(is_bool($t))
  307.             {
  308.                 $r = $t;
  309.                 $t = isset($a[1]) ? $a[1] : [];
  310.                 $i = 2;
  311.             }
  312.            
  313.             if(FALSE === is_array($t)
  314.             && FALSE === is_object($t)
  315.             && FALSE === is_string($t))
  316.                 $t = [];
  317.                
  318.             if($l === $i)
  319.             {
  320.                 $t = $this;
  321.                 --$i;
  322.             }
  323.            
  324.             for( ; $i < $l; $i++)
  325.             {
  326.                 if(NULL === ($o = $a[$i]))
  327.                     continue;
  328.                
  329.                 foreach($o as $p => $v)
  330.                 {
  331.                     switch(TRUE):
  332.                         case is_array($t):
  333.                             $t[$p] = (TRUE === $r && is_array($v) && isset($t[$p]) && is_array($t[$p]))
  334.                                 ? $this->extend($r, $t[$p], $v)
  335.                                 : $v;
  336.                             break;
  337.                         case is_object($t):
  338.                             $t->$p = (TRUE === $r && is_array($v) && isset($t->$p) && is_array($t->$p))
  339.                                 ? $this->extend($r, $t->$p, $v)
  340.                                 : $v;
  341.                             break;
  342.                         case is_string($t):
  343.                             if(FALSE === class_exists($t))
  344.                                 throw new Exception('Class {:t} not found.', compact('t'));
  345.                                
  346.                             if(FALSE === property_exists($t, $p))
  347.                                 throw new Exception('Property {:t}::${:p} not found.', compact('t', 'p'));
  348.                                
  349.                             $t::$$p = (TRUE === $r && is_array($v) && is_array($t::${$p}))
  350.                                 ? $this->extend($r, $t::$$p, $v)
  351.                                 : $v;
  352.                             break;
  353.                         default:
  354.                             throw new Exception('Target not writable.');
  355.                     endswitch;
  356.                 }
  357.             }
  358.            
  359.             return $t;
  360.         }
  361.        
  362.         public function dump()
  363.         {
  364.             return self::$__Core_Proto_T_Boot_Static;
  365.         }
  366.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement