8

Recently I've finally begun shifting my focus from D7 to D8, and I'm converting a site over to D8. In D7, I type-hinted my account objects as \stdClass, since they were not members of any class. However in D8, they are now members of the User class.

That said, I'm finding in some code on the net that people are typehinting as Drupal\Core\Session\AccountInterface, and in other places as Drupal\user\UserInterface. How should we be determining which one to use for our typehints, and what is the difference between the two types of objects?

  • I think both of the answers here are decent (and I upvoted both of them as well as the question), but I think both could do a better job explaining the difference between AccountInterface and UserInterface. In other words, why do we have one (and classes the implement it) in \Drupal\Core\Session and another in its own module \Drupal\user. The mechanics are explained, but not the why (which is important to really understand the differences). – mpdonadio Nov 22 '16 at 22:42
6

UserInterface extends ContentEntityInterface, EntityChangedInterface, and AccountInterface. This means there are methods an object implementing UserInterface needs to have but objects implementing AccountInterface don't need to have. For example, there is UserInterface::hasRole(), but AccountInterface::getRoles(); in the first case, there is a helper method allowing to check the object has a specific role, while in the second case you would need to write your code for that, getting the list of the roles with AccountInterface::getRoles().

Which hint should be used is given from the documentation. For example, hook_user_logout() gets an object implementing \Drupal\Core\Session\AccountProxyInterface, since it gets the object returned from Drupal::currentUser(). See user_logout(), the function invoking hook_user_logout().

  $user = \Drupal::currentUser();

  \Drupal::logger('user')->notice('Session closed for %name.', array('%name' => $user->getAccountName()));

  \Drupal::moduleHandler()->invokeAll('user_logout', array($user));

Sometime the documentation for a hook doesn't show a specific hint, such as in the case of hook_user_login(). In this case, it could help to see which hint is used from the implementations of that hook, for example system_user_login(), which uses UserInterface as hint for its argument.

When you aren't sure about the correct interface implemented by the object passed to a function (including a hook), use the most generic one as hint. In the case you describe, that would be AccountInterface.

4

As UserInterface extends AccountInterface setting type hint to AccountInterface would allow you to accept both types of objects. You may think about UserInterface as advanced AccountInterface which declares a few extra methods (hasRole, addRole, removeRole, etc). I would use AccountInterface interface wherever it possible unless you need some of these extra methods.

One more detail, object of UserInterface should also implement methods from ContentEntityInterface and EntityChangedInterface.

2

Check the documentation for AccountInterface:

Defines an object that has a user id, roles and can have session data. The interface is implemented both by the global session and the user entity

It's in the Session namespace for a reason – it represents something that can have session data.

The ContentEntityInterface and EntityChangedInterface interfaces extended by UserInterface tell you that it represents a different concept:

Content entities use fields for all their entity properties and are translatable and revisionable, while translations and revisions can be enabled per entity type.

Defines an interface for entity change timestamp tracking.

This data may be useful for more precise cache invalidation (especially on the client side) and concurrent editing locking.

A UserInterface represents a full Drupal user account that can have revisions, fields, translations, etc.


I can't tell you which is more fitting for your use case, but I encourage you to think about which of these interfaces is most applicable for the code you are writing.

My instinct tells me that you would use AccountInterface for something that is minimally "logged in" (e.g. logged in user, a list of users online, someone signed in through SSO) and UserInterface for anything more than that (e.g. user profiles, associated authors, long-lived data, most things we do in Drupal).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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