Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Updated: Comment #0
Problem/Motivation
When using the current_user service (replacement for global $user
) in early-ish bootstrap, you will see
You cannot create a service ("current_user") of an inactive scope ("request").
The current_user service is needlessly scoped to the request.
We currently have hacks in place to make the request Just Work™, but #2004086: The Request service must be synthetic will resolve it once and for all.
Proposed resolution
Remove the scope from current_user.
Remaining tasks
N/A
User interface changes
N/A
API changes
N/A
Related Issues
Comment | File | Size | Author |
---|---|---|---|
#10 | request-2076411-10.patch | 2.67 KB | dawehner |
#1 | request-2076411-1.patch | 420 bytes | tim.plunkett |
Comments
Comment #1
tim.plunkettThis blocks anyone trying to remove global $user or _account.
All credit goes to dawehner, not me.
Comment #2
Crell CreditAttribution: Crell commentedGiven that the user is derived FROM the request, I don't see how removing that scope makes any sense. Why exactly are we trying to mess around with the user before we can possibly have derived a user? That sounds like a bug to me.
Comment #3
dawehnerThe problem is that as the user service is needed pretty much everywhere, pretty much every service would need to have the request scope.
One example is the CSRF Generator, which is called from drupal_get_js() which is called from AjaxResponse->prepare() which is called outside of the request scope.
Maybe there should be more research for the user service, but would you be okay with adding scope: request on various places?
Comment #4
tim.plunkettWhen you actually try to use Drupal now:
Symfony\Component\DependencyInjection\Exception\InactiveScopeException: You cannot create a service ("current_user") of an inactive scope ("request"). in service_container_prod->getCurrentUserService() (line 1352 of /Users/timplunk/www/d8/sites/default/files/php/service_container/service_container_prod.php/22f00eaf383d72c665f8a37923a8aa6a394d52d895f6ec0e4ee01dd58d948b22.php)
When you have toolbar.module enabled:
Uncaught SyntaxError: Unexpected token <
...... ,"admin-help":""});<h1>Uncaught exception thrown in shutdown function.</h1><p>Symfony\Component\DependencyInjection\Exception\InactiveScopeException: You cannot create a service (&quot;current_user&quot;) of an inactive scope (&quot;request&quot;). in service_container_prod->getCurrentUserService() (line 1352 of /Users/timplunk/www/d8/sites/default/files/php/service_container/service_container_prod.php/22f00eaf383d72c665f8a37923a8aa6a394d52d895f6ec0e4ee01dd58d948b22.php).</p><hr />
This prevents any JS from working at all.
Comment #5
dawehnerYes, theoretically scope: request would be right, though we do need access in early bootstrap or late rendering, so let's our life easier for now.
Comment #6
m1r1k CreditAttribution: m1r1k commentedAlso
scope: request
breaks test for these fixes:#2061929: Remove calls to deprecated global $user from language.module
#2078057: Remove references to global $user in Content Translation module
#2061949: Remove calls to deprecated global $user in update.php
And it's only small part of issues which depends on this one.
Comment #7
sergeypavlenko CreditAttribution: sergeypavlenko commentedIssue which helped remove scope:
#2061921: Remove calls to deprecated global $user in views module
#2061923: Remove calls to deprecated global $user in locale module
Comment #8
Crell CreditAttribution: Crell commenteddawehner: Where? And you say "For now", does that mean we'd put it back later? Examples please. :-)
(We're at the stage of the dev cycle where it's super tempting to say "oh, let's just hack it and make it work so we can release", but that's how code debt gets built up that takes 3 releases to finally get rid of.)
Comment #9
dawehnerSee #2076411-3: Remove the request scope from the current user service
AjaxResponse->prepare()->drupal_get_js()->drupal_valid_token()->CsrfGenerator
Comment #10
dawehnerLet's try to see whether the change of #2004086-50: The Request service must be synthetic breaks something.
Comment #12
Gábor HojtsyGlobal user removal issues such as #2061929: Remove calls to deprecated global $user from language.module are being postponed on this, so it would be great to figure this out sooner than later :)
Comment #13
catchI'd be OK committing this, then opening a separate critical bug/task to add it back again - on the assumption that'd unblock some issues without explicitly blocking new ones.
Also at least some of these issues (like the watchdog one filed ages ago) are in large part because we've not really updated bootstrap phases since 7.x, so some things happen much later or earlier than others, for reasons that are no longer relevant. I opened #2023495: Make bootstrap three steps a while ago but no time to seriously look at it.
Comment #14
Crell CreditAttribution: Crell commentedI just ran into another place for this: add the current_user service to an event subscriber. The compilation process dies with a totally mysterious:
Fatal error: Call to a member function get() on a non-object in /stor/sandboxes/garfield/wscci/www/wscci/core/lib/Drupal.php on line 241
Because our error handler catches the very helpful Symfony error:
Scope Widening Injection detected: The definition "drupalgotchi.subscriber" references the service "current_user" which belongs to a narrower scope. Generally, it is safer to either move "drupalgotchi.subscriber" to scope "request" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "current_user" each time it is needed. In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.
(Took me a while to track THAT down.)
I'm still concerned that removing the request scope will break more than it fixes, though, since it is then not going to change when a subrequest happens, and accessing it pre-request will do who knows what.
Comment #15
dawehnerCould it be that the RequestStack introduced in https://github.com/symfony/symfony/pull/8904 would solve that problem entirely?
For the authentication subscriber we than could just get the master request all the time.
Comment #16
alexpottAs per #13 I think we should move on with this to unblock other issues and have a critical task to add it back.
So I'm rtbcing #1
Comment #17
m1r1k CreditAttribution: m1r1k commentedI've created new tag for such issues: https://drupal.org/project/issues/search/drupal?issue_tags=blocked-by-re.... There are only some of them.
Comment #18
catch#1: request-2076411-1.patch queued for re-testing.
Comment #19
catchManually resolved conflicts locally and committed/pushed this to 8.x.
I've opened #2102027: Add back the request scope to the current user service to put it back.