Completed
Push — master ( 4a2095...b578cc )
by Artem
01:30
created

AbstractEnumType::getName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
/*
3
 * This file is part of the FreshDoctrineEnumBundle.
4
 *
5
 * (c) Artem Henvald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Fresh\DoctrineEnumBundle\DBAL\Types;
14
15
use Doctrine\DBAL\Platforms\AbstractPlatform;
16
use Doctrine\DBAL\Platforms\MySqlPlatform;
17
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
18
use Doctrine\DBAL\Platforms\SqlitePlatform;
19
use Doctrine\DBAL\Platforms\SQLServerPlatform;
20
use Doctrine\DBAL\Types\Type;
21
use Fresh\DoctrineEnumBundle\Exception\InvalidArgumentException;
22
23
/**
24
 * AbstractEnumType.
25
 *
26
 * Provides support of ENUM type for Doctrine in Symfony applications.
27
 *
28
 * @author Artem Henvald <[email protected]>
29
 * @author Ben Davies <[email protected]>
30
 * @author Jaik Dean <[email protected]>
31
 */
32
abstract class AbstractEnumType extends Type
33
{
34
    /** @var string */
35
    protected $name = '';
36
37
    /**
38
     * @var array|mixed[] Array of ENUM Values, where ENUM values are keys and their readable versions are values
39
     *
40
     * @static
41
     */
42
    protected static $choices = [];
43
44
    /**
45
     * {@inheritdoc}
46
     *
47
     * @throws InvalidArgumentException
48
     */
49
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
50
    {
51
        if (null === $value) {
52
            return null;
53
        }
54
55
        if (!isset(static::$choices[$value])) {
56
            throw new InvalidArgumentException(\sprintf('Invalid value "%s" for ENUM "%s".', $value, $this->getName()));
57
        }
58
59
        return $value;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function convertToPHPValue($value, AbstractPlatform $platform)
66
    {
67
        if (!isset(static::$choices[$value])) {
68
            return $value;
69
        }
70
71
        // Check whether choice list is using integers as values
72
        $choice = static::$choices[$value];
73
        $choices = \array_flip(static::$choices);
74
        if (\is_int($choices[$choice])) {
75
            return (int) $value;
76
        }
77
78
        return $value;
79
    }
80
81
    /**
82
     * Gets the SQL declaration snippet for a field of this type.
83
     *
84
     * @param mixed[]          $fieldDeclaration The field declaration
85
     * @param AbstractPlatform $platform         The currently used database platform
86
     *
87
     * @return string
88
     */
89
    public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
90
    {
91
        $values = \implode(
92
            ', ',
93
            \array_map(
94
                static function (string $value) {
95
                    return "'{$value}'";
96
                },
97
                static::getValues()
98
            )
99
        );
100
101
        switch (true) {
102
            case $platform instanceof SqlitePlatform:
103
                $sqlDeclaration = \sprintf('TEXT CHECK(%s IN (%s))', $fieldDeclaration['name'], $values);
104
105
                break;
106
            case $platform instanceof PostgreSqlPlatform:
107
            case $platform instanceof SQLServerPlatform:
108
                $sqlDeclaration = \sprintf('VARCHAR(255) CHECK(%s IN (%s))', $fieldDeclaration['name'], $values);
109
110
                break;
111
            default:
112
                $sqlDeclaration = \sprintf('ENUM(%s)', $values);
113
        }
114
115
        $defaultValue = static::getDefaultValue();
116
        if (null !== $defaultValue) {
117
            $sqlDeclaration .= \sprintf(' DEFAULT %s', $platform->quoteStringLiteral($defaultValue));
118
        }
119
120
        return $sqlDeclaration;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function requiresSQLCommentHint(AbstractPlatform $platform): bool
127
    {
128
        return true;
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134
    public function getName(): string
135
    {
136
        return $this->name ?: (string) \array_search(\get_class($this), self::getTypesMap(), true);
137
    }
138
139
    /**
140
     * Get readable choices for the ENUM field.
141
     *
142
     * @static
143
     *
144
     * @return string[]
145
     */
146
    public static function getChoices(): array
147
    {
148
        return \array_flip(static::$choices);
149
    }
150
151
    /**
152
     * Get values for the ENUM field.
153
     *
154
     * @static
155
     *
156
     * @return string[] Values for the ENUM field
157
     */
158
    public static function getValues(): array
159
    {
160
        return \array_keys(static::$choices);
161
    }
162
163
    /**
164
     * Get random value for the ENUM field.
165
     *
166
     * @static
167
     *
168
     * @return int|string
169
     */
170
    public static function getRandomValue()
171
    {
172
        $values = self::getValues();
173
        $randomKey = \random_int(0, \count($values) - 1);
174
175
        return $values[$randomKey];
176
    }
177
178
    /**
179
     * Get array of ENUM Values, where ENUM values are keys and their readable versions are values.
180
     *
181
     * @static
182
     *
183
     * @return string[] Array of values in readable format
184
     */
185
    public static function getReadableValues(): array
186
    {
187
        return static::$choices;
188
    }
189
190
    /**
191
     * Asserts that given choice exists in the array of ENUM values.
192
     *
193
     * @param string $value ENUM value
194
     *
195
     * @throws InvalidArgumentException
196
     */
197
    public static function assertValidChoice(string $value): void
198
    {
199
        if (!isset(static::$choices[$value])) {
200
            throw new InvalidArgumentException(\sprintf('Invalid value "%s" for ENUM type "%s".', $value, static::class));
201
        }
202
    }
203
204
    /**
205
     * Get value in readable format.
206
     *
207
     * @param string $value ENUM value
208
     *
209
     * @static
210
     *
211
     * @return string Value in readable format
212
     */
213
    public static function getReadableValue(string $value): string
214
    {
215
        static::assertValidChoice($value);
216
217
        return static::$choices[$value];
218
    }
219
220
    /**
221
     * Check if some string value exists in the array of ENUM values.
222
     *
223
     * @param string $value ENUM value
224
     *
225
     * @static
226
     *
227
     * @return bool
228
     */
229
    public static function isValueExist(string $value): bool
230
    {
231
        return isset(static::$choices[$value]);
232
    }
233
234
    /**
235
     * Get default value for DDL statement.
236
     *
237
     * @static
238
     *
239
     * @return string|null Default value for DDL statement
240
     */
241
    public static function getDefaultValue(): ?string
242
    {
243
        return null;
244
    }
245
246
    /**
247
     * Gets an array of database types that map to this Doctrine type.
248
     *
249
     * @param AbstractPlatform $platform
250
     *
251
     * @return string[]
252
     */
253
    public function getMappedDatabaseTypes(AbstractPlatform $platform): array
254
    {
255
        if ($platform instanceof MySqlPlatform) {
256
            return \array_merge(parent::getMappedDatabaseTypes($platform), ['enum']);
257
        }
258
259
        return parent::getMappedDatabaseTypes($platform);
260
    }
261
}
262