├── .gitignore ├── .php_cs ├── .scrutinizer.yml ├── .travis.yml ├── LICENSE ├── README.md ├── appveyor.yml ├── composer.json ├── fixtures ├── FlagFixture.php └── SimpleFixture.php ├── phpspec.yml ├── spec └── fixtures │ ├── FlagFixtureSpec.php │ └── SimpleFixtureSpec.php └── src └── Enums ├── EnumTrait.php ├── FlagEnumInterface.php ├── FlagEnumTrait.php ├── SimpleEnumInterface.php └── SimpleEnumTrait.php /.gitignore: -------------------------------------------------------------------------------- 1 | composer.lock 2 | composer.phar 3 | .idea 4 | vendor/ 5 | bin/ -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | exclude('spec') 5 | ->in(__DIR__) 6 | ; 7 | 8 | return Symfony\CS\Config\Config::create() 9 | ->finder($finder) 10 | ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) 11 | ; -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - php 3 | 4 | filter: 5 | excluded_paths: 6 | - spec/* 7 | - fixtures/* 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 7.0 6 | - 7.1 7 | 8 | before_install: 9 | - composer self-update 10 | 11 | install: 12 | - composer install --prefer-source --no-interaction --dev 13 | 14 | script: 15 | - bin/spec run --format=pretty --no-interaction 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Chad Sikorra 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-simple-enum 2 | Provides a simple enum and flag enum for PHP using traits and interfaces. 3 | 4 | A simple enum example: 5 | 6 | ```php 7 | use Enums\SimpleEnumInterface; 8 | use Enums\SimpleEnumTrait; 9 | 10 | class DayOfWeek implements SimpleEnumInterface 11 | { 12 | use SimpleEnumTrait; 13 | 14 | const Monday = 1; 15 | 16 | const Tuesday = 2; 17 | 18 | const Wednesday = 3; 19 | 20 | const Thursday = 4; 21 | 22 | const Friday = 5; 23 | 24 | const Saturday = 6; 25 | 26 | const Sunday = 7; 27 | } 28 | 29 | // Get all of the names 30 | var_dump(DayOfWeek::names()); 31 | 32 | // Get all of the values 33 | var_dump(DayOfWeek::values()); 34 | 35 | // View it as an array 36 | var_dump(DayOfWeek::toArray()); 37 | 38 | // Check if a name is valid. This is case insensitive. 39 | if (DayOfWeek::isValidName('Monday')) { 40 | // ... 41 | } 42 | 43 | // Check if a value is valid. 44 | if (DayOfWeek::isValidValue(DayOfWeek::Monday)) { 45 | // ... 46 | } 47 | 48 | // Get the name for a specific value. 49 | var_dump(DayOfWeek::getValueName(1)); 50 | 51 | // Get the value for a specific name. This is case insensitive. 52 | var_dump(DayOfWeek::getNameValue('Monday')); 53 | ``` 54 | 55 | A flag enum example: 56 | 57 | ```php 58 | use Enums\FlagEnumInterface; 59 | use Enums\FlagEnumTrait; 60 | 61 | class FilePermission implements FlagEnumInterface 62 | { 63 | use FlagEnumTrait; 64 | 65 | const Read = 1; 66 | 67 | const Write = 2; 68 | 69 | const Execute = 4; 70 | } 71 | 72 | $permission = new FilePermission(FilePermission::Read | FilePermission::Write); 73 | 74 | // Remove a permission 75 | $permission->remove('Write'); 76 | 77 | // Add a permission 78 | $permission->add('Execute'); 79 | 80 | // Check for a permission 81 | if ($permission->has('Read')) { 82 | // ... 83 | } 84 | 85 | // Get the flag value 86 | var_dump($permission->getValue()); 87 | 88 | // Get all of the names for the flag as an array 89 | var_dump($permission->getNames()); 90 | 91 | // View the string representation (comma delimited list) 92 | var_dump((string) $permission); 93 | ``` 94 | 95 | The static methods are available in both the simple and flag enums. 96 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | build: off 2 | shallow_clone: false 3 | platform: 'x64' 4 | clone_folder: c:\projects\php-simple-enum 5 | 6 | environment: 7 | matrix: 8 | - PHP_VERSION: "5.6" 9 | - PHP_VERSION: "7.0" 10 | - PHP_VERSION: "7.1" 11 | 12 | install: 13 | - ps: Invoke-WebRequest "https://raw.githubusercontent.com/ChadSikorra/ps-install-php/master/Install-PHP.ps1" -OutFile "Install-PHP.ps1" 14 | - ps: .\Install-PHP.ps1 -Version $Env:PHP_VERSION -Highest -Arch x64 15 | - refreshenv 16 | - cd C:\projects\php-simple-enum 17 | - php -r "readfile('https://getcomposer.org/installer');" | php 18 | 19 | before_test: 20 | - cd C:\projects\php-simple-enum 21 | - php composer.phar install --no-interaction --no-progress --optimize-autoloader --prefer-source --no-ansi 22 | 23 | test_script: 24 | - cd C:\projects\php-simple-enum 25 | - bin\phpspec.bat run 26 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chadsikorra/php-simple-enum", 3 | "type": "library", 4 | "description": "Provides a simple enum and flag enum for PHP.", 5 | "keywords": [ 6 | "enum" 7 | ], 8 | "homepage": "https://github.com/ChadSikorra/php-simple-enum", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Chad Sikorra", 13 | "email": "Chad.Sikorra@gmail.com", 14 | "homepage": "http://www.chadsikorra.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=5.6" 19 | }, 20 | "require-dev": { 21 | "phpspec/phpspec": "~3.0", 22 | "friendsofphp/php-cs-fixer": "~1.0" 23 | }, 24 | "config": { 25 | "bin-dir": "bin" 26 | }, 27 | "autoload": { 28 | "psr-4": {"Enums\\": "src/Enums"} 29 | }, 30 | "autoload-dev": { 31 | "psr-4": {"fixtures\\": "fixtures/"} 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fixtures/FlagFixture.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace fixtures; 12 | 13 | use Enums\FlagEnumInterface; 14 | use Enums\FlagEnumTrait; 15 | 16 | class FlagFixture implements FlagEnumInterface 17 | { 18 | use FlagEnumTrait; 19 | 20 | const Read = 1; 21 | 22 | const Write = 2; 23 | 24 | const Execute = 4; 25 | } 26 | -------------------------------------------------------------------------------- /fixtures/SimpleFixture.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace fixtures; 12 | 13 | use Enums\SimpleEnumInterface; 14 | use Enums\SimpleEnumTrait; 15 | 16 | class SimpleFixture implements SimpleEnumInterface 17 | { 18 | use SimpleEnumTrait; 19 | 20 | const Monday = 1; 21 | 22 | const Tuesday = 2; 23 | 24 | const Wednesday = 3; 25 | 26 | const Thursday = 4; 27 | 28 | const Friday = 5; 29 | 30 | const Saturday = 6; 31 | 32 | const Sunday = 7; 33 | } 34 | -------------------------------------------------------------------------------- /phpspec.yml: -------------------------------------------------------------------------------- 1 | fixtures_suite: 2 | namespace: fixtures 3 | psr4_prefix: fixtures 4 | src_path: fixtures 5 | -------------------------------------------------------------------------------- /spec/fixtures/FlagFixtureSpec.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace spec\fixtures; 12 | 13 | use fixtures\FlagFixture; 14 | use fixtures\SimpleFixture; 15 | use PhpSpec\ObjectBehavior; 16 | 17 | class FlagFixtureSpec extends ObjectBehavior 18 | { 19 | function let() 20 | { 21 | $this->beConstructedWith('Read'); 22 | } 23 | 24 | function it_is_initializable() 25 | { 26 | $this->shouldHaveType(FlagFixture::class); 27 | } 28 | 29 | function it_should_be_constructable_with_a_value() 30 | { 31 | $this->beConstructedWith(7); 32 | 33 | $this->getValue()->shouldBeEqualTo(7); 34 | } 35 | 36 | function it_should_be_constructable_with_an_object() 37 | { 38 | $this->beConstructedWith(new FlagFixture('Execute')); 39 | 40 | $this->getValue()->shouldBeEqualTo(4); 41 | } 42 | 43 | function it_should_add_a_flag_by_name() 44 | { 45 | $this->add('Write')->getValue()->shouldBeEqualTo(3); 46 | } 47 | 48 | function it_should_add_a_flag_by_value() 49 | { 50 | $this->add(2)->getValue()->shouldBeEqualTo(3); 51 | } 52 | 53 | function it_should_add_a_flag_by_object() 54 | { 55 | $this->add(new FlagFixture('Write'))->getValue()->shouldBeEqualTo(3); 56 | } 57 | 58 | function it_should_only_add_flag_objects_that_are_instances_of_itself() 59 | { 60 | $this->add(new SimpleFixture('Monday'))->getValue()->shouldBeEqualTo(1); 61 | } 62 | 63 | function it_should_add_multiple_values_to_the_flag() 64 | { 65 | $this->add('Write', new FlagFixture('Execute'))->getValue()->shouldBeEqualTo(7); 66 | } 67 | 68 | function it_should_not_add_a_flag_that_already_exists() 69 | { 70 | $this->add('Read')->getValue()->shouldBeEqualTo(1); 71 | } 72 | 73 | function it_should_remove_a_flag_by_name() 74 | { 75 | $this->remove('Read')->getValue()->shouldBeEqualTo(0); 76 | } 77 | 78 | function it_should_remove_a_flag_by_value() 79 | { 80 | $this->remove(1)->getValue()->shouldBeEqualTo(0); 81 | } 82 | 83 | function it_should_remove_a_flag_by_object() 84 | { 85 | $this->remove(new FlagFixture('Read'))->getValue()->shouldBeEqualTo(0); 86 | } 87 | 88 | function it_should_remove_multiple_flags() 89 | { 90 | $this->beConstructedWith(7); 91 | 92 | $this->remove('Read', new FlagFixture('Write'))->getValue()->shouldBeEqualTo(4); 93 | } 94 | 95 | function it_should_not_remove_a_flag_that_doesnt_exist() 96 | { 97 | $this->remove('Write')->getValue()->shouldBeEqualTo(1); 98 | } 99 | 100 | function it_should_check_if_a_flag_exists() 101 | { 102 | $this->has('Read')->shouldBeEqualTo(true); 103 | } 104 | 105 | function it_should_check_if_a_flag_does_not_exist() 106 | { 107 | $this->has('Write')->shouldBeEqualTo(false); 108 | } 109 | 110 | function it_should_be_case_insensitive_checking_a_flag() 111 | { 112 | $this->has('ReAd')->shouldBeEqualTo(true); 113 | } 114 | 115 | function it_should_be_case_insensitive_adding_a_flag() 116 | { 117 | $this->add('WrItE')->getValue()->shouldBeEqualTo(3); 118 | } 119 | 120 | function it_should_be_case_insensitive_removing_a_flag() 121 | { 122 | $this->remove('ReAd')->getValue()->shouldBeEqualTo(0); 123 | } 124 | 125 | function it_should_get_all_the_names_the_flag_represents() 126 | { 127 | $this->beConstructedWith(3); 128 | 129 | $this->getNames()->shouldBeEqualTo(['Read', 'Write']); 130 | } 131 | 132 | function it_should_have_a_string_representation() 133 | { 134 | $this->beConstructedWith(3); 135 | 136 | $this->__toString()->shouldBeEqualTo('Read,Write'); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /spec/fixtures/SimpleFixtureSpec.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace spec\fixtures; 12 | 13 | use fixtures\SimpleFixture; 14 | use PhpSpec\ObjectBehavior; 15 | 16 | class SimpleFixtureSpec extends ObjectBehavior 17 | { 18 | function let() 19 | { 20 | $this->beConstructedWith(1); 21 | } 22 | 23 | function it_is_initializable() 24 | { 25 | $this->shouldHaveType(SimpleFixture::class); 26 | } 27 | 28 | function it_should_have_a_string_representation() 29 | { 30 | $this->__toString()->shouldBeEqualTo('Monday'); 31 | } 32 | 33 | function it_should_get_the_value_of_the_enum() 34 | { 35 | $this->getValue()->shouldBeEqualTo(1); 36 | } 37 | 38 | function it_should_get_the_name_that_the_enum_represents() 39 | { 40 | $this->getName()->shouldBeEqualTo('Monday'); 41 | } 42 | 43 | function it_should_get_all_possible_names_for_the_enum() 44 | { 45 | $this::names()->shouldBeEqualTo([ 46 | "Monday", 47 | "Tuesday", 48 | "Wednesday", 49 | "Thursday", 50 | "Friday", 51 | "Saturday", 52 | "Sunday", 53 | ]); 54 | } 55 | 56 | function it_should_get_all_possible_values_for_the_enum() 57 | { 58 | $this::values()->shouldBeEqualTo([ 59 | 1, 60 | 2, 61 | 3, 62 | 4, 63 | 5, 64 | 6, 65 | 7, 66 | ]); 67 | } 68 | 69 | function it_should_have_an_array_representation() 70 | { 71 | $this->toArray()->shouldBeEqualTo([ 72 | 'Monday' => 1, 73 | 'Tuesday' => 2, 74 | 'Wednesday' => 3, 75 | 'Thursday' => 4, 76 | 'Friday' => 5, 77 | 'Saturday' => 6, 78 | 'Sunday' => 7, 79 | ]); 80 | } 81 | 82 | function it_should_check_if_an_enum_name_is_valid() 83 | { 84 | $this::isValidName('Monday')->shouldBeEqualTo(true); 85 | $this::isValidName('FooDay')->shouldBeEqualTo(false); 86 | } 87 | 88 | function it_should_check_if_an_enum_name_is_valid_regardless_of_case() 89 | { 90 | $this::isValidName('mOnDaY')->shouldBeEqualTo(true); 91 | } 92 | 93 | function it_should_check_if_an_enum_value_is_valid() 94 | { 95 | $this::isValidValue(1)->shouldBeEqualTo(true); 96 | $this::isValidValue(8)->shouldBeEqualTo(false); 97 | } 98 | 99 | function it_should_get_an_enum_value_for_a_name() 100 | { 101 | $this::getNameValue('Monday')->shouldBeEqualTo(1); 102 | } 103 | 104 | function it_should_throw_an_exception_getting_a_value_for_a_name_that_doesnt_exist() 105 | { 106 | $this->shouldThrow('\InvalidArgumentException')->during('getNameValue', ['FooDay']); 107 | } 108 | 109 | function it_should_get_an_enum_name_for_a_value() 110 | { 111 | $this::getValueName(1)->shouldBeEqualTo('Monday'); 112 | } 113 | 114 | function it_should_throw_an_exception_getting_a_name_for_a_value_that_doesnt_exist() 115 | { 116 | $this->shouldThrow('\InvalidArgumentException')->during('getValueName', [8]); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Enums/EnumTrait.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace Enums; 12 | 13 | /** 14 | * Provides a base for the flag and simple enum. 15 | * 16 | * @author Chad Sikorra 17 | */ 18 | trait EnumTrait 19 | { 20 | /** 21 | * @var mixed 22 | */ 23 | protected $value; 24 | 25 | /** 26 | * @var array 27 | */ 28 | protected static $constants; 29 | 30 | /** 31 | * @var array 32 | */ 33 | protected static $lcKeyMap = []; 34 | 35 | /** 36 | * Get the value this enum represents. 37 | * 38 | * @return mixed 39 | */ 40 | public function getValue() 41 | { 42 | return $this->value; 43 | } 44 | 45 | /** 46 | * Get all the names for the enum. 47 | * 48 | * @return array 49 | */ 50 | public static function names() 51 | { 52 | static::initialize(); 53 | 54 | return array_keys(static::$constants); 55 | } 56 | 57 | /** 58 | * Get all the values for the enum. 59 | * 60 | * @return array 61 | */ 62 | public static function values() 63 | { 64 | static::initialize(); 65 | 66 | return array_values(static::$constants); 67 | } 68 | 69 | /** 70 | * Get the enum as its key => value pairs. 71 | * 72 | * @return array 73 | */ 74 | public static function toArray() 75 | { 76 | static::initialize(); 77 | 78 | return static::$constants; 79 | } 80 | 81 | /** 82 | * Check if a specific enum exists by name. 83 | * 84 | * @param string $name 85 | * @return bool 86 | */ 87 | public static function isValidName($name) 88 | { 89 | static::initialize(); 90 | 91 | return isset(static::$lcKeyMap[strtolower($name)]); 92 | } 93 | 94 | /** 95 | * Check if a specific enum exists by value. 96 | * 97 | * @param $value 98 | * @param bool $strict 99 | * @return bool 100 | */ 101 | public static function isValidValue($value, $strict = false) 102 | { 103 | static::initialize(); 104 | 105 | return (array_search($value, static::$constants, $strict) !== false); 106 | } 107 | 108 | /** 109 | * Get the enum name from its value. 110 | * 111 | * @param mixed $value 112 | * @param bool $strict 113 | * @return string 114 | */ 115 | public static function getValueName($value, $strict = false) 116 | { 117 | if (!static::isValidValue($value)) { 118 | throw new \InvalidArgumentException('No enum name was found for the value supplied.'); 119 | } 120 | 121 | return array_search($value, static::$constants, $strict); 122 | } 123 | 124 | /** 125 | * Get the enum value from its name. 126 | * 127 | * @param string $name 128 | * @return mixed 129 | */ 130 | public static function getNameValue($name) 131 | { 132 | static::initialize(); 133 | 134 | if (!static::isValidName($name)) { 135 | throw new \InvalidArgumentException(sprintf( 136 | 'The enum name "%s" is not valid. Expected one of: %s', 137 | $name, 138 | implode(', ', static::names()) 139 | )); 140 | } 141 | 142 | return static::$constants[static::$lcKeyMap[strtolower($name)]]; 143 | } 144 | 145 | /** 146 | * Cache the enum array statically so we only have to do reflection a single time. 147 | */ 148 | protected static function initialize() 149 | { 150 | $class = static::class; 151 | 152 | if (static::$constants === null) { 153 | static::$constants = (new \ReflectionClass($class))->getConstants(); 154 | 155 | foreach (static::names() as $name) { 156 | static::$lcKeyMap[strtolower($name)] = $name; 157 | } 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/Enums/FlagEnumInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace Enums; 12 | 13 | /** 14 | * Flag based enum interface. 15 | * 16 | * @author Chad Sikorra 17 | */ 18 | interface FlagEnumInterface 19 | { 20 | /** 21 | * Get the enum names this flag contains. 22 | * 23 | * @return string[] 24 | */ 25 | public function getNames(); 26 | 27 | /** 28 | * Get the value of this flag enum. 29 | * 30 | * @return mixed 31 | */ 32 | public function getValue(); 33 | 34 | /** 35 | * Check if the flag has this enum name/value. 36 | * 37 | * @param mixed $flag 38 | * @return bool 39 | */ 40 | public function has($flag); 41 | 42 | /** 43 | * Add an enum name/value to the flag. 44 | * 45 | * @param array ...$flag 46 | * @return $this 47 | */ 48 | public function add(...$flag); 49 | 50 | /** 51 | * Remove an enum name/value from the flag. 52 | * 53 | * @param array ...$flag 54 | * @return $this 55 | */ 56 | public function remove(...$flag); 57 | } 58 | -------------------------------------------------------------------------------- /src/Enums/FlagEnumTrait.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace Enums; 12 | 13 | /** 14 | * Provides a flag based enum. 15 | * 16 | * @author Chad Sikorra 17 | */ 18 | trait FlagEnumTrait 19 | { 20 | use EnumTrait; 21 | 22 | /** 23 | * @param int|string $flags 24 | */ 25 | public function __construct($flags = 0) 26 | { 27 | if ($flags instanceof static) { 28 | $this->value = $flags->getValue(); 29 | } elseif (static::isValidName($flags)) { 30 | $this->value = static::getNameValue($flags); 31 | } else { 32 | $this->value = (int) $flags; 33 | } 34 | } 35 | 36 | /** 37 | * Add a flag to the value. 38 | * 39 | * @param int[]|string[]|FlagEnumTrait[] ...$flags 40 | * @return $this 41 | */ 42 | public function add(...$flags) 43 | { 44 | foreach ($flags as $flag) { 45 | if ($this->has($flag)) { 46 | continue; 47 | } 48 | foreach ($this->getValuesFromFlagOrEnum($flag) as $value) { 49 | $this->value = $this->value | (int) $value; 50 | } 51 | } 52 | 53 | return $this; 54 | } 55 | 56 | /** 57 | * Remove a flag from the value. 58 | * 59 | * @param int[]|string[]|FlagEnumTrait[] ...$flags 60 | * @return $this 61 | */ 62 | public function remove(...$flags) 63 | { 64 | foreach ($flags as $flag) { 65 | if (!$this->has($flag)) { 66 | continue; 67 | } 68 | foreach ($this->getValuesFromFlagOrEnum($flag) as $value) { 69 | $this->value = $this->value ^ (int) $value; 70 | } 71 | } 72 | 73 | return $this; 74 | } 75 | 76 | /** 77 | * Given an enum name, value, or another FlagEnumTrait instance, check if this instance has the same value(s). 78 | * 79 | * @param string|int|FlagEnumTrait $flag 80 | * @return bool 81 | */ 82 | public function has($flag) 83 | { 84 | $values = $this->getValuesFromFlagOrEnum($flag); 85 | 86 | if (empty($values)) { 87 | return false; 88 | } 89 | 90 | foreach ($values as $value) { 91 | if (!(bool) ($this->value & $value)) { 92 | return false; 93 | } 94 | } 95 | 96 | return true; 97 | } 98 | 99 | /** 100 | * Get an array of all the enum names this flag instance represents. 101 | * 102 | * @return array 103 | */ 104 | public function getNames() 105 | { 106 | $enums = []; 107 | 108 | foreach (static::toArray() as $name => $value) { 109 | if ($this->has($value)) { 110 | $enums[] = $name; 111 | } 112 | } 113 | 114 | return $enums; 115 | } 116 | 117 | /** 118 | * Returns a comma-delimited list of enum names this instance represents. 119 | * 120 | * @return string 121 | */ 122 | public function __toString() 123 | { 124 | return implode(',', $this->getNames()); 125 | } 126 | 127 | /** 128 | * Given an enum name, enum value, or flag enum instance, get the array of values it represents. 129 | * 130 | * @param int|string|FlagEnumTrait $flag 131 | * @return array 132 | */ 133 | protected function getValuesFromFlagOrEnum($flag) 134 | { 135 | $values = []; 136 | 137 | if ($flag instanceof static) { 138 | foreach ($flag->getNames() as $enum) { 139 | $values[] = static::getNameValue($enum); 140 | } 141 | } elseif (static::isValidName((string) $flag)) { 142 | $values[] = static::getNameValue((string) $flag); 143 | } elseif (is_numeric($flag)) { 144 | $values[] = $flag; 145 | } 146 | 147 | return $values; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/Enums/SimpleEnumInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace Enums; 12 | 13 | /** 14 | * Simple enum interface. 15 | * 16 | * @author Chad Sikorra 17 | */ 18 | interface SimpleEnumInterface 19 | { 20 | /** 21 | * Get the enum name. 22 | * 23 | * @return string 24 | */ 25 | public function getName(); 26 | 27 | /** 28 | * Get the enum value. 29 | * 30 | * @return mixed 31 | */ 32 | public function getValue(); 33 | } 34 | -------------------------------------------------------------------------------- /src/Enums/SimpleEnumTrait.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | namespace Enums; 12 | 13 | /** 14 | * Provides a simple enum. 15 | * 16 | * @author Chad Sikorra 17 | */ 18 | trait SimpleEnumTrait 19 | { 20 | use EnumTrait; 21 | 22 | /** 23 | * @param mixed $value 24 | */ 25 | public function __construct($value) 26 | { 27 | if ($value instanceof static) { 28 | $this->value = $value->getValue(); 29 | } elseif (static::isValidName($value)) { 30 | $this->value = self::getNameValue($value); 31 | } elseif (static::isValidValue($value, true)) { 32 | $this->value = $value; 33 | } else { 34 | throw new \InvalidArgumentException(sprintf( 35 | 'Invalid enum name/value "%s". Expected one of: %s', 36 | $value, 37 | implode(', ', static::names()) 38 | )); 39 | } 40 | } 41 | 42 | /** 43 | * Get the name this enum represents. 44 | * 45 | * @return string 46 | */ 47 | public function getName() 48 | { 49 | return static::getValueName($this->value); 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | public function __toString() 56 | { 57 | return $this->getName(); 58 | } 59 | } 60 | --------------------------------------------------------------------------------