Advertisement
fruffl

Enum Game

Feb 25th, 2012
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.58 KB | None | 0 0
  1. <?PHP
  2.     /**
  3.      * ILLI
  4.      *
  5.      * @category   ILLI
  6.      * @package    ILLI
  7.      * @subpackage SystemType
  8.      * @link       http://illi.be
  9.      * @license    http://l.illi.be
  10.      * @copyright  ILLI Conference
  11.      */
  12.  
  13.     /**
  14.      * ILLI System Type Enum
  15.      *
  16.      * @category   ILLI
  17.      * @package    ILLI
  18.      * @subpackage SystemType
  19.      * @link       http://illi.be
  20.      * @license    http://l.illi.be
  21.      * @copyright  ILLI Conference
  22.      *
  23.      * @todo bit flag for
  24.      *  strict type
  25.      *  unique values
  26.      *  allow __default as NULL
  27.      *
  28.      * @todo array_shift in getDefinedName() and getDefaultName()? sure?
  29.      *
  30.      * @author ~luc <luc[at]s.illi.be>
  31.      */
  32.     ABSTRACT CLASS ILLI_System_Type_Enum EXTENDS ILLI_System_Type_Abstract
  33.     {
  34.         private static $__reflectionBase    = NULL;
  35.         private static $__constantsBase     = array();
  36.        
  37.         private $__definedConstants     = NULL;
  38.        
  39.         private $__definedDefault       = NULL;
  40.         private $__initValue            = NULL;
  41.         private $__definedValue         = NULL;
  42.        
  43.         final public function __construct($default = NULL)
  44.         {
  45.             if(NULL === self::$__reflectionBase)
  46.             {
  47.                 self::$__reflectionBase  = new ReflectionClass(__CLASS__);
  48.                 self::$__constantsBase   = self::$__reflectionBase->getConstants();
  49.             }
  50.            
  51.             $ref = new ReflectionClass($this->getQualifiedName());
  52.             $con  = $ref->getConstants();
  53.            
  54.             // hide constants from base
  55.             $diff = array_intersect_assoc(self::$__constantsBase, $con);
  56.            
  57.             foreach($diff as $const => $val)
  58.                 unset($con[$const]);
  59.            
  60.             $this->__definedConstants = new ILLI_System_Type_AssocArray($con);
  61.            
  62.             if(sizeOf($con) <= 1)
  63.                 throw new ILLI_Exception_ArgumentExpected
  64.                 (
  65.                     ILLI_System_E::ARGUMENT_EXPECTED_ENUMERABLE_CONSTANT_EXPECTED,
  66.                     array($this->getQualifiedName())
  67.                 );
  68.                
  69.             if(FALSE === $this->__definedConstants->offsetExists('__DEFAULT'))
  70.                 throw new ILLI_Exception_ArgumentExpected
  71.                 (
  72.                     ILLI_System_E::ARGUMENT_EXPECTED_ENUMERABLE_DEFAULT_EXPECTED,
  73.                     array
  74.                     (
  75.                         $this->getQualifiedName(),
  76.                         '__DEFAULT'
  77.                     )
  78.                 );
  79.                
  80.             $this->__definedDefault = $this->__definedConstants->offsetGet('__DEFAULT');
  81.            
  82.             if(NULL === $this->__definedDefault)
  83.                 throw new ILLI_Exception_ArgumentExpected
  84.                 (
  85.                     ILLI_System_E::ARGUMENT_EXPECTED_ENUMERABLE_IS_NULL,
  86.                     array
  87.                     (
  88.                         $this->getQualifiedName(),
  89.                         '__DEFAULT'
  90.                     )
  91.                 );
  92.            
  93.             $this->__definedConstants->offsetUnset('__DEFAULT');
  94.            
  95.             $cache = array();
  96.             foreach($this->__definedConstants as $const => $val)
  97.             {
  98.                 if(array_key_exists($val, $cache))
  99.                     throw new ILLI_Exception_ArgumentExpected
  100.                     (
  101.                         ILLI_System_E::ARGUMENT_EXPECTED_ENUMERABLE_UNIQUE_EXPECTED,
  102.                         array
  103.                         (
  104.                             $this->getQualifiedName(),
  105.                             $const,
  106.                             $val,
  107.                             $cache[$val]
  108.                         )
  109.                     );
  110.                    
  111.                 $cache[$val] = $const;
  112.             }
  113.            
  114.             if(FALSE === $this->isDefinedValue($this->__definedDefault))
  115.                 throw new ILLI_Exception_ArgumentExpected
  116.                 (
  117.                     ILLI_SYSTEM_E::ARGUMENT_EXPECTED_ENUMERABLE_DEFINED_EXPECTED,
  118.                     array
  119.                     (
  120.                         $this->getQualifiedName(),
  121.                         '__DEFAULT',
  122.                         $this->__definedDefault
  123.                     )
  124.                 );
  125.            
  126.             if(NULL === $default)
  127.                 $default = $this->__definedDefault;
  128.                
  129.             $this->define($default);
  130.             $this->__initValue = $default;
  131.         }
  132.        
  133.         final public function define($value)
  134.         {
  135.             try
  136.             {
  137.                 if(FALSE === $this->isDefinedValue($value))
  138.                     throw new ILLI_Exception_ArgumentOutOfRange
  139.                     (
  140.                         ILLI_SYSTEM_E::ARGUMENT_OUT_OF_ENUM_INDEX,
  141.                         array($value)
  142.                     );
  143.             }
  144.             catch(ILLI_Exception_ArgumentOutOfRange $e)
  145.             {
  146.                 throw $e;
  147.             }
  148.             catch(ILLI_Exception_Argument $e)
  149.             {
  150.                 throw new ILLI_Exception_ArgumentOutOfRange
  151.                 (
  152.                     ILLI_SYSTEM_E::ARGUMENT_OUT_OF_ENUM_INDEX,
  153.                     $e,
  154.                     array($const)
  155.                 );
  156.             }
  157.            
  158.             $this->__definedValue = $value;
  159.             return $this;
  160.         }
  161.        
  162.         final public function getValues()
  163.         {
  164.             return $this->__definedConstants->getValues();
  165.         }
  166.        
  167.         final public function getNames($value = NULL)
  168.         {
  169.             return $this->__definedConstants->getOffsets($value);
  170.         }
  171.        
  172.         final public function getValue($const)
  173.         {
  174.             try
  175.             {
  176.                 if(FALSE === $this->isDefinedConst($const))
  177.                     throw new ILLI_Exception_ArgumentOutOfRange
  178.                     (
  179.                         ILLI_SYSTEM_E::ARGUMENT_OUT_OF_ENUM_INDEX, 
  180.                         array($const)
  181.                     );
  182.             }
  183.             catch(ILLI_Exception_ArgumentOutOfRange $e)
  184.             {
  185.                 throw $e;
  186.             }
  187.             catch(ILLI_Exception_Argument $e)
  188.             {
  189.                 throw new ILLI_Exception_ArgumentOutOfRange
  190.                 (
  191.                     ILLI_SYSTEM_E::ARGUMENT_OUT_OF_ENUM_INDEX,
  192.                     $e,
  193.                     array($const)
  194.                 );
  195.             }
  196.                
  197.             return $this->__definedConstants->offsetGet($const);
  198.         }
  199.        
  200.         final public function reset()
  201.         {
  202.             $this->define($this->__initValue);
  203.             return $this;
  204.         }
  205.        
  206.         final public function getDefinedValue()
  207.         {
  208.             return $this->__definedValue;
  209.         }
  210.        
  211.         final public function getDefinedName()
  212.         {
  213.             $res = $this->getDefinedNames();
  214.             return array_shift($res);
  215.         }
  216.        
  217.         final public function getDefinedNames()
  218.         {
  219.             return $this->getNames($this->__definedValue);
  220.         }
  221.        
  222.         final public function getDefaultValue()
  223.         {
  224.             return $this->__initValue;
  225.         }
  226.        
  227.         final public function getDefaultName()
  228.         {
  229.             $res = $this->getDefaultNames();
  230.             return array_shift($res);
  231.         }
  232.        
  233.         final public function getDefaultNames()
  234.         {
  235.             return $this->getNames($this->__initValue);
  236.         }
  237.        
  238.         public function __toString()
  239.         {
  240.             return (string) $this->getDefinedValue();
  241.         }
  242.        
  243.         public function __invoke()
  244.         {
  245.             return $this->getDefinedValue();
  246.         }
  247.        
  248.         private function isDefinedValue($value)
  249.         {
  250.             if(NULL === $value)
  251.                 throw new ILLI_Exception_ArgumentNull;
  252.            
  253.             if(!is_integer($value))
  254.                 throw new ILLI_Exception_ArgumentExpected
  255.                 (
  256.                     ILLI_System_E::ARGUMENT_EXPECTED_INTEGER
  257.                 );
  258.                
  259.             foreach($this->__definedConstants as $key => $val)
  260.                 if($value === $val)
  261.                     return TRUE;
  262.                
  263.             return FALSE;
  264.         }
  265.        
  266.         private function isDefinedConst($const)
  267.         {
  268.             if(NULL === $const)
  269.                 throw new ILLI_Exception_ArgumentNull;
  270.            
  271.             if(!is_string($const))
  272.                 throw new ILLI_Exception_ArgumentExpected
  273.                 (
  274.                     ILLI_System_E::ARGUMENT_EXPECTED_STRING
  275.                 );
  276.            
  277.             return $this->__definedConstants->offsetExists($const);
  278.         }
  279.     }
  280.  
  281. class Fruit extends ILLI_System_Type_Enum
  282. {
  283.   const __DEFAULT = 1;
  284.   const APPLE     = 1;
  285.   const BANANA     = 2;
  286.   const ORANGE    = 3;
  287. }
  288.  
  289. function eat(Fruit $aFruit)
  290. {
  291.   if (Fruit::APPLE == $aFruit()) {
  292.     echo "Eating an apple.\n";
  293.   } elseif (Fruit::ORANGE == $aFruit()) {
  294.     echo "Eating an orange.\n";
  295.   } elseif (Fruit::BANANA == $aFruit()) {
  296.     echo "Eating an banana.\n";
  297.   }
  298. }
  299.  
  300.  
  301. $myApple   = new Fruit();
  302. eat($myApple);  // Eating an apple.
  303.  
  304. $myOrange  = new Fruit(Fruit::ORANGE);
  305. eat($myOrange); // Eating an orange.
  306.  
  307. eat($myOrange->define(Fruit::BANANA));  // switch to banana.
  308. eat($myOrange->reset());        // reset to orange.
  309.  
  310. $myCopy = $myOrange;
  311. var_dump($myCopy);
  312.  
  313. /**
  314.  
  315. Eating an apple.
  316. Eating an orange.
  317. Eating an banana.
  318. Eating an orange.
  319. object(Fruit)#5 (4) {
  320.   ["__definedConstants":"ILLI_System_Type_Enum":private]=>
  321.   object(ILLI_System_Type_AssocArray)#7 (2) {
  322.     ["__array":"ILLI_System_Type_ArrayAbstract":private]=>
  323.     array(3) {
  324.       ["APPLE"]=>
  325.       int(1)
  326.       ["BANANA"]=>
  327.       int(2)
  328.       ["ORANGE"]=>
  329.       int(3)
  330.     }
  331.     ["__protMode":"ILLI_System_Type_ArrayAbstract":private]=>
  332.     int(0)
  333.   }
  334.   ["__definedDefault":"ILLI_System_Type_Enum":private]=>
  335.   int(1)
  336.   ["__initValue":"ILLI_System_Type_Enum":private]=>
  337.   int(3)
  338.   ["__definedValue":"ILLI_System_Type_Enum":private]=>
  339.   int(3)
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement