Problem/Motivation
This is a child issue of #2856744: [META] Add trigger_error(..., E_USER_DEPRECATED) to deprecated code
Drupal\workflows\WorkflowDeleteAccessCheck is marked as @deprecated and @internal.
It's also a service in workflows.services.yml. The service is named workflows.access_check.delete_state.
The only place in core that makes reference to this deprecated service or its class name is core/modules/content_moderation/tests/fixtures/update/drupal-8.4.0-content_moderation_installed.php.
Adding a typical @trigger_error() to WorkflowDeleteAccessCheck fails quite a few tests: https://www.drupal.org/pift-ci-job/1106392 (Search for 'WorkflowDeleteAccessCheck' on the page).
Proposed resolution
Figure out how to trigger a deprecation error from this service so that developers will avoid using it.
Either mark tests using that fixture as @group legacy or rebuild the fixture in some way.
Remaining tasks
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | 3009848-15.deprecate-WorkflowDeleteAccessCheck.patch | 791 bytes | jonathan1055 |
Comments
Comment #2
sam152 commentedI believe since this is a tagged service, so the class is instantiated and triggers deprecation issues, even if no code is using the API. We actually already trigger a deprecation in the body of
::access:I don't believe you are suppose to use these classes as injected services, rather as references from route definitions. So any actual usage of this class would in fact trigger a deprecation warning, and this will be safe to remove even if it's autoloaded by the access check collector.
Have I missed anything important?
Comment #5
jonathan1055 commentedI have just hit this problem in #3094454-6: Fix remaining @deprecated manually and enable the coding standard and have 12 core tests failing for this problem.
Yes, that is correct. However, the deprecation messages were not previously being thrown, due to a combination of the way the
@deprecatedtag was written and howSymfony\Component\DependencyInjection\ContainerBuilder::createService()(in vendor/symfony/dependency-injection/ContainerBuilder.php) detects the deprecation.Currently WorkflowDeleteAccessCheck has the following:
Note the single
@deprecatedon its own line. InCreateService()there is the codeThe key bit is
strpos($r->getDocComment(), "\n * @deprecated ")which will only match when there is a space immediately after the@deprecatedtag. So currently the core tests pass with no deprecation message because this part of the logic returns false. When I corrected the @deprecated tag to follow our standards, i.e. have the version etc following in the same line, that strpos logic check returned true and the deprecation warning was produced, and those tests failed - see https://www.drupal.org/pift-ci-job/1474532 This is the only case where this has happened in the 653 +21 = 674 @deprecated standards fixes which have been done. So it looks like an oddity in how the @deprecated tag got added on its own line.Not sure how best this can be fixed, but it needs to be done for #3094454: Fix remaining @deprecated manually and enable the coding standard to be completed, which was a follow-up from the major issue #3048498: [≈Nov. 11] Fix Drupal.Commenting.Deprecated coding standard
Comment #6
jonathan1055 commentedCannot add a second parent, but this issue is now listed on #2959269: [meta] Core should not trigger deprecated code except in tests and during updates
Comment #7
jonathan1055 commentedTo illustrate what happens when the
@deprecatedtag inWorkflowDeleteAccessCheckis written as per standards, i.e. with text following the tag. This should cause 12 or so test failures.Comment #8
jonathan1055 commentedHere is the coding standard fix in #7 plus addition to the Tests/Listeners/DeprecationListenerTrait
Comment #9
sam152 commentedWait, we manually call trigger_error in the body of the function, so aren't deprecation errors correctly triggered when the service is actually used?
Comment #10
berdirYes, that's the problem with event subscriber/tagged services, you can't prevent that they are called, we can only ensure that they are not actually used. Not sure what's the correct thing here.
I'm not a fan of using getSkippedDeprecations() for our own things, it *should* be reserved for third-party components that we can't fix/update yet. I tried deprecating the service too, but all access checks are instantiated in \Drupal\Core\Access\CheckProvider::loadDynamicRequirementMap().
So, I think this really is the best we can do in this case, we do have the @trigger_error() in case someone actually uses it and properly mark it as deprecated. Just one nitpick:
the current comment isn't very useful, lets just try to describe what I said in my comment? Something like:
"All access check services are instantiated during route rebuilds, an additional deprecation message ensures that it is not used for access checks in routes."
Comment #11
jonathan1055 commentedThanks Berdir. I felt that this was ultimately the way to solve it, but did not have the technical vocabulary or background to explain it like you have.
Attached is a patch with the comment as per your request above. Didn't do an interdiff as it is just that one line altered in DeprecationListenerTrait.php
Comment #12
sam152 commentedWhat's the motivation for this, is it just for consistency or static analysis perhaps? I don't get why we'd trigger two deprecations for this class and silence one of them. Apologies if I'm missing some key bit of info here.
Comment #13
berdirOne argument to keep the @deprecated is to officially mark the class as deprecated, although it is arguably very unlikely that someone used this service or class directly.
But yes, the alternative would be to just remove the @deprecated altogether and maybe just keep it as a regular comment in the class docblock (and the service?).
Comment #14
sam152 commentedI'd be fine with removing the notice triggering
@deprecatedcomment on the class and replace it with a regular comment given that it's also marked@internal.Comment #15
jonathan1055 commentedOK. This patch replaces the
@deprecatedtag with a regular comment and does not make any changes to DeprecationListenerTrait.php at all.Comment #16
berdirI can live with both options, as it's already internal anyway this is probably fine.
Comment #17
jonathan1055 commentedThanks @Berdir. Either #11 or #15 is fine with me. This simple correction will allow me to get back and finish #3094454: Fix remaining @deprecated manually and enable the coding standard
Comment #18
gábor hojtsyHm, why commit this with a format that does not conform to coding standards?
Comment #19
gábor hojtsyHm, misread the patch. Moving back to RTBC to undo my misunderstanding. Now read all the comments and it all makes sense.
Comment #21
gábor hojtsyDid not apply to Drupal 9 anymore as WorkflowDeleteAccessCheck.php does not exist in Drupal 9.0.x anymore. So we don't need to ensure to actually remove this even though it was only marked with a comment. Committed to 8.9.x though :)
I agree undoing the deprecation in our listener or not adding it has the same runtime effect and we have the trigger_error() anyway when its actually used.