Skip to content

Commit 654e31e

Browse files
michnovkaogizanagi
authored andcommittedJun 7, 2024
DBAL4 changes
1 parent a1e8c52 commit 654e31e

File tree

7 files changed

+282
-212
lines changed

7 files changed

+282
-212
lines changed
 

‎composer.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
"require-dev": {
4242
"ext-pdo_sqlite": "*",
4343
"composer/semver": "^3.2",
44-
"doctrine/dbal": "^3.2",
44+
"doctrine/dbal": "^3.2|^4.0",
4545
"doctrine/doctrine-bundle": "^2.5",
46-
"doctrine/orm": "^2.10",
46+
"doctrine/orm": "^2.10|^3.0",
4747
"phpstan/phpstan": "^1.10",
4848
"phpstan/phpstan-symfony": "^1.2",
4949
"symfony/browser-kit": "^5.4|^6.3|^7.0",

‎src/Bridge/Doctrine/DBAL/Types/AbstractEnumType.php

+16-132
Original file line numberDiff line numberDiff line change
@@ -13,143 +13,27 @@
1313
namespace Elao\Enum\Bridge\Doctrine\DBAL\Types;
1414

1515
use Doctrine\DBAL\ParameterType;
16-
use Doctrine\DBAL\Platforms\AbstractPlatform;
17-
use Doctrine\DBAL\Types\Type;
18-
use Elao\Enum\Exception\InvalidArgumentException;
1916

20-
abstract class AbstractEnumType extends Type
21-
{
22-
private bool $isIntBackedEnum;
23-
24-
/**
25-
* The enum FQCN for which we should make the DBAL conversion.
26-
*
27-
* @psalm-return class-string<\BackedEnum>
28-
*/
29-
abstract protected function getEnumClass(): string;
30-
31-
/**
32-
* What should be returned on null value from the database.
33-
*/
34-
protected function onNullFromDatabase(): ?\BackedEnum
35-
{
36-
return null;
37-
}
38-
39-
/**
40-
* What should be returned on null value from PHP.
41-
*/
42-
protected function onNullFromPhp(): int|string|null
43-
{
44-
return null;
45-
}
46-
47-
/**
48-
* {@inheritdoc}
49-
*
50-
* @param \BackedEnum|int|string|null $value
51-
*/
52-
public function convertToDatabaseValue($value, AbstractPlatform $platform): string|int|null
53-
{
54-
if ($value !== null && !is_a($value, $this->getEnumClass())) {
55-
$throwException = true;
56-
if ($this->checkIfValueMatchesBackedEnumType($value)) {
57-
$value = $this->getEnumClass()::tryFrom($this->cast($value));
58-
if ($value !== null) {
59-
$throwException = false;
60-
}
61-
}
62-
63-
if ($throwException) {
64-
throw new InvalidArgumentException(sprintf(
65-
'Expected an instance of a %s. %s given.',
66-
$this->getEnumClass(),
67-
get_debug_type($value),
68-
));
69-
}
70-
}
71-
72-
if (null === $value) {
73-
return $this->onNullFromPhp();
74-
}
75-
76-
return $value->value;
77-
}
78-
79-
/**
80-
* {@inheritdoc}
81-
*
82-
* @param int|string|null $value The value to convert.
83-
*/
84-
public function convertToPHPValue($value, AbstractPlatform $platform): ?\BackedEnum
85-
{
86-
if (null === $value) {
87-
return $this->onNullFromDatabase();
88-
}
89-
90-
return $this->getEnumClass()::from($this->cast($value));
91-
}
92-
93-
/**
94-
* {@inheritdoc}
95-
*/
96-
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
17+
if (enum_exists(ParameterType::class)) {
18+
abstract class AbstractEnumType extends AbstractEnumTypeCommon
9719
{
98-
if ($this->isIntBackedEnum()) {
99-
return $platform->getIntegerTypeDeclarationSQL($column);
20+
/**
21+
* {@inheritdoc}
22+
*/
23+
public function getBindingType(): ParameterType
24+
{
25+
return $this->isIntBackedEnum() ? ParameterType::INTEGER : ParameterType::STRING;
10026
}
101-
102-
if (empty($column['length'])) {
103-
$column['length'] = 255;
104-
}
105-
106-
return method_exists($platform, 'getStringTypeDeclarationSQL') ?
107-
$platform->getStringTypeDeclarationSQL($column) :
108-
$platform->getVarcharTypeDeclarationSQL($column);
10927
}
110-
111-
/**
112-
* {@inheritdoc}
113-
*/
114-
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
28+
} else {
29+
abstract class AbstractEnumType extends AbstractEnumTypeCommon
11530
{
116-
return true;
117-
}
118-
119-
/**
120-
* {@inheritdoc}
121-
*/
122-
public function getBindingType(): int
123-
{
124-
return $this->isIntBackedEnum() ? ParameterType::INTEGER : ParameterType::STRING;
125-
}
126-
127-
/**
128-
* Cast the value from database to proper enumeration internal type.
129-
*/
130-
private function cast(int|string $value): int|string
131-
{
132-
return $this->isIntBackedEnum() ? (int) $value : (string) $value;
133-
}
134-
135-
private function checkIfValueMatchesBackedEnumType(mixed $value): bool
136-
{
137-
return ($this->isIntBackedEnum() && \is_int($value)) || (!$this->isIntBackedEnum() && \is_string($value));
138-
}
139-
140-
private function isIntBackedEnum(): bool
141-
{
142-
if (!isset($this->isIntBackedEnum)) {
143-
$r = new \ReflectionEnum($this->getEnumClass());
144-
145-
$this->isIntBackedEnum = 'int' === (string) $r->getBackingType();
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function getBindingType(): int
35+
{
36+
return $this->isIntBackedEnum() ? ParameterType::INTEGER : ParameterType::STRING;
14637
}
147-
148-
return $this->isIntBackedEnum;
149-
}
150-
151-
public function getName(): string
152-
{
153-
return $this->getEnumClass();
15438
}
15539
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the "elao/enum" package.
7+
*
8+
* Copyright (C) Elao
9+
*
10+
* @author Elao <contact@elao.com>
11+
*/
12+
13+
namespace Elao\Enum\Bridge\Doctrine\DBAL\Types;
14+
15+
use Doctrine\DBAL\Platforms\AbstractPlatform;
16+
use Doctrine\DBAL\Types\Type;
17+
use Elao\Enum\Exception\InvalidArgumentException;
18+
19+
abstract class AbstractEnumTypeCommon extends Type
20+
{
21+
private bool $isIntBackedEnum;
22+
23+
/**
24+
* The enum FQCN for which we should make the DBAL conversion.
25+
*
26+
* @psalm-return class-string<\BackedEnum>
27+
*/
28+
abstract protected function getEnumClass(): string;
29+
30+
/**
31+
* What should be returned on null value from the database.
32+
*/
33+
protected function onNullFromDatabase(): ?\BackedEnum
34+
{
35+
return null;
36+
}
37+
38+
/**
39+
* What should be returned on null value from PHP.
40+
*/
41+
protected function onNullFromPhp(): int|string|null
42+
{
43+
return null;
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*
49+
* @param \BackedEnum|int|string|null $value
50+
*/
51+
public function convertToDatabaseValue($value, AbstractPlatform $platform): string|int|null
52+
{
53+
if ($value !== null && !is_a($value, $this->getEnumClass())) {
54+
$throwException = true;
55+
if ($this->checkIfValueMatchesBackedEnumType($value)) {
56+
$value = $this->getEnumClass()::tryFrom($this->cast($value));
57+
if ($value !== null) {
58+
$throwException = false;
59+
}
60+
}
61+
62+
if ($throwException) {
63+
throw new InvalidArgumentException(sprintf(
64+
'Expected an instance of a %s. %s given.',
65+
$this->getEnumClass(),
66+
get_debug_type($value),
67+
));
68+
}
69+
}
70+
71+
if (null === $value) {
72+
return $this->onNullFromPhp();
73+
}
74+
75+
return $value->value;
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*
81+
* @param int|string|null $value The value to convert.
82+
*/
83+
public function convertToPHPValue($value, AbstractPlatform $platform): ?\BackedEnum
84+
{
85+
if (null === $value) {
86+
return $this->onNullFromDatabase();
87+
}
88+
89+
return $this->getEnumClass()::from($this->cast($value));
90+
}
91+
92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
96+
{
97+
if ($this->isIntBackedEnum()) {
98+
return $platform->getIntegerTypeDeclarationSQL($column);
99+
}
100+
101+
if (empty($column['length'])) {
102+
$column['length'] = 255;
103+
}
104+
105+
return method_exists($platform, 'getStringTypeDeclarationSQL') ?
106+
$platform->getStringTypeDeclarationSQL($column) :
107+
$platform->getVarcharTypeDeclarationSQL($column);
108+
}
109+
110+
/**
111+
* {@inheritdoc}
112+
*/
113+
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
114+
{
115+
return true;
116+
}
117+
118+
/**
119+
* Cast the value from database to proper enumeration internal type.
120+
*/
121+
private function cast(int|string $value): int|string
122+
{
123+
return $this->isIntBackedEnum() ? (int) $value : (string) $value;
124+
}
125+
126+
private function checkIfValueMatchesBackedEnumType(mixed $value): bool
127+
{
128+
return ($this->isIntBackedEnum() && \is_int($value)) || (!$this->isIntBackedEnum() && \is_string($value));
129+
}
130+
131+
protected function isIntBackedEnum(): bool
132+
{
133+
if (!isset($this->isIntBackedEnum)) {
134+
$r = new \ReflectionEnum($this->getEnumClass());
135+
136+
$this->isIntBackedEnum = 'int' === (string) $r->getBackingType();
137+
}
138+
139+
return $this->isIntBackedEnum;
140+
}
141+
142+
public function getName(): string
143+
{
144+
return $this->getEnumClass();
145+
}
146+
}

‎src/Bridge/Doctrine/DBAL/Types/AbstractFlagBagType.php

+11-77
Original file line numberDiff line numberDiff line change
@@ -12,88 +12,22 @@
1212

1313
namespace Elao\Enum\Bridge\Doctrine\DBAL\Types;
1414

15-
use Doctrine\DBAL\Platforms\AbstractPlatform;
16-
use Doctrine\DBAL\Types\IntegerType;
17-
use Elao\Enum\Exception\InvalidArgumentException;
18-
use Elao\Enum\FlagBag;
15+
use Doctrine\DBAL\ParameterType;
1916

20-
abstract class AbstractFlagBagType extends IntegerType
21-
{
22-
/**
23-
* The enum FQCN for which we should make the DBAL conversion.
24-
*
25-
* @psalm-return class-string<\BackedEnum>
26-
*/
27-
abstract protected function getEnumClass(): string;
28-
29-
/**
30-
* What should be returned on null value from the database.
31-
*
32-
* @return FlagBag<\BackedEnum>|null
33-
*/
34-
protected function onNullFromDatabase(): ?FlagBag
35-
{
36-
return null;
37-
}
38-
39-
/**
40-
* What should be returned on null value from PHP.
41-
*/
42-
protected function onNullFromPhp(): int|null
43-
{
44-
return null;
45-
}
46-
47-
/**
48-
* {@inheritdoc}
49-
*
50-
* @param FlagBag<\BackedEnum>|null $value
51-
*/
52-
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?int
17+
if (enum_exists(ParameterType::class)) {
18+
abstract class AbstractFlagBagType extends AbstractFlagBagTypeCommon
5319
{
54-
if ($value !== null && !$value instanceof FlagBag) {
55-
throw new InvalidArgumentException(sprintf(
56-
'Expected an instance of a %s. %s given.',
57-
FlagBag::class,
58-
get_debug_type($value),
59-
));
20+
public function getBindingType(): ParameterType
21+
{
22+
return ParameterType::INTEGER;
6023
}
61-
62-
if (null === $value) {
63-
return $this->onNullFromPhp();
64-
}
65-
66-
return $value->getValue();
6724
}
68-
69-
/**
70-
* {@inheritdoc}
71-
*
72-
* @param int|null $value The value to convert.
73-
*
74-
* @return FlagBag<\BackedEnum>|null
75-
*/
76-
public function convertToPHPValue($value, AbstractPlatform $platform)
25+
} else {
26+
abstract class AbstractFlagBagType extends AbstractFlagBagTypeCommon
7727
{
78-
$value = parent::convertToPHPValue($value, $platform);
79-
80-
if (null === $value) {
81-
return $this->onNullFromDatabase();
28+
public function getBindingType(): int
29+
{
30+
return ParameterType::INTEGER;
8231
}
83-
84-
return new FlagBag($this->getEnumClass(), $value);
85-
}
86-
87-
/**
88-
* {@inheritdoc}
89-
*/
90-
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
91-
{
92-
return true;
93-
}
94-
95-
public function getName(): string
96-
{
97-
return $this->getEnumClass();
9832
}
9933
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the "elao/enum" package.
7+
*
8+
* Copyright (C) Elao
9+
*
10+
* @author Elao <contact@elao.com>
11+
*/
12+
13+
namespace Elao\Enum\Bridge\Doctrine\DBAL\Types;
14+
15+
use Doctrine\DBAL\Platforms\AbstractPlatform;
16+
use Doctrine\DBAL\Types\Type;
17+
use Elao\Enum\Exception\InvalidArgumentException;
18+
use Elao\Enum\FlagBag;
19+
20+
abstract class AbstractFlagBagTypeCommon extends Type
21+
{
22+
/**
23+
* The enum FQCN for which we should make the DBAL conversion.
24+
*
25+
* @psalm-return class-string<\BackedEnum>
26+
*/
27+
abstract protected function getEnumClass(): string;
28+
29+
/**
30+
* What should be returned on null value from the database.
31+
*
32+
* @return FlagBag<\BackedEnum>|null
33+
*/
34+
protected function onNullFromDatabase(): ?FlagBag
35+
{
36+
return null;
37+
}
38+
39+
/**
40+
* What should be returned on null value from PHP.
41+
*/
42+
protected function onNullFromPhp(): int|null
43+
{
44+
return null;
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*
50+
* @param FlagBag<\BackedEnum>|null $value
51+
*/
52+
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?int
53+
{
54+
if ($value !== null && !$value instanceof FlagBag) {
55+
throw new InvalidArgumentException(sprintf(
56+
'Expected an instance of a %s. %s given.',
57+
FlagBag::class,
58+
get_debug_type($value),
59+
));
60+
}
61+
62+
if (null === $value) {
63+
return $this->onNullFromPhp();
64+
}
65+
66+
return $value->getValue();
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*
72+
* @param int|null $value The value to convert.
73+
*
74+
* @return FlagBag<\BackedEnum>|null
75+
*/
76+
public function convertToPHPValue($value, AbstractPlatform $platform): ?FlagBag
77+
{
78+
$value = parent::convertToPHPValue($value, $platform);
79+
80+
if (null === $value) {
81+
return $this->onNullFromDatabase();
82+
}
83+
84+
return new FlagBag($this->getEnumClass(), $value);
85+
}
86+
87+
/**
88+
* {@inheritdoc}
89+
*/
90+
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
91+
{
92+
return true;
93+
}
94+
95+
public function getName(): string
96+
{
97+
return $this->getEnumClass();
98+
}
99+
100+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
101+
{
102+
return $platform->getIntegerTypeDeclarationSQL($column);
103+
}
104+
}

‎src/Bridge/Symfony/Bundle/DependencyInjection/ElaoEnumExtension.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
use Elao\Enum\Bridge\Symfony\HttpKernel\Controller\ArgumentResolver\BackedEnumValueResolver;
1818
use Symfony\Component\Config\FileLocator;
1919
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\DependencyInjection\Extension\Extension;
2021
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
2122
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
22-
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
2323

2424
class ElaoEnumExtension extends Extension implements PrependExtensionInterface
2525
{

‎tests/Fixtures/Integration/Symfony/config/doctrine-new.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ doctrine:
22
orm:
33
report_fields_where_declared: true
44
enable_lazy_ghost_objects: true
5+
controller_resolver:
6+
auto_mapping: true

0 commit comments

Comments
 (0)
Please sign in to comment.