Completed
Pull Request — master (#30)
by
unknown
09:57
created

EnumProvider::randomEnum()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the "elao/enum" package.
5
 *
6
 * Copyright (C) 2017 Elao
7
 *
8
 * @author Elao <[email protected]>
9
 */
10
11
namespace Elao\Enum\Bridge\Faker\Provider;
12
13
use Elao\Enum\EnumInterface;
14
use Elao\Enum\Exception\InvalidArgumentException;
15
use Elao\Enum\FlaggedEnum;
16
17
class EnumProvider
18
{
19
    /**
20
     * Enum mapping as an array with :
21
     *
22
     * - alias for Enum class as key
23
     * - Enum FQCN as value
24
     *
25
     * Example :
26
     *
27
     * ```
28
     * [
29
     *   'Civility' => Civility::class,
30
     *   'Gender'   => Gender::class,
31
     * ]
32
     * ```
33
     *
34
     * @var array $enumMapping
35
     */
36
    private $enumMapping = [];
37
38
    public function __construct(array $enumMapping)
39
    {
40
        foreach ($enumMapping as $enumAlias => $enumClass) {
41
            $this->ensureEnumClass($enumClass);
42
            $this->enumMapping[$enumAlias] = $enumClass;
43
        }
44
    }
45
46
    /**
47
     * @param string $enumValueShortcut As <ENUM_CLASS_ALIAS>::<ENUM_VALUE_CONSTANT>
48
     *                                  Examples: 'Gender::MALE', 'Gender::FEMALE', 'Permissions::READ|WRITE', etc.
49
     *
50
     * @throws \InvalidArgumentException When the alias part of $enumValueShortcut is not a valid alias
51
     *
52
     * @return EnumInterface
53
     */
54
    public function enum(string $enumValueShortcut): EnumInterface
55
    {
56
        list($enumClassAlias, $constants) = explode('::', $enumValueShortcut);
57
58
        if (!array_key_exists($enumClassAlias, $this->enumMapping)) {
59
            throw new InvalidArgumentException("$enumClassAlias is not a valid alias");
60
        }
61
62
        /** @var EnumInterface $class */
63
        $class = $this->enumMapping[$enumClassAlias];
64
65
        $constants = explode('|', $constants);
66
67
        // Flagged Enum if $constants count is greater than one:
68
        if (count($constants) > 1) {
69
            if (!is_a($class, FlaggedEnum::class, true)) {
70
                throw new InvalidArgumentException("$class is not a valid FlaggedEnum");
71
            }
72
            $value = 0;
73
            foreach ($constants as $constant) {
74
                $value |= constant($class . '::' . $constant);
75
            }
76
        } else {
77
            $value = constant($class . '::' . current($constants));
78
        }
79
80
        return $class::get($value);
81
    }
82
83
    public function randomEnum(string $enumClassAlias): EnumInterface
84
    {
85
        if (!array_key_exists($enumClassAlias, $this->enumMapping)) {
86
            throw new InvalidArgumentException("$enumClassAlias is not a valid alias");
87
        }
88
89
        // Unimplemented yet
90
    }
91
92
    /**
93
     * Make sure that $enumClass is a proper Enum class. Throws exception otherwise.
94
     *
95
     * @param string $enumClass
96
     *
97
     * @throws \InvalidArgumentException When $enumClass is not a class or is not a proper Enum
98
     */
99
    private function ensureEnumClass(string $enumClass)
100
    {
101
        if (!is_a($enumClass, EnumInterface::class, true)) {
102
            throw new InvalidArgumentException("$enumClass is not a proper enum class");
103
        }
104
    }
105
}
106