Skip to content
This repository was archived by the owner on Dec 26, 2023. It is now read-only.

Commit a97ffb1

Browse files
author
Petr Knap
committed
AbstractEnum 0.1
1 parent c610808 commit a97ffb1

File tree

7 files changed

+295
-0
lines changed

7 files changed

+295
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
vendor
3+
phpunit.log
4+
composer.lock

composer.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "petrknap/php-enum",
3+
"description": "Enumerated type for PHP",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Petr Knap",
8+
"email": "dev@petrknap.cz",
9+
"homepage": "http://petrknap.cz",
10+
"role": "Developer"
11+
}
12+
],
13+
"homepage": "https://github.com/petrknap/php-enum",
14+
"config": {
15+
"preferred-install": "dist"
16+
},
17+
"require": {
18+
"php": ">=5.4"
19+
},
20+
"require-dev": {
21+
"phpunit/phpunit": "4.*"
22+
},
23+
"scripts": {
24+
"test": [
25+
"./vendor/bin/phpunit"
26+
],
27+
"post-autoload-dump": [
28+
"@test"
29+
]
30+
},
31+
"autoload": {
32+
"psr-4": {
33+
"PetrKnap\\Php\\Enum\\": "src/Enum",
34+
"PetrKnap\\Php\\Enum\\Test\\": "tests/Enum"
35+
}
36+
}
37+
}

phpunit.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<phpunit bootstrap="./vendor/autoload.php">
2+
<testsuites>
3+
<testsuite>
4+
<directory suffix="Test.php">./tests</directory>
5+
</testsuite>
6+
</testsuites>
7+
<logging>
8+
<log type="testdox-text" target="./tests/phpunit.log"/>
9+
</logging>
10+
</phpunit>

src/Enum/AbstractEnum.php

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
namespace PetrKnap\Php\Enum;
4+
5+
/**
6+
* Abstract enum object
7+
*
8+
* @author Petr Knap <dev@petrknap.cz>
9+
* @since 2016-01-23
10+
* @package PetrKnap\Php\Enum
11+
* @version 0.1
12+
* @license https://github.com/petrknap/php-enum/blob/master/LICENSE MIT
13+
*/
14+
abstract class AbstractEnum
15+
{
16+
/**
17+
* @var self[][]
18+
*/
19+
private static $instances;
20+
21+
/**
22+
* @var mixed[]
23+
*/
24+
private $items = [];
25+
26+
/**
27+
* @var mixed
28+
*/
29+
private $key;
30+
31+
/**
32+
* @var mixed
33+
*/
34+
private $value;
35+
36+
/**
37+
* @param mixed $key
38+
* @throws EnumException
39+
*/
40+
public function __construct($key)
41+
{
42+
$this->key = $key;
43+
$this->value = $this->get($key);
44+
}
45+
46+
/**
47+
* Creates magical factories for easier access to enum
48+
*
49+
* @param mixed $key enum key
50+
* @param array $args ignored
51+
* @return mixed
52+
*/
53+
public static function __callStatic($key, array $args)
54+
{
55+
$className = get_called_class();
56+
57+
$instances = &self::$instances[$className];
58+
59+
if (!is_array($instances)) {
60+
$instances = [];
61+
}
62+
63+
$instance = &$instances[$key];
64+
65+
if (!($instance instanceof $className)) {
66+
$instance = new $className($key);
67+
}
68+
69+
return $instance;
70+
}
71+
72+
/**
73+
* @return mixed
74+
*/
75+
public function getKey()
76+
{
77+
return $this->key;
78+
}
79+
80+
/**
81+
* @return mixed
82+
*/
83+
public function getValue()
84+
{
85+
return $this->value;
86+
}
87+
88+
/**
89+
* @param mixed[] $items
90+
*/
91+
protected function setItems(array $items)
92+
{
93+
$this->items = $items;
94+
}
95+
96+
/**
97+
* @param mixed $key
98+
* @return bool
99+
*/
100+
private function exists($key)
101+
{
102+
return array_key_exists($key, $this->items);
103+
}
104+
105+
/**
106+
* @param mixed $key
107+
* @return mixed
108+
* @throws EnumException
109+
*/
110+
private function get($key)
111+
{
112+
if (!$this->exists($key)) {
113+
throw new EnumException(
114+
sprintf(
115+
"%s does not exists in %s",
116+
$key,
117+
get_called_class()
118+
),
119+
EnumException::OUT_OF_RANGE
120+
);
121+
}
122+
123+
return $this->items[$key];
124+
}
125+
}

src/Enum/EnumException.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace PetrKnap\Php\Enum;
4+
5+
class EnumException extends \Exception
6+
{
7+
const GENERAL = 0;
8+
const OUT_OF_RANGE = 1;
9+
}

tests/Enum/EnumTest.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace PetrKnap\Php\Enum\Test;
4+
5+
use PetrKnap\Php\Enum\EnumException;
6+
use PetrKnap\Php\Enum\Test\EnumTest\EnumMock;
7+
8+
class EnumTest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function goodKeyProvider()
11+
{
12+
return [["A", "a"], ["B", "b"]];
13+
}
14+
15+
public function wrongKeyProvider()
16+
{
17+
return [["C"], ["D"]];
18+
}
19+
20+
/**
21+
* @dataProvider goodKeyProvider
22+
* @param string $key
23+
* @param string $value
24+
*/
25+
public function testEnumDirectConstruction_GoodKey($key, $value)
26+
{
27+
$enum = new EnumMock($key);
28+
29+
$this->assertInstanceOf(EnumMock::getClass(), $enum);
30+
$this->assertSame($key, $enum->getKey());
31+
$this->assertSame($value, $enum->getValue());
32+
}
33+
34+
/**
35+
* @dataProvider wrongKeyProvider
36+
* @param string $key
37+
*/
38+
public function testEnumDirectConstruction_WrongKey($key)
39+
{
40+
$this->setExpectedException(
41+
get_class(new EnumException()),
42+
"",
43+
EnumException::OUT_OF_RANGE
44+
);
45+
46+
new EnumMock($key);
47+
}
48+
49+
/**
50+
* @dataProvider goodKeyProvider
51+
* @param string $key
52+
* @param string $value
53+
*/
54+
public function testEnumMagicConstruction_GoodKey($key, $value)
55+
{
56+
/** @var EnumMock $enum */
57+
$enum = EnumMock::$key();
58+
59+
$this->assertInstanceOf(EnumMock::getClass(), $enum);
60+
$this->assertSame($key, $enum->getKey());
61+
$this->assertSame($value, $enum->getValue());
62+
}
63+
64+
/**
65+
* @dataProvider wrongKeyProvider
66+
* @param string $key
67+
*/
68+
public function testEnumMagicConstruction_WrongKey($key)
69+
{
70+
$this->setExpectedException(
71+
get_class(new EnumException()),
72+
"",
73+
EnumException::OUT_OF_RANGE
74+
);
75+
76+
EnumMock::$key();
77+
}
78+
}

tests/Enum/EnumTest/EnumMock.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace PetrKnap\Php\Enum\Test\EnumTest;
4+
5+
use PetrKnap\Php\Enum\AbstractEnum;
6+
7+
/**
8+
* @method static EnumMock A()
9+
* @method static EnumMock B()
10+
*/
11+
class EnumMock extends AbstractEnum
12+
{
13+
public function __construct($key)
14+
{
15+
$this->setItems([
16+
"A" => "a",
17+
"B" => "b"
18+
]);
19+
20+
parent::__construct($key);
21+
}
22+
23+
/**
24+
* Returns class name (PHP <5.5)
25+
*
26+
* @return string
27+
*/
28+
public static function getClass()
29+
{
30+
return __CLASS__;
31+
}
32+
}

0 commit comments

Comments
 (0)