[Beeframework-svn] SF.net SVN: beeframework:[65] trunk/framework/Bee
Brought to you by:
b_hartmann,
m_plomer
From: <m_p...@us...> - 2013-08-24 17:16:48
|
Revision: 65 http://sourceforge.net/p/beeframework/code/65 Author: m_plomer Date: 2013-08-24 17:16:44 +0000 (Sat, 24 Aug 2013) Log Message: ----------- - EnumBase / EnumType Modified Paths: -------------- trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php Added Paths: ----------- trunk/framework/Bee/Utils/EnumBase.php Modified: trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php =================================================================== --- trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php 2013-08-24 14:04:11 UTC (rev 64) +++ trunk/framework/Bee/Persistence/Doctrine2/Types/EnumType.php 2013-08-24 17:16:44 UTC (rev 65) @@ -7,8 +7,9 @@ * Class EnumType * @package Bee\Persistence\Doctrine2\Types */ -abstract class EnumType extends Type -{ +abstract class EnumType extends Type { + + const ENUM_BASE_TYPE = 'Bee\Utils\EnumBase'; /** * @var array */ @@ -19,37 +20,41 @@ */ private $name; + private $reflClass; + + protected abstract function getEnumClassName(); + public function __construct() { - $reflClass = new \ReflectionClass($this); - $this->values = array_diff_key($reflClass->getConstants(), array('ENUM_NAME')); - $this->name = $reflClass->getConstant('ENUM_NAME'); + $this->reflClass = new \ReflectionClass($this->getEnumClassName()); + if (!$this->reflClass->isSubclassOf(self::ENUM_BASE_TYPE)) { + throw new \UnexpectedValueException('"' . $this->reflClass . '" is not a subclass of "' . self::ENUM_BASE_TYPE . '"'); + } + + $this->name = 'enum_' . str_replace('\\', '', $this->getEnumClassName()); } - protected function getValues() { - return $this->values; + public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) { + $values = array_map(function ($val) { + return "'" . $val . "'"; + }, $this->reflClass->getMethod('getValues')->invoke(null)); + return "ENUM(" . implode(", ", $values) . ") COMMENT '(DC2Type:" . $this->name . ")'"; } - public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) - { - $values = array_map(function($val) { return "'".$val."'"; }, $this->getValues()); - return "ENUM(".implode(", ", $values).") COMMENT '(DC2Type:".$this->name.")'"; - } + public function convertToPHPValue($value, AbstractPlatform $platform) { + return $this->reflClass->getMethod('get')->invoke(null, $value); + } - public function convertToPHPValue($value, AbstractPlatform $platform) - { - return $value; - } + public function convertToDatabaseValue($value, AbstractPlatform $platform) { + if (!$this->reflClass->isInstance($value)) { + throw new \UnexpectedValueException('Not a valid enum element for "' . self::ENUM_BASE_TYPE . '": ' . $value); + } + // check if value is valid + self::convertToPHPValue($value->val(), $platform); + // return actual value + return $value->val(); + } - public function convertToDatabaseValue($value, AbstractPlatform $platform) - { - if (!in_array($value, $this->getValues())) { - throw new \InvalidArgumentException("Invalid '".$this->name."' value."); - } - return $value; - } - - public function getName() - { - return $this->name; - } + public function getName() { + return $this->name; + } } \ No newline at end of file Added: trunk/framework/Bee/Utils/EnumBase.php =================================================================== --- trunk/framework/Bee/Utils/EnumBase.php (rev 0) +++ trunk/framework/Bee/Utils/EnumBase.php 2013-08-24 17:16:44 UTC (rev 65) @@ -0,0 +1,122 @@ +<?php +namespace Bee\Utils; +/* + * Copyright 2008-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use ReflectionClass; + +/** + * Class EnumBase + * @package Bee\Utils + */ +abstract class EnumBase { + + /** + * @var ReflectionClass + */ + private static $reflClass = null; + + /** + * @var array + */ + private static $valueToName = null; + + /** + * @var EnumBase + */ + private static $instancesByValue = null; + + /** + * @var EnumBase + */ + private static $instancesByOid = null; + + /** + * @var mixed + */ + private $value; + + private final function __construct($value) { + $this->value = $value; + } + + /** + * @return mixed + */ + public final function val() { + return $this->value; + } + + /** + * @return array + */ + public static function getValues() { + self::init(); + return array_keys(self::$valueToName); + } + + /** + * Check if valid instance + * @param EnumBase $inst + * @return bool + */ + public static function has(EnumBase $inst) { + // no need to call init, as + return isset(self::$instancesByOid[spl_object_hash($inst)]); + } + + /** + * Retrieve singleton instance + * + * @param $value + * @return EnumBase + * @throws \UnexpectedValueException + */ + public static function get($value) { + self::init(); + if(!isset(self::$valueToName[$value])) { + throw new \UnexpectedValueException('Invalid value "' . $value . '" for enum ' . self::$reflClass->getShortName()); + } + + if(!isset(self::$instancesByValue[$value])) { + $name = self::$valueToName[$value]; + $className = self::$reflClass->getName(); + $instanceClassName = class_exists($className . '_' . $name, false) ? $className . '_' . $name : $className; + $inst = new $instanceClassName($value); + self::$instancesByValue[$value] = $inst; + self::$instancesByOid[spl_object_hash($inst)] = $inst; + } + + return self::$instancesByValue[$value]; + } + + private static function init() { + if(is_null(self::$reflClass)) { + self::$reflClass = new \ReflectionClass(new static(false)); + $constants = self::$reflClass->getConstants(); + self::$valueToName = array_flip($constants); + if(count($constants) !== count(self::$valueToName)) { + throw new \UnexpectedValueException('Invalid enum definition ' . self::$reflClass->getName() .' : const values probably not unique'); + } + } + } + + private function __clone() { + } + + private function __wakeup() { + } +} + \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |