Problem/Motivation
Symfony 3.4 provides a shortcut to inject all services tagged with a specific tag, which is a common need in some applications, so you don't have to write a compiler pass just for that.
However, when you use a tagged argument the YAML decoder needs to support 'custom tags'.
Which at the moment is not supported in Drupal.
There is more that can be done with custom tags since Symfony 3.3. to mention a few, here are some of the custom tags that are already supported by Symfony YAML component.
!!binary for storing binary data
!php/const: for referring to PHP constants.
It already supports also defining your own custom YAML tags (Custom tags are arbitrary strings that start with the ! character, such as the !my_tag value).
The above can only be possible if the Yaml::PARSE_CUSTOM_TAGS flag is supported in Drupal.
Proposed resolution
Update Drupal\Component\Serialization\YamlSymfony::decode and pass in the flag 'SymfonyYaml::PARSE_CUSTOM_TAGS'
Remaining tasks
User interface changes
None
API changes
No change.
Data model changes
None
| Comment | File | Size | Author |
|---|
Issue fork drupal-3108309
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
larowlanGiven we already support the 'service_collector' tag to avoid needing a compiler pass (which I think may have inspired the symfony feature) - do we need this?
Sample from core:
the collector:
and a tagged service:
In this scenario,
addInvalidatoris called onDrupal\Core\Cache\CacheTagsInvalidatorfor every service tagged withcache_tags_invalidatorSee
\Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPassComment #3
bonrita commentedThanks, @larowlan for the info.
Indeed the above-mentioned example can already be done by Drupal using the service_collector tag. However, that is just part of the problem.
There is more that can be done with custom tags since Symfony 3.3. to mention a few, here are some of the custom tags that are already supported by Symfony YAML component.
It already supports also defining your own custom YAML tags (Custom tags are arbitrary strings that start with the ! character, such as the !my_tag value).
The above can only be possible if the Yaml::PARSE_CUSTOM_TAGS flag is supported in Drupal.
Comment #4
bonrita commentedComment #5
bonrita commentedComment #6
bonrita commentedComment #8
bonrita commentedComment #9
bonrita commentedComment #15
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #16
longwaveFollowing #2961380: Support IteratorArgument in \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::dumpValue if we implemented this then we could also use
!tagged_iteratorand friends from Symfony.Comment #17
godotislateAlong those lines, we could also use
!service_closureto define services following this: #3108020: Support ServiceClosureArgument in \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::dumpValue. Though I have found that autowiring closures (using annotations) solves that since the arguments don't even need to be defined in YAML.Comment #19
kim.pepperComment #21
kim.pepperCreated a MR from the patch in #8
Comment #23
longwaveFixing title.
Comment #24
longwaveGiven we added constant parsing as well, can we add a test for that too?
What do we need to add to the PECL parser to support this?
Comment #25
longwaveAlso, is there any additional overhead in adding this parsing? Is there a case where we might not want this flag to be enabled?
Comment #26
alexpott@longwave I don't really think there is much overhead - given we would already be parsing the tag in Symfony and throwing an error. The question is really can we duplicate this functionality in PECL. And the problem is we cannot. Looking at the underlying PECL code (https://github.com/php/pecl-file_formats-yaml/blob/php7/parse.c#L641) there is no way to subscribe a callback to all tags. We would need to file an issue and get it into PECL yaml ... not fun. Maybe we could make it make it really simple to register new tags to a PECL yaml callback that produces TaggedValue objects.
Comment #27
longwave@alexpott should we just force the Symfony parser in the DI YamlFileLoader, as that's currently the only place (I think) that we need this?
Comment #28
longwaveFurther to #24 we already have #2951046: Allow parsing and writing PHP class constants and enums in YAML files to enable PARSE_CONSTANT which also works on PECL and has tests, so let's only work on custom tags here.
Comment #29
alexpottRe #27 I was tempted to suggest that. I was reticent because service.yml files are one of the thing parsed on cold cache. But the more I think about it the more I think that this is a good approach for now. The capabilities of the YAML parser and container configuration are quite closely related so this does not feel like a bad decision - also we use FileCache here so potentially this has no impact on cold cache as that can persist across a cache rebuild.
Comment #30
kim.pepperCreated #3414647: Always use YamlSymfony for loading service yaml files
Comment #31
longwaveComment #32
kim.pepperComment #33
longwaveDoes what it says, has test coverage. Not even sure we should bother with catching the exception in the test, just let it fail if the exception is thrown, but the code is already written so let's leave it as-is.
Comment #34
alexpottI don't think we should do this until we've removed support for PECL yaml in #3205480: Drop PECL YAML library support in favor of only Symfony YAML - this intentionally makes the pecl and symfony parsers different and I don't think we should do that.
Comment #35
longwaveLet's use this status, then.
Comment #36
wim leersComment #37
wim leers#3205480: Drop PECL YAML library support in favor of only Symfony YAML landed!
Comment #39
andypostrebased
Comment #40
longwaveThis is just adding the flag and some tests, the dependent issue landed, back to RTBC as per #33.
Comment #41
alexpottCommitted and pushed a91f4f4e5b to 11.x and c6a3077802 to 10.3.x. Thanks!
Comment #44
kim.pepperUnfortunately, this commit came after #3205480: Drop PECL YAML library support in favor of only Symfony YAML which means we added the flag to the deprecated
\Drupal\Component\Serialization\YamlSymfony::decode()method.We need to make the change to
\Drupal\Component\Serialization\Yaml::decode()now.#3414208: Add support for tagged_iterator to YamlFileLoader is doing that already, so I don't know if we need a separate dedicated issue to do that.
Comment #45
alexpott@kim.pepper whoops nice spot and yeah sure let's do it in that issue.
Comment #46
wim leersLooks like @kim.pepper did that as of ~14 hours ago: https://git.drupalcode.org/project/drupal/-/merge_requests/6134/diffs?co...
Comment #49
kim.pepperAdded a new child issue #3450516: Add support for !service_closure custom tag in YamlFileLoader