5

I need to get the global $user object in Drupal 8. I did $account = \Drupal::currentUser(); in the definition of getSubscribedEvents() (a static method) inside a class file.

I get the following error when running drush cr:

exception
[error] 'Drupal\Core\DependencyInjection\ContainerNotInitializedException' with message '\Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.' in /Applications/MAMP/htdocs/drupal-8.0.x-dev/core/lib/Drupal.php:129

What is wrong in my code?

6
  • You don't need to use any namespace $account = \Drupal::currentUser();, will give current user object. To get user ID, you can use \Drupal::currentUser()->id(); directly.
    – Yogesh
    Jun 30, 2016 at 9:55
  • Using $account = \Drupal::currentUser(); itself is giving the error.
    – neha
    Jun 30, 2016 at 10:08
  • @JyotiBohra you still getting error with my answer ?
    – Sanjay
    Jun 30, 2016 at 10:13
  • Which version of Drush are you using? seems like a Drush version issue, check here.
    – Yogesh
    Jun 30, 2016 at 10:33
  • @Sanjay Yes i am getting the same error with your code as well.
    – neha
    Jun 30, 2016 at 10:40

4 Answers 4

10

You can not get the current user in getSubscribedEvents()

That is not possible and not needed. There is no container at this point.

The only thing you may do in there is returned a list of events you want to register to. This information is then stored in the compiled container and must be identical for all requests, it must not be conditional.

Any logic needs to be inside the methods you register there.

0
10

Since you are using a getSubscribedEvents() static method, I get you are implementing an event subscriber. In this case, you don't access \Drupal::currentUser() (and any static method returning a service that \Drupal exposes) in that method since it would be getting called too early, when Drupal has not yet initialized the dependency container.
That static method is supposed to return a static array describing the events to which the module wants to subscribe; the methods used to subscribe to the events will eventually take a different action basing on the user currently logged-in, and the user permissions that user account has.

Event subscribers are services, and as such they get their dependency injected. Instead of using \Drupal::currentUser(), you define @current_user as one of the arguments of your service, which is what the authentication_subscriber service does.

class: Drupal\Core\EventSubscriber\AuthenticationSubscriber
arguments:
  - '@authentication'
  - '@current_user'
tags:
  - { name: event_subscriber }

If you look at AuthenticationSubscriber::__construct(), you will see how it gets the current user object.

public function __construct(AuthenticationProviderInterface $authentication_provider, AccountProxyInterface $account_proxy) {
  $this->authenticationProvider = $authentication_provider;
  $this->filter = ($authentication_provider instanceof AuthenticationProviderFilterInterface) ? $authentication_provider : NULL;
  $this->challengeProvider = ($authentication_provider instanceof AuthenticationProviderChallengeInterface) ? $authentication_provider : NULL;
  $this->accountProxy = $account_proxy;
}

In your case, I would use the following code.

mymodule.services.yml

services:
  mymodule.eventsubscriber:
    class: Drupal\mymodule\EventSubscriber\MyModuleSubscriber
    arguments:
      - '@current_user'
    tags:
      - { name: event_subscriber }

src/EventSubscriber/MyModuleSubscriber.php

namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MymoduleSubscriber implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    // Return the array describing the events to which you subscribe.
  }

  public function __construct(AccountProxyInterface $account_proxy) {
    $this->accountProxy = $account_proxy;
  }

}

Notice that @current_user is an instance of AccountProxyInterface, so for example, you can check the user has some user permissions with $this->accountProxy->hasPermission().

5
  • That's all correct, the problem is that OP is trying to call the current user in getSubscribedEvents, which simply is not possibe. See my answer. Using it correctly will then involve your approach.
    – Berdir
    Jun 30, 2016 at 12:24
  • @Berdir In fact, I said "Also, EventSubscriberInterface::getSubscribedEvents() just returns an array of events to which the module wants to subscribe. It's those methods associated to the event that eventually do something basing on the current logged-in user."
    – apaderno
    Jun 30, 2016 at 12:29
  • Right, I overlooked that. I'd recommend to move that at the top and make it a bit strong, along the lines of what I wrote. Because clearly @JyotiBohra didn't see it either :)
    – Berdir
    Jun 30, 2016 at 13:07
  • This is working fine for admin users but it is showing anonymous user with id = 0 for other authenticated users.
    – neha
    Jul 20, 2016 at 13:26
  • @njb You need to ask another question where you show your code. Since you didn't show your code, I cannot answer about that. You can't edit the question to add your code, or you would change the question meaning. Notice also that my code doesn't contain the part you didn't show, since I can't know to which events you are trying to subscribe.
    – apaderno
    Jul 20, 2016 at 13:57
2

You have to use namespace for load the current user object.

// Load the current user.
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// get field data from that user

$email = $user->get('mail')->value;
$name = $user->get('name')->value;
6
  • This answer doesn't have to do anything with the question. First of all: when using static calls you don't have to use namespaces, or whatsoever. Secondly: he/she got a quiet different exception, it's not like he/she doesn't know who to get values from the user object.
    – ssibal
    Jun 30, 2016 at 10:03
  • when she asked her question, it was without edited and she asked for namespace missing, so i answer that according to that and nothing wrong with my answer also that you put down my answer.
    – Sanjay
    Jun 30, 2016 at 10:10
  • The first revision gave the same exact information you see in the current revision.
    – apaderno
    Jun 30, 2016 at 11:02
  • 1
    This statement: "You have to use namespace for load the current user object": It's irreveleant, that he/she is trying to load it in a evensubscriber service, where (from some reason) the Drupal container is not initialized yet. This problem has nothing to do with namespaces whatsoever.
    – ssibal
    Jun 30, 2016 at 11:12
  • 1
    Still, with the way the title of the question is phrased, this is the best answer. Google brought me here. Mar 28, 2017 at 1:08
2

Here is my whole piece of code which works fine now:

Inside my_module.service.yml

services:
  myModule.event_subscriber:
    class: Drupal\my_module\EventSubscriber\MymoduleSubscriber

    tags:
      - {name: event_subscriber}

Inside MymoduleSubscriber.php

<?php

namespace Drupal\my_module\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class myModule implements EventSubscriberInterface {



  public function xyz(GetResponseEvent $event) {
    $user_id = $this->accountProxy->id();
    if($user_id) {
    }
  }
  /**
   * {@inheritdoc}
   */
  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('xyz');
    return $events;

  }

  public function __construct() {
    $user = \Drupal::currentUser();
    $this->accountProxy = $user;
  }

}
1
  • That is not the way you check ìf the user has logged in; there is a method for that.
    – apaderno
    Jul 20, 2016 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.