DoctrineExtensions
DoctrineExtensions copied to clipboard
Timestampable (and maybe more extensions) don't work with DBAL 4.0.0-RC2
Environment
Package
show
$ composer show --latest gedmo/doctrine-extensions
name : gedmo/doctrine-extensions
descrip. : Doctrine behavioral extensions
keywords : Blameable, behaviors, doctrine, extensions, gedmo, loggable, nestedset, odm, orm, sluggable, sortable, timestampable, translatable, tree, uploadable
versions : * v3.14.0
latest : v3.14.0
type : library
license : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
homepage : http://gediminasm.org/
source : [git] https://github.com/doctrine-extensions/DoctrineExtensions.git 3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf
dist : [zip] https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf 3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf
path : /app/vendor/gedmo/doctrine-extensions
names : gedmo/doctrine-extensions
support
email : [email protected]
issues : https://github.com/doctrine-extensions/DoctrineExtensions/issues
source : https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.14.0
wiki : https://github.com/Atlantic18/DoctrineExtensions/tree/main/doc
autoload
psr-4
Gedmo\ => src/
requires
behat/transliterator ^1.2
doctrine/annotations ^1.13 || ^2.0
doctrine/collections ^1.2 || ^2.0
doctrine/common ^2.13 || ^3.0
doctrine/event-manager ^1.2 || ^2.0
doctrine/persistence ^2.2 || ^3.0
php ^7.4 || ^8.0
psr/cache ^1 || ^2 || ^3
symfony/cache ^5.4 || ^6.0 || ^7.0
symfony/deprecation-contracts ^2.1 || ^3.0
requires (dev)
doctrine/cache ^1.11 || ^2.0
doctrine/dbal ^3.2
doctrine/doctrine-bundle ^2.3
doctrine/mongodb-odm ^2.3
doctrine/orm ^2.14.0
friendsofphp/php-cs-fixer ^3.14.0
nesbot/carbon ^2.71 || 3.x-dev as 3.0
phpstan/phpstan ^1.10.2
phpstan/phpstan-doctrine ^1.0
phpstan/phpstan-phpunit ^1.0
phpunit/phpunit ^9.6
rector/rector ^0.18
symfony/console ^5.4 || ^6.0 || ^7.0
symfony/phpunit-bridge ^6.0 || ^7.0
symfony/yaml ^5.4 || ^6.0 || ^7.0
suggests
doctrine/mongodb-odm to use the extensions with the MongoDB ODM
doctrine/orm to use the extensions with the ORM
conflicts
doctrine/dbal <3.2
doctrine/mongodb-odm <2.3
doctrine/orm <2.14.0 || 2.16.0 || 2.16.1
sebastian/comparator <2.0
Doctrine packages
show
$ composer show --latest 'doctrine/*'
Color legend:
- patch or minor release available - update recommended
- major release available - update possible
- up to date version
Direct dependencies required in composer.json:
doctrine/dbal 4.0.0-RC2 4.0.0-RC2 Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.
doctrine/doctrine-bundle 2.11.1 2.11.1 Symfony DoctrineBundle
doctrine/doctrine-migrations-bundle 3.3.0 3.3.0 Symfony DoctrineMigrationsBundle
doctrine/orm 3.0.0-RC1 3.0.0-RC1 Object-Relational-Mapper for PHP
Transitive dependencies not required in composer.json:
doctrine/annotations 2.0.1 2.0.1 Docblock Annotations Parser
doctrine/cache 2.2.0 2.2.0 PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.
doctrine/collections 2.1.4 2.1.4 PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.
doctrine/common 3.4.3 3.4.3 PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and mu...
doctrine/deprecations 1.1.3 1.1.3 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.
doctrine/event-manager 2.0.0 2.0.0 The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.
doctrine/inflector 2.0.9 2.0.9 PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.
doctrine/instantiator 2.0.0 2.0.0 A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer 3.0.0 3.0.0 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
doctrine/migrations 3.7.2 3.7.2 PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying ...
doctrine/persistence 3.2.0 3.2.0 The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.
doctrine/sql-formatter 1.1.3 1.1.3 a PHP SQL highlighting library
PHP version
$ php -v
PHP 8.3.2 (cli) (built: Jan 27 2024 04:34:00) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.3.2, Copyright (c) Zend Technologies
with Zend OPcache v8.3.2, Copyright (c), by Zend Technologies
with Xdebug v3.3.1, Copyright (c) 2002-2023, by Derick Rethans
Subject
With DBAL 4.0.0-RC2, there is a bug with Timestampable. I found why and I can provide a fix, but I think this bug can be on other extensions... That's why I only create a bug issue.
In DBAL 4.0.0-RC2, the method $this->getObjectManager()->getConnection()->getDriver()->getDatabasePlatform()
now wait an argument, which is not provided for the moment, and the getFieldMapping
function return an object instead of an array.
I found the bug in the src/Timestampable/Mapping/Event/Adapter/ORM.php
file.
Actual version :
show
<?php
/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <[email protected]> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Gedmo\Timestampable\Mapping\Event\Adapter;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping\ClassMetadata;
use Gedmo\Mapping\Event\Adapter\ORM as BaseAdapterORM;
use Gedmo\Timestampable\Mapping\Event\TimestampableAdapter;
/**
* Doctrine event adapter for ORM adapted
* for Timestampable behavior
*
* @author Gediminas Morkevicius <[email protected]>
*/
final class ORM extends BaseAdapterORM implements TimestampableAdapter
{
/**
* @param ClassMetadata $meta
*/
public function getDateValue($meta, $field)
{
$mapping = $meta->getFieldMapping($field);
$converter = Type::getType($mapping['type'] ?? Types::DATETIME_MUTABLE);
$platform = $this->getObjectManager()->getConnection()->getDriver()->getDatabasePlatform();
return $converter->convertToPHPValue($this->getRawDateValue($mapping), $platform);
}
/**
* Generates current timestamp for the specified mapping
*
* @param array<string, mixed> $mapping
*
* @return \DateTimeInterface|int
*/
private function getRawDateValue(array $mapping)
{
$datetime = new \DateTime();
$type = $mapping['type'] ?? null;
if ('integer' === $type) {
return (int) $datetime->format('U');
}
if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable'], true)) {
return \DateTimeImmutable::createFromMutable($datetime);
}
return $datetime;
}
}
Fixed version :
show
<?php
/*
* This file is part of the Doctrine Behavioral Extensions package.
* (c) Gediminas Morkevicius <[email protected]> http://www.gediminasm.org
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Gedmo\Timestampable\Mapping\Event\Adapter;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\FieldMapping;
use Gedmo\Mapping\Event\Adapter\ORM as BaseAdapterORM;
use Gedmo\Timestampable\Mapping\Event\TimestampableAdapter;
/**
* Doctrine event adapter for ORM adapted
* for Timestampable behavior
*
* @author Gediminas Morkevicius <[email protected]>
*/
final class ORM extends BaseAdapterORM implements TimestampableAdapter
{
/**
* @param ClassMetadata $meta
*/
public function getDateValue($meta, $field)
{
$mapping = $meta->getFieldMapping($field);
$converter = Type::getType($mapping['type'] ?? Types::DATETIME_MUTABLE);
$platform = $this->getObjectManager()->getConnection()->getDriver()->getDatabasePlatform($this->getObjectManager()->getConnection());
return $converter->convertToPHPValue($this->getRawDateValue($mapping), $platform);
}
/**
* Generates current timestamp for the specified mapping
*
* @param FieldMapping $mapping
*
* @return \DateTimeInterface|int
*/
private function getRawDateValue(FieldMapping $mapping)
{
$datetime = new \DateTime();
$type = $mapping->type ?? null;
if ('integer' === $type) {
return (int) $datetime->format('U');
}
if (in_array($type, ['date_immutable', 'time_immutable', 'datetime_immutable', 'datetimetz_immutable'], true)) {
return \DateTimeImmutable::createFromMutable($datetime);
}
return $datetime;
}
}
This fix work on my side.
I'll be happy to help if needed !
Minimal repository with the bug
I'll do it if I have some free time, I apologize to haven't created it for now.
Steps to reproduce
Just create a project that use DBAL 4.0.0-RC2 instead of 3.x.x and use Timestampable on a updated_at property and try to save a entity.
Expected results
{"@context":"\/api\/contexts\/Todo","@id":"\/api\/todos\/10","@type":"Todo","id":10,"name":"Test","done":false,"createdAt":"2024-02-01T18:07:54+00:00","updatedAt":"2024-02-01T18:07:54+00:00"}
Actual results
"Too few arguments to function Doctrine\\DBAL\\Driver\\Middleware\\AbstractDriverMiddleware::getDatabasePlatform(), 0 passed in /app/vendor/gedmo/doctrine-extensions/src/Timestampable/Mapping/Event/Adapter/ORM.php on line 33 and exactly 1 expected"
Thanks ! 😄
DBAL 4.0 isn't supported right now and probably won't be for a while (IIRC ORM 2.x isn't getting support for it, so ORM 3.x compat has to be sorted out first).
The solution is actually to use the high-level API to access the platform (which has not change between 3.x and 4.x) instead of reaching for the low-level driver.
It seems the Symfony 7 generator uses DBAL 4.0, this "bug" will annoy many people (I'm one of them ;)).
Note that the Symfony generator should be forcing DBAL 3.x for now since a few days.
Hi folks, I've installed Doctrine manually into a Laravel application and I'm experiencing the same problem.
DBAL 4.0 isn't supported right now and probably won't be for a while....
@mbabker is there a roadmap I could look at? Failing that, do you have any idea when DBAL 4.x will be implemented?
I'll build a workaround for my particular scenario.
@mbabker is there a roadmap I could look at? Failing that, do you have any idea when DBAL 4.x will be implemented?
As this package is entirely supported by volunteers, there's no roadmap or timeline. But, the gist of what's required is basically to finish ORM 3 compat (as ORM 2 and DBAL 4 are not usable together, so there's nothing that can really be done to test this at the moment) then start working on DBAL 4 compatibility.
The fix noted in https://github.com/doctrine-extensions/DoctrineExtensions/issues/2752#issuecomment-1939313831 (basically changing any calls similar to $this->getObjectManager()->getConnection()->getDriver()->getDatabasePlatform()
to $this->getObjectManager()->getConnection()->getDatabasePlatform()
) could be sent as a PR at any time to fix this specific issue, but issues like https://github.com/doctrine-extensions/DoctrineExtensions/issues/2502 are pretty big blockers to allowing DBAL 4 (and if I'm being honest, my gut feeling says that might not come without a major release of this package considering what would be involved to resolve that one).
I also just ran into this issue - it would be helpful to make a note what the extension is and is not compatible with in the README.md so people don't get started with the extension only to run into the same error (especially if the incompatibility issue 2502 is almost 2 years old)
fwiw @Arkanii I was able to get the Timestampable annotation working with your change and one other - here's a composer patch file, maybe it'll help somebody out. gedmo-doctrine-extenstions-timestampable.patch
I also just ran into this issue - it would be helpful to make a note what the extension is and is not compatible with in the README.md so people don't get started with the extension only to run into the same error
The best place to look at compatibility is going to be the composer.json
file because that's what Composer is going to use to figure out what to install. Putting compatibility info in README files or other docs files ends up in info being outdated pretty easily (like I just learned that there's a table that tries to convey what versions of doctrine/orm
and doctrine/common
some things are compatible with, and that table's massively out-of-date and honestly not well presented (the two libraries have different versioning schemes, so trying to say it's compatible with both like the header implies isn't great).
especially if the incompatibility issue 2502 is almost 2 years old
And as that issue shows, there's actually a patch that can help fix that particular compatibility issue from a pure code perspective. Except it's not easy to ship it because the changes require data migrations for downstream users (the DBAL's object and array types store data using PHP's serialize()
function, whereas the JSON type uses native JSON support, so it's not just a matter applying that patch and shipping the change but figuring out how to deal with any existing data as well).
I was able to get the Timestampable extension working with your change and one other - here's a composer patch file, maybe it'll help somebody out.
A pull request for the first change in that patch would be hugely appreciated instead of just patching your local app. As for the second change, a proper fix has already landed in this repository, so it's not necessary with the latest release.
@nbennett25 patch works, thanks
but still, it needs fixing :|
Is it planned to update dbal > 4.0.0 in the upcoming release?
Is it planned to update dbal > 4.0.0 in the upcoming release?
Eventually, yes. Unfortunately, there is a huge task involved in that (see #2502 and #2825).
any progress ?