Problem/Motivation
Drupal validation constraint plugins simply extend Symfony constraint plugins, e.g.
class IsNullConstraint extends IsNull {}
This means that we inherit the constructor from Symfony.
ConstraintManager uses the default ContainerFactory to construct plugin instances:
return new $plugin_class($configuration, $plugin_id, $plugin_definition);
Technically this is compatible with the Constraint constructor in Symfony 4:
public function __construct($options = null)
However in Symfony 5, two new parameters have been added:
public function __construct($options = null, array $groups = null, $payload = null)
This fails, because $plugin_id
is a string but we try to pass it as the $groups
array parameter.
Steps to reproduce
Upgrade symfony/validator to 5.2 and try to run core tests.
Proposed resolution
Add a ConstraintFactory that calls the constructor correctly.
Remaining tasks
Extract part of the patch from #3161889-67: [META] Symfony 6 compatibility
Add tests
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#13 | 3185603-11.patch | 6.54 KB | daffie |
#13 | interdiff-3185603-9-11.txt | 1.37 KB | daffie |
Comments
Comment #2
longwaveComment #3
Gábor HojtsyGood find! Tagging up.
Comment #4
longwaveWe actually need to solve this before Symfony 6, as this will break in 5.2 or above. Symfony constructors do have BC, but we were always calling this one incorrectly, and the extra arguments were simply being ignored.
Comment #5
Gábor HojtsyWe used the Symfony 5 tag for things that break when updating to Symfony 5.0. Let's at least add the Symfony 6 tag.
Comment #6
andypostLooks it caused by PHP 8 additions https://symfony.com/blog/new-in-symfony-5-2-constraints-as-php-attributes
Comment #7
longwaveSlightly improved version of the factory from the other issue, this checks whether we really are creating a Constraint and falls back in the unlikely case that we have a normal Drupal plugin.
This probably needs a test at least for the Symfony case.
Comment #8
catchSince this blocks Drupal 10 it should be marked critical. Approach looks good but agreed we need tests here.
Comment #9
daffie CreditAttribution: daffie commentedAdded testing.
Comment #10
longwaveTests look good, one question:
Why
is_subclass_of()
and notassert[Not]InstanceOf()
? Aren't they equivalent here?Comment #11
joachim CreditAttribution: joachim as a volunteer commentedWhat happens if a developer creates a plugin that does both?
Should the plugin manager catch this during discovery and throw an exception?
Comment #12
longwaveI think it should still work if you want a Symfony Constraint that also needs the Drupal container? It would be up to the ::create() method defined in the plugin to instantiate the plugin correctly via the constructor.
Comment #13
daffie CreditAttribution: daffie commented@longwave: You are right.
Comment #14
longwaveThanks! This looks great now, assuming tests come back green.
Comment #16
catchCommitted d0e54c0 and pushed to 9.2.x. Thanks!
This probably could be backported to 9.1.x, but I don't see any reason to do so since it won't become a problem until we actually upgrade to Symfony 5/6, so leaving in 9.1.x