Completed
Push — master ( 95ed0c...56cd54 )
by Alejandro
03:27
created

PhpEnumType::convertToPHPValue()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 18
c 0
b 0
f 0
ccs 12
cts 12
cp 1
rs 9.4285
cc 3
eloc 11
nc 3
nop 2
crap 3
1
<?php
2
namespace Acelaya\Doctrine\Type;
3
4
use Acelaya\Doctrine\Exception\InvalidArgumentException;
5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\Platforms\AbstractPlatform;
7
use Doctrine\DBAL\Types\Type;
8
use MyCLabs\Enum\Enum;
9
10
class PhpEnumType extends Type
11
{
12
    /**
13
     * @var string
14
     */
15
    private $name;
16
    /**
17
     * @var string
18
     */
19
    private $enumClass = Enum::class;
20
21
    /**
22
     * Gets the name of this type.
23
     *
24
     * @return string
25
     */
26 1
    public function getName()
27
    {
28 1
        return $this->name ?: 'enum';
29
    }
30
31
    /**
32
     * Gets the SQL declaration snippet for a field of this type.
33
     *
34
     * @param array $fieldDeclaration The field declaration.
35
     * @param AbstractPlatform $platform The currently used database platform.
36
     *
37
     * @return string
38
     */
39 1
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
40
    {
41 1
        return $platform->getVarcharTypeDeclarationSQL([]);
42
    }
43
44
    /**
45
     * @param string $value
46
     * @param AbstractPlatform $platform
47
     * @return mixed
48
     * @throws InvalidArgumentException
49
     */
50 3
    public function convertToPHPValue($value, AbstractPlatform $platform)
51
    {
52 3
        if ($value === null) {
53 1
            return null;
54
        }
55
56 2
        $isValid = call_user_func([$this->enumClass, 'isValid'], $value);
57 2
        if (! $isValid) {
58 1
            throw new InvalidArgumentException(sprintf(
59 1
                'The value "%s" is not valid for the enum "%s". Expected one of ["%s"]',
60 1
                $value,
61 1
                $this->enumClass,
62 1
                implode('", "', call_user_func([$this->enumClass, 'toArray']))
63 1
            ));
64
        }
65
66 1
        return new $this->enumClass($value);
67
    }
68
69 1
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
70
    {
71 1
        return ($value === null) ? null : (string) $value;
72
    }
73
74
    /**
75
     * @param $typeNameOrEnumClass
76
     * @param null $enumClass
77
     * @throws InvalidArgumentException
78
     * @throws DBALException
79
     */
80 9
    public static function registerEnumType($typeNameOrEnumClass, $enumClass = null)
81
    {
82 9
        $typeName = $typeNameOrEnumClass;
83 9
        $enumClass = $enumClass ?: $typeNameOrEnumClass;
84
85 9
        if (! is_subclass_of($enumClass, Enum::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \MyCLabs\Enum\Enum::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
86 1
            throw new InvalidArgumentException(sprintf(
87 1
                'Provided enum class "%s" is not valid. Enums must extend "%s"',
88 1
                $enumClass,
89
                Enum::class
90 1
            ));
91
        }
92
93
        // Register and customize the type
94 8
        self::addType($typeName, static::class);
95
        /** @var PhpEnumType $type */
96 8
        $type = self::getType($typeName);
97 8
        $type->name = $typeName;
98 8
        $type->enumClass = $enumClass;
99 8
    }
100
101
    /**
102
     * @param array $types
103
     * @throws InvalidArgumentException
104
     * @throws DBALException
105
     */
106 2
    public static function registerEnumTypes(array $types)
107
    {
108 2
        foreach ($types as $typeName => $enumClass) {
109 2
            $typeName = is_string($typeName) ? $typeName : $enumClass;
110 2
            static::registerEnumType($typeName, $enumClass);
111 2
        }
112 2
    }
113
}
114