Passed
Push — master ( f34f5c...ba26d1 )
by 4kizuki
02:19
created

Enum::_init()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 11
cts 11
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 3
nop 0
crap 5
1
<?php
2
3
namespace Akizuki\enum;
4
5
use Akizuki\enum\Exceptions\ {
6
    EnumConstantTypeException,
7
    InvalidInitializerException,
8
    DuplicatedConstantException
9
};
10
use BadMethodCallException;
11
use ReflectionClass;
12
use Akizuki\BSC\StandardClass;
13
14
/**
15
 * [ Abstract Class ] Enumeration
16
 *
17
 * Provides basic function of Enumeration.
18
 *
19
 * @author 4kizuki <[email protected]>
20
 * @copyright 2017 4kizuki. All Rights Reserved.
21
 * @package 4kizuki/php-enum
22
 * @since 1.0.0
23
 */
24
abstract class Enum extends StandardClass {
25
26
    private static $___constants = [ ];
27
    protected $scalar;
28
29 14
    public function __construct( $scalar ) {
30
31 14
        self::_init( );
32
33 8
        if( !self::_validate_constants( $scalar ) or !isset( self::$___constants[ static::class ][ 1 ][ $scalar ] ) )
34 5
            throw new InvalidInitializerException;
35
36 3
        $this->scalar = $scalar;
37
38 3
    }
39
40 5
    final public static function __callStatic( string $name, array $args ) {
41
42 5
        if( !empty( $args ) ) throw new BadMethodCallException;
43
44 4
        self::_init( );
45
46 2
        if( !isset( self::$___constants[ static::class ][ 0 ][ $name ] ) )
47 1
            throw new InvalidInitializerException;
48
49 1
        $class = static::class;
50 1
        return new $class( self::$___constants[ static::class ][ 0 ][ $name ] );
51
52
    }
53
54 17
    private static function _init( ) {
55
56 17
        if( !isset( self::$___constants[ static::class ] ) ) {
57
58 11
            $csts = ( new ReflectionClass( static::class ) )->getConstants( );
59 11
            $vals = [ ];
60
61 11
            foreach( $csts as $key => $value ) {
62
63 11
                if( !static::_validate_constants( $value ) )
64 7
                    throw new EnumConstantTypeException( static::class, $key, gettype( $value ) );
65
66 5
                if( isset( $vals[ $value ] ) )
67 1
                    throw new DuplicatedConstantException( static::class, $key );
68
                
69 5
                $vals[$value] = true;
70
71
            }
72
73 3
            self::$___constants[ static::class ] = [ $csts, $vals ];
74
75
        }
76
77 9
    }
78
79
    public function value( ) { return $this->scalar; }
80
81 12
    protected static function _validate_constants( $value ) : bool {
82
83 12
        if( is_int( $value ) ) return true;
84 10
        if( is_string( $value ) && $value !== '' ) return true;
85 6
        return false;
86
87
    }
88
89
}