Problem/Motivation
After installing scheduler on a site without the token contributed module, trying to create a new node fails and generates the server error:
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "token.entity_mapper". in Drupal\Component\DependencyInjection\Container->get() (line 157 of SITEROOT/web/core/lib/Drupal/Component/DependencyInjection/Container.php).
Steps to reproduce
Install Drupal 10; I use drush :
- composer create-project drupal/recommended-project:^10 SITEROOT
- composer require drush/drush
- ./vendor/bin/drush site:install etc etc
Then add scheduler but no other modules
- composer require scheduler:^2.0
- drush pm-install scheduler
Then, log in and visit /node/add/article
Proposed resolution
The issue seems to be due to scheduler assuming that hook_tokens is only invoked by the contributed "token" module, given the comments in _scheduler_token_types() as implemented in scheduler.tokens.inc:
// This function should only get executed if the Token module is enabled,
// therefore we can assume the token.entity_mapper service exists without
// having to check for it.
That function is in turn called from scheduler_tokens() which is an implementation of hook_tokens().
However, the call trace shows that this hook is being invoked on a site even without the Token module, via
- SITEROOT/web/core/lib/Drupal/Core/Utility/Token.php line 364
Checking that Token.php provided by core, it is indeed invoking hook_tokens():
$replacements = $this->moduleHandler->invokeAll('tokens', [$type, $tokens, $data, $options, $bubbleable_metadata]);
One approach would be to stop making the assumption in the comment from _scheduler_token_types() and check to see if the Token module is enable before using the token.entity_mapper service, but I've not followed through the possible implications of that change.
Issue fork scheduler-3443183
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
sense-designIssue confirmed, same here for me.
Comment #4
jonathan1055 commentedThanks for raising this issue and giving the details. It is a problem and I'll work on the fix right now.
Comment #6
jonathan1055 commentedTest fail on drupal.org simply because I am writing out debug. They pass on gitlab.
Comment #7
jonathan1055 commentedThe token module is loaded due to it being required by commerce_product, so testing without the token module is going to take a bit more work. The commerce_product module is enabled at the start, and then test products are created, so uninstalling the module (a pre-requisite to uninstalling token) is difficult to do within the executing test.
I have tested the change to
_scheduler_token_types()locally when the token module is not installed, and it works. If others can test and confirm this change, I may commit that fix and release Scheduler 2.0.3, then work on the test coverage later.Comment #8
sense-designPatch works for me in project.
Comment #9
alt36 commentedThe MR works for me - specifically I've checked with commit bd16830, which I can see now checks if the token.entity_mapper service is available. Thanks!
Comment #10
jonathan1055 commentedThank you both for confirming the fix. I have also now added test coverage, checking that the url to add a node, media item or taxonomy term still works and give 200 when the token module is uninstalled. We can verify the extended test coverage using the new "test-only changes" phpunit job (which incidentally I worked on adding into gitlab templates). This runs phpunit after reverting all non-test changes. So the test should fail, which shows that the changed code is now covered by a test.
Oddly we only get a failure for
media/add/{media_type}, there is no failure fornode/add/{nodetype}oradmin/structure/taxonomy/manage/{vocab}/add. Same thing happens when I run the phpunit tests locally. Thehook_token_info()is not called for nodes and taxonomy terms in the test environment, I guess it must be something to do with which input filters are active in the tests? or something else, any ideas?At least the test does fail for 'media' so we have proof that we are now covering that part of the functionality with the extra test.
Comment #12
jonathan1055 commentedMerged and fixed.
Comment #13
jonathan1055 commentedI have now released Scheduler 2.0.3
Comment #14
jonathan1055 commentedI have done some more investigation. The content type does not need to be enabled for Scheduling to get the original error. It is caused when
hook_tokensis invoked, as shown in the backtraceThis is done when the entity has a file upload field defined, because the upload directory location uses the year and month template, defined with [ ] for formatting the date. If the entity does not have a file upload field then there it no call to
->invokeAll('tokens')and no error. That's why the phpunit tests for node and taxonomy term did not fail. Addind a node fails in my UI because it an image field attached. Taxonomy term does not fail in the UI because there is no file upload.