Passed
Push — master ( 8b14d6...99e35d )
by Константин
05:45
created

EnumType::requiresSQLCommentHint()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Premier\Enum\Doctrine;
6
7
use function assert;
8
use Doctrine\DBAL\Platforms\AbstractPlatform;
9
use Doctrine\DBAL\Types\ConversionException;
10
use Doctrine\DBAL\Types\Type;
11
use function filter_var;
12
use InvalidArgumentException;
13
use function is_subclass_of;
14
use Premier\Enum\Enum;
15
use function sprintf;
16
17
/**
18
 * @author Konstantin Grachev <[email protected]>
19
 */
20
final class EnumType extends Type
21
{
22
    /**
23
     * @var string
24
     */
25
    private $class;
26
27
    /**
28
     * @var string
29
     */
30
    private $name;
31
32
    /**
33
     * @var string
34
     */
35
    private $property;
36
37
    /**
38
     * @psalm-param class-string<Enum> $class
39
     */
40 1
    public static function register(string $class, string $name, string $property = 'id'): void
41
    {
42 1
        if (!is_subclass_of($class, Enum::class, true)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Premier\Enum\Enum::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
43
            throw new InvalidArgumentException(sprintf('%s is not child of %s', $class, Enum::class));
44
        }
45
46 1
        Type::addType($name, self::class);
47 1
        $type = Type::getType($name);
48 1
        assert($type instanceof self);
49
50 1
        $type->class = $class;
51 1
        $type->name = $name;
52 1
        $type->property = $property;
53 1
    }
54
55
    public function getName(): string
56
    {
57
        return $this->name;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 2
    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
64
    {
65 2
        if ('id' === $this->property) {
66 1
            return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
67
        }
68
69 1
        return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 4
    public function convertToPHPValue($value, AbstractPlatform $platform): ?Enum
76
    {
77 4
        if (null === $value) {
78
            return null;
79
        }
80
81 4
        $class = $this->class;
82 4
        if ($value instanceof $class) {
83
            assert($value instanceof Enum);
0 ignored issues
show
Bug introduced by
The class Premier\Enum\Enum does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
84
85
            return $value;
86
        }
87
88 4
        if ('id' === $this->property) {
89 2
            if (false === $id = filter_var($value, FILTER_VALIDATE_INT)) {
90
                throw ConversionException::conversionFailed($value, $this->getName());
91
            }
92
93 2
            $value = $id;
94
        }
95
96
        /** @var callable $callable */
97 4
        $callable = [$class, 'from'];
98 4
        $enum = $callable($this->property, $value);
99
100 4
        if (!$enum instanceof $class) {
101
            throw ConversionException::conversionFailed($value, $this->getName());
102
        }
103
104 4
        assert($enum instanceof Enum);
0 ignored issues
show
Bug introduced by
The class Premier\Enum\Enum does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
105
106 4
        return $enum;
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112 4
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
113
    {
114 4
        if (null === $value) {
115
            return null;
116
        }
117
118 4
        $class = $this->class;
119 4
        if (!$value instanceof $class) {
120
            throw ConversionException::conversionFailed($value, $this->getName());
121
        }
122
123 4
        assert($value instanceof Enum);
0 ignored issues
show
Bug introduced by
The class Premier\Enum\Enum does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
124
125 4
        return $value->get($this->property);
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131
    public function requiresSQLCommentHint(AbstractPlatform $platform): bool
132
    {
133
        return true;
134
    }
135
}
136