PHP Enum Class

As part of the framework I am writing…


<?php
	/*
	 *	The KLF Framework
	 *
	 *	@author Kristian Oye  
	 *	@copyright (C) 2010-2011, Kristian Oye
	 */
	namespace KLF\System;
	
	/**
	 *  Class KEnum
	 *
	 *  An attempt at creating an enumeration type.
	 *  
	 *  $val  = KEnum::FIRST()
	 *  $val2 = KEnum::SECOND()
	 *
	 *  @package KLF\System
	 *  @access public
	 *  @author Kristian Oye 
	 *  @since 1.0
	 */
	class KEnum
	{
		/**
		 * Possible values for all enum types.
		 * @var unknown_type
		 */
		private static $PossibleValues;
		
		/**
		 * Instance variable storing the friendly name of the value.
		 * @var string
		 */
		protected $EnumValue;
		
		/**
		 * Fetches a list of constants for the derived enum class.
		 * @param string $class
		 */
		private static function Initialize($class)
		{
			if (!isset(KEnum::$PossibleValues[$class]))
			{
				KEnum::$PossibleValues[$class] = array();
				$reflect = new \ReflectionClass($class);
				foreach($reflect->getConstants() as $const => $v)
				{
					KEnum::$PossibleValues[$class][$const] = $v;
				}
			}
			return KEnum::$PossibleValues[$class];
		}
		
		/**
		 * Creates an instance of an enum value.
		 * @param string $class
		 * @param string $name
		 * @param int $val
		 */
		private static function Create($class, $name, $value)
		{
			$reflect = new \ReflectionClass($class);
			$instance = $reflect->newInstance();
			$instance->EnumValue = array($name => $value);
			return $instance;
		}
		
		/**
		 * Method for getting an enum value from the collection by name.
		 * @param string $name
		 * @param unused $args
		 */
		public static function __callStatic($name, $args=array(false))
		{
			$class = get_called_class();
			$values = KEnum::Initialize($class);
			
			if (isset($values[$name]))
			{
				$r = KEnum::Create($class, $name, $values[$name]);
				return (is_array($args) && count($args) > 0 && $args[0] === true ? $r->getValue() : $r);
			}
				
			throw new \Exception("Enum type $class does not have member named $name");
		}
		
		/**
		 * Returns the underlying value of the enum.
		 */
		public function getValue()
		{
			$r = 0;
			foreach($this->EnumValue as $key => $val)
			{
				$r |= $val;
			}
			return $r;
		}
		
		/**
		 * Add one or more enums together
		 *
		 * MyEnum::FIRST().Add(MyEnum::SECOND())
		 *
		 * @author: Kristian Oye 
		 * @since 1.0
		 * @return KEnum The resulting enum
		*/
		public function EnumAdd()
		{
			$myClass = get_class($this);
			foreach(func_get_args() as $arg)
			{
				if(!is_object($arg) || get_class($arg) !== $myClass)
					throw new \Exception("Bad argument to EnumAdd(); Argument must be of type $myClass");
				$this->EnumValue = array_merge($this->EnumValue, $arg->EnumValue);
			}
			return $this;
		}

		
		/**
		 * Returns true only if all the passed values are contained within the enum.
		 *
		 * @author: Kristian Oye 
		 * @since 1.0
		 * @return bool Result of the AND operation
		*/
		public function EnumAnd()
		{
			$myClass = get_class($this);
			$myValue = $this->getValue();
			foreach(func_get_args() as $arg)
			{
				if(!is_object($arg) || get_class($arg) !== $myClass)
					throw new \Exception("Bad argument to EnumAdd(); Argument must be of type $myClass");
				if (($arg->getValue() & $myValue) !== $arg->getValue())
					return false;
			}
			return true;
		}
		
		
		/**
		 * Returns true if the enum contains one or more of the enums specified.
		 *
		 * @author: Kristian Oye 
		 * @since 1.0
		 * @return bool Result of the OR operation
		*/
		public function EnumOr()
		{
			$myClass = get_class($this);
			$myValue = $this->getValue();
			foreach(func_get_args() as $arg)
			{
				if(!is_object($arg) || get_class($arg) !== $myClass)
					throw new \Exception("Bad argument to EnumAdd(); Argument must be of type $myClass");
				if (($arg->getValue() & $myValue) > 0)
					return true;
			}
			return false;
		}
		
		
		/**
		 * Takes a numeric value and converts it into an enum value.
		 * @param $val
		 */
		public static function parseValue($val)
		{
			$class = get_called_class();
			$values = KEnum::Initialize($class);
			foreach($values as $k => $v)
			{
				if($val === $v) return KEnum::Create($class, $k, $v);
			}
			throw new \Exception("Failed to parse '$val' into type $class");
		}
		
		/**
		 * Shorthand method for getting the enum's value
		 */
		public function __invoke()
		{
			return $this->getValue();
		}
		
		/**
		 * Returns the string equivelant of the enum value.
		 */
		public function __toString()
		{
			$class = get_class($this);
			return implode(' | ', array_map(function ($item) use ($class)
			{
				return $class . '::' . $item;
			},
			array_keys($this->EnumValue)));
		}
	}
?>

?>
Advertisements

1 Response to “PHP Enum Class”


  1. 1 melanie February 25, 2011 at 10:20 am

    Friday, 25 February, 2011 20:19 MAT

    is the inum class next ?

    ,` )


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s





%d bloggers like this: