Skip to content

Commit b7d60b9

Browse files
committed
Merge branch '7.4' into 8.0
* 7.4: [TwigBridgeRessources] add aria-invalid and aria-describedby on form inputs when validation failure exist [MonologBridge] Add ability to react to console input being interactive or not [Validator] Reviewed and corrected Ukrainian translations for the Val… [Security] improve VoteObject adding extraData for give more possibilities to AccessDecicsionStrategy [DoctrineBridge] add new DayPointType and TimePointType Doctrine type [Notifier] Rename LOX24RequestParser to Lox24RequestParser [Uid] Default to `UuidV7` when using `UuidFactory` [Doctrine] Allow data-fixtures v2 in Symfony root [Config] Add `ArrayNodeDefinition::acceptAndWrap()` to list alternative types that should be accepted and wrapped in an array
2 parents 8158374 + d06e589 commit b7d60b9

File tree

8 files changed

+304
-3
lines changed

8 files changed

+304
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212

1313
* Deprecate `UniqueEntity::getRequiredOptions()` and `UniqueEntity::getDefaultOption()`
1414
* Use a single table named `_schema_subscriber_check` in schema listeners to detect same database connections
15+
* Add support for `Symfony\Component\Clock\DatePoint` as `DayPointType` and `TimePointType` Doctrine type
1516

1617
7.3
1718
---

DependencyInjection/CompilerPass/RegisterDatePointTypePass.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass;
1313

1414
use Symfony\Bridge\Doctrine\Types\DatePointType;
15+
use Symfony\Bridge\Doctrine\Types\DayPointType;
16+
use Symfony\Bridge\Doctrine\Types\TimePointType;
1517
use Symfony\Component\Clock\DatePoint;
1618
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1719
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -31,6 +33,8 @@ public function process(ContainerBuilder $container): void
3133
$types = $container->getParameter('doctrine.dbal.connection_factory.types');
3234

3335
$types['date_point'] ??= ['class' => DatePointType::class];
36+
$types['day_point'] ??= ['class' => DayPointType::class];
37+
$types['time_point'] ??= ['class' => TimePointType::class];
3438

3539
$container->setParameter('doctrine.dbal.connection_factory.types', $types);
3640
}

Tests/DependencyInjection/CompilerPass/RegisterDatePointTypePassTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterDatePointTypePass;
1616
use Symfony\Bridge\Doctrine\Types\DatePointType;
17+
use Symfony\Bridge\Doctrine\Types\DayPointType;
18+
use Symfony\Bridge\Doctrine\Types\TimePointType;
1719
use Symfony\Component\DependencyInjection\ContainerBuilder;
1820

1921
class RegisterDatePointTypePassTest extends TestCase
@@ -27,6 +29,8 @@ public function testRegistered()
2729
$expected = [
2830
'foo' => 'bar',
2931
'date_point' => ['class' => DatePointType::class],
32+
'day_point' => ['class' => DayPointType::class],
33+
'time_point' => ['class' => TimePointType::class],
3034
];
3135
$this->assertSame($expected, $container->getParameter('doctrine.dbal.connection_factory.types'));
3236
}

Tests/IdGenerator/UuidGeneratorTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
1717
use Symfony\Component\Uid\Factory\UuidFactory;
18+
use Symfony\Component\Uid\TimeBasedUidInterface;
1819
use Symfony\Component\Uid\Uuid;
1920
use Symfony\Component\Uid\UuidV4;
20-
use Symfony\Component\Uid\UuidV6;
2121

2222
class UuidGeneratorTest extends TestCase
2323
{
@@ -47,13 +47,13 @@ public function testUuidfactory()
4747
{
4848
$em = (new \ReflectionClass(EntityManager::class))->newInstanceWithoutConstructor();
4949
$generator = new UuidGenerator();
50-
$this->assertInstanceOf(UuidV6::class, $generator->generateId($em, new Entity()));
50+
$this->assertInstanceOf(TimeBasedUidInterface::class, $generator->generateId($em, new Entity()));
5151

5252
$generator = $generator->randomBased();
5353
$this->assertInstanceOf(UuidV4::class, $generator->generateId($em, new Entity()));
5454

5555
$generator = $generator->timeBased();
56-
$this->assertInstanceOf(UuidV6::class, $generator->generateId($em, new Entity()));
56+
$this->assertInstanceOf(TimeBasedUidInterface::class, $generator->generateId($em, new Entity()));
5757

5858
$generator = $generator->nameBased('prop1', Uuid::NAMESPACE_OID);
5959
$this->assertEquals(Uuid::v5(new Uuid(Uuid::NAMESPACE_OID), '3'), $generator->generateId($em, new Entity()));

Tests/Types/DayPointTypeTest.php

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Types;
13+
14+
use Doctrine\DBAL\Exception;
15+
use Doctrine\DBAL\Platforms\AbstractPlatform;
16+
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
17+
use Doctrine\DBAL\Types\Type;
18+
use PHPUnit\Framework\TestCase;
19+
use Symfony\Bridge\Doctrine\Types\DayPointType;
20+
use Symfony\Component\Clock\DatePoint;
21+
22+
final class DayPointTypeTest extends TestCase
23+
{
24+
private DayPointType $type;
25+
26+
public static function setUpBeforeClass(): void
27+
{
28+
$name = DayPointType::NAME;
29+
if (Type::hasType($name)) {
30+
Type::overrideType($name, DayPointType::class);
31+
} else {
32+
Type::addType($name, DayPointType::class);
33+
}
34+
}
35+
36+
protected function setUp(): void
37+
{
38+
if (!class_exists(DatePoint::class)) {
39+
self::markTestSkipped('The DatePoint class is not available.');
40+
}
41+
$this->type = Type::getType(DayPointType::NAME);
42+
}
43+
44+
public function testDatePointConvertsToDatabaseValue()
45+
{
46+
$datePoint = DatePoint::createFromFormat('!Y-m-d', '2025-03-03');
47+
48+
$expected = $datePoint->format('Y-m-d');
49+
$actual = $this->type->convertToDatabaseValue($datePoint, new PostgreSQLPlatform());
50+
51+
$this->assertSame($expected, $actual);
52+
}
53+
54+
public function testDatePointConvertsToPHPValue()
55+
{
56+
$datePoint = new DatePoint();
57+
$actual = $this->type->convertToPHPValue($datePoint, self::getSqlitePlatform());
58+
59+
$this->assertSame($datePoint, $actual);
60+
}
61+
62+
public function testNullConvertsToPHPValue()
63+
{
64+
$actual = $this->type->convertToPHPValue(null, self::getSqlitePlatform());
65+
66+
$this->assertNull($actual);
67+
}
68+
69+
public function testDateTimeImmutableConvertsToPHPValue()
70+
{
71+
$format = 'Y-m-d H:i:s.u';
72+
$date = '2025-03-03';
73+
$dateTime = \DateTimeImmutable::createFromFormat('!Y-m-d', $date);
74+
$actual = $this->type->convertToPHPValue($dateTime, self::getSqlitePlatform());
75+
$expected = DatePoint::createFromFormat('!Y-m-d', $date);
76+
77+
$this->assertInstanceOf(DatePoint::class, $actual);
78+
$this->assertSame($expected->format($format), $actual->format($format));
79+
}
80+
81+
public function testDatabaseValueConvertsToPHPValue()
82+
{
83+
$format = 'Y-m-d H:i:s.u';
84+
$date = '2025-03-03';
85+
$actual = $this->type->convertToPHPValue($date, new PostgreSQLPlatform());
86+
$expected = DatePoint::createFromFormat('!Y-m-d', $date);
87+
88+
$this->assertInstanceOf(DatePoint::class, $actual);
89+
$this->assertSame($expected->format($format), $actual->format($format));
90+
}
91+
92+
public function testGetName()
93+
{
94+
$this->assertSame('day_point', $this->type->getName());
95+
}
96+
97+
private static function getSqlitePlatform(): AbstractPlatform
98+
{
99+
if (interface_exists(Exception::class)) {
100+
// DBAL 4+
101+
return new \Doctrine\DBAL\Platforms\SQLitePlatform();
102+
}
103+
104+
return new \Doctrine\DBAL\Platforms\SqlitePlatform();
105+
}
106+
}

Tests/Types/TimePointTypeTest.php

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Types;
13+
14+
use Doctrine\DBAL\Exception;
15+
use Doctrine\DBAL\Platforms\AbstractPlatform;
16+
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
17+
use Doctrine\DBAL\Types\Type;
18+
use PHPUnit\Framework\TestCase;
19+
use Symfony\Bridge\Doctrine\Types\TimePointType;
20+
use Symfony\Component\Clock\DatePoint;
21+
22+
final class TimePointTypeTest extends TestCase
23+
{
24+
private TimePointType $type;
25+
26+
public static function setUpBeforeClass(): void
27+
{
28+
$name = TimePointType::NAME;
29+
if (Type::hasType($name)) {
30+
Type::overrideType($name, TimePointType::class);
31+
} else {
32+
Type::addType($name, TimePointType::class);
33+
}
34+
}
35+
36+
protected function setUp(): void
37+
{
38+
if (!class_exists(DatePoint::class)) {
39+
self::markTestSkipped('The DatePoint class is not available.');
40+
}
41+
$this->type = Type::getType(TimePointType::NAME);
42+
}
43+
44+
public function testDatePointConvertsToDatabaseValue()
45+
{
46+
$datePoint = DatePoint::createFromFormat('!H:i:s', '05:10:15');
47+
48+
$expected = $datePoint->format('H:i:s');
49+
$actual = $this->type->convertToDatabaseValue($datePoint, new PostgreSQLPlatform());
50+
51+
$this->assertSame($expected, $actual);
52+
}
53+
54+
public function testDatePointConvertsToPHPValue()
55+
{
56+
$datePoint = new DatePoint();
57+
$actual = $this->type->convertToPHPValue($datePoint, self::getSqlitePlatform());
58+
59+
$this->assertSame($datePoint, $actual);
60+
}
61+
62+
public function testNullConvertsToPHPValue()
63+
{
64+
$actual = $this->type->convertToPHPValue(null, self::getSqlitePlatform());
65+
66+
$this->assertNull($actual);
67+
}
68+
69+
public function testDateTimeImmutableConvertsToPHPValue()
70+
{
71+
$format = 'Y-m-d H:i:s.u';
72+
$time = '05:10:15';
73+
$dateTime = \DateTimeImmutable::createFromFormat('!H:i:s', $time);
74+
$actual = $this->type->convertToPHPValue($dateTime, self::getSqlitePlatform());
75+
$expected = DatePoint::createFromFormat('!H:i:s', $time);
76+
77+
$this->assertInstanceOf(DatePoint::class, $actual);
78+
$this->assertSame($expected->format($format), $actual->format($format));
79+
}
80+
81+
public function testDatabaseValueConvertsToPHPValue()
82+
{
83+
$format = 'Y-m-d H:i:s.u';
84+
$time = '05:10:15';
85+
$actual = $this->type->convertToPHPValue($time, new PostgreSQLPlatform());
86+
$expected = DatePoint::createFromFormat('!H:i:s', $time);
87+
88+
$this->assertInstanceOf(DatePoint::class, $actual);
89+
$this->assertSame($expected->format($format), $actual->format($format));
90+
}
91+
92+
public function testGetName()
93+
{
94+
$this->assertSame('time_point', $this->type->getName());
95+
}
96+
97+
private static function getSqlitePlatform(): AbstractPlatform
98+
{
99+
if (interface_exists(Exception::class)) {
100+
// DBAL 4+
101+
return new \Doctrine\DBAL\Platforms\SQLitePlatform();
102+
}
103+
104+
return new \Doctrine\DBAL\Platforms\SqlitePlatform();
105+
}
106+
}

Types/DayPointType.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Types;
13+
14+
use Doctrine\DBAL\Platforms\AbstractPlatform;
15+
use Doctrine\DBAL\Types\DateImmutableType;
16+
use Symfony\Component\Clock\DatePoint;
17+
18+
final class DayPointType extends DateImmutableType
19+
{
20+
public const NAME = 'day_point';
21+
22+
/**
23+
* @return ($value is null ? null : DatePoint)
24+
*/
25+
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DatePoint
26+
{
27+
if (null === $value || $value instanceof DatePoint) {
28+
return $value;
29+
}
30+
31+
$value = parent::convertToPHPValue($value, $platform);
32+
33+
return DatePoint::createFromInterface($value);
34+
}
35+
36+
public function getName(): string
37+
{
38+
return self::NAME;
39+
}
40+
}

Types/TimePointType.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Types;
13+
14+
use Doctrine\DBAL\Platforms\AbstractPlatform;
15+
use Doctrine\DBAL\Types\TimeImmutableType;
16+
use Symfony\Component\Clock\DatePoint;
17+
18+
final class TimePointType extends TimeImmutableType
19+
{
20+
public const NAME = 'time_point';
21+
22+
/**
23+
* @return ($value is null ? null : DatePoint)
24+
*/
25+
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?DatePoint
26+
{
27+
if (null === $value || $value instanceof DatePoint) {
28+
return $value;
29+
}
30+
31+
$value = parent::convertToPHPValue($value, $platform);
32+
33+
return DatePoint::createFromInterface($value);
34+
}
35+
36+
public function getName(): string
37+
{
38+
return self::NAME;
39+
}
40+
}

0 commit comments

Comments
 (0)