Newer
Older
<?php
/**
* @file
* Contains \Drupal\user\Entity\User.
*/
namespace Drupal\user\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
Alex Pott
committed
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\user\UserInterface;
/**
* Defines the user entity class.
Angie Byron
committed
*
* The base table name here is plural, despite Drupal table naming standards,
* because "user" is a reserved word in many databases.
*
Alex Pott
committed
* @ContentEntityType(
Angie Byron
committed
* id = "user",
* label = @Translation("User"),
Alex Pott
committed
* handlers = {
catch
committed
* "storage" = "Drupal\user\UserStorage",
* "access" = "Drupal\user\UserAccessControlHandler",
* "list_builder" = "Drupal\user\UserListBuilder",
Alex Pott
committed
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "views_data" = "Drupal\user\UserViewsData",
Alex Pott
committed
* "default" = "Drupal\user\ProfileForm",
* "cancel" = "Drupal\user\Form\UserCancelForm",
Alex Pott
committed
* "register" = "Drupal\user\RegisterForm"
* "translation" = "Drupal\user\ProfileTranslationHandler"
Angie Byron
committed
* },
* admin_permission = "administer user",
Angie Byron
committed
* base_table = "users",
Alex Pott
committed
* data_table = "users_field_data",
catch
committed
* label_callback = "user_format_name",
Angie Byron
committed
* fieldable = TRUE,
Angie Byron
committed
* translatable = TRUE,
Angie Byron
committed
* entity_keys = {
* "id" = "uid",
* "uuid" = "uuid"
Alex Pott
committed
* },
* links = {
* "canonical" = "entity.user.canonical",
* "edit-form" = "entity.user.edit_form",
Alex Pott
committed
* "cancel-form" = "entity.user.cancel_form",
* },
* field_ui_base_route = "entity.user.admin_form",
Angie Byron
committed
* )
*/
class User extends ContentEntityBase implements UserInterface {
/**
* The hostname for this user.
*
* @var string
*/
protected $hostname;
Alex Pott
committed
/**
* {@inheritdoc}
*/
public function isNew() {
return !empty($this->enforceIsNew) || $this->id() === NULL;
}
/**
* {@inheritdoc}
*/
catch
committed
static function preCreate(EntityStorageInterface $storage, array &$values) {
parent::preCreate($storage, $values);
Angie Byron
committed
// Users always have the authenticated user role.
$values['roles'][] = DRUPAL_AUTHENTICATED_RID;
}
/**
* {@inheritdoc}
*/
catch
committed
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
Angie Byron
committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Update the user password if it has changed.
if ($this->isNew() || ($this->pass->value && $this->pass->value != $this->original->pass->value)) {
// Allow alternate password hashing schemes.
$this->pass->value = \Drupal::service('password')->hash(trim($this->pass->value));
// Abort if the hashing failed and returned FALSE.
if (!$this->pass->value) {
throw new EntityMalformedException('The entity does not have a password.');
}
}
if (!$this->isNew()) {
// If the password is empty, that means it was not changed, so use the
// original password.
if (empty($this->pass->value)) {
$this->pass->value = $this->original->pass->value;
}
}
// Store account cancellation information.
foreach (array('user_cancel_method', 'user_cancel_notify') as $key) {
if (isset($this->{$key})) {
\Drupal::service('user.data')->set('user', $this->id(), substr($key, 5), $this->{$key});
}
}
}
/**
* {@inheritdoc}
*/
catch
committed
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
Angie Byron
committed
if ($update) {
$session_manager = \Drupal::service('session_manager');
// If the password has been changed, delete all open sessions for the
// user and recreate the current one.
if ($this->pass->value != $this->original->pass->value) {
$session_manager->delete($this->id());
if ($this->id() == \Drupal::currentUser()->id()) {
$session_manager->regenerate();
}
}
// Update user roles if changed.
if ($this->getRoles() != $this->original->getRoles()) {
catch
committed
$storage->deleteUserRoles(array($this->id()));
$storage->saveRoles($this);
}
// If the user was blocked, delete the user's sessions to force a logout.
if ($this->original->status->value != $this->status->value && $this->status->value == 0) {
$session_manager->delete($this->id());
}
// Send emails after we have the new user object.
if ($this->status->value != $this->original->status->value) {
// The user's status is changing; conditionally send notification email.
$op = $this->status->value == 1 ? 'status_activated' : 'status_blocked';
Alex Pott
committed
_user_mail_notify($op, $this);
}
}
else {
// Save user roles.
if (count($this->getRoles()) > 1) {
catch
committed
$storage->saveRoles($this);
}
}
}
/**
* {@inheritdoc}
*/
catch
committed
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
Angie Byron
committed
$uids = array_keys($entities);
\Drupal::service('user.data')->delete(NULL, $uids);
catch
committed
$storage->deleteUserRoles($uids);
}
/**
* {@inheritdoc}
*/
public function getRoles($exclude_locked_roles = FALSE) {
$roles = array();
foreach ($this->get('roles') as $role) {
if (!($exclude_locked_roles && in_array($role->value, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)))) {
$roles[] = $role->value;
}
return $roles;
}
/**
* {@inheritdoc}
*/
public function getSecureSessionId() {
return NULL;
}
/**
* {@inheritdoc}
*/
public function getSessionData() {
return array();
}
/**
* {@inheritdoc}
*/
public function getSessionId() {
return NULL;
}
/**
* {@inheritdoc}
*/
public function getHostname() {
if (!isset($this->hostname) && \Drupal::hasRequest()) {
$this->hostname = \Drupal::request()->getClientIp();
}
return $this->hostname;
}
/**
* {@inheritdoc}
*/
public function hasRole($rid) {
return in_array($rid, $this->getRoles());
}
/**
* {@inheritdoc}
*/
public function addRole($rid) {
$roles = $this->getRoles();
$roles[] = $rid;
$this->set('roles', array_unique($roles));
}
/**
* {@inheritdoc}
*/
public function removeRole($rid) {
$this->set('roles', array_diff($this->getRoles(), array($rid)));
}
/**
* {@inheritdoc}
*/
public function hasPermission($permission) {
// User #1 has all privileges.
if ((int) $this->id() === 1) {
return TRUE;
}
return $this->getRoleStorage()->isPermissionInRoles($permission, $this->getRoles());
}
/**
* {@inheritdoc}
*/
public function getPassword() {
return $this->get('pass')->value;
}
/**
* {@inheritdoc}
*/
public function setPassword($password) {
$this->get('pass')->value = $password;
}
/**
* {@inheritdoc}
*/
public function getEmail() {
return $this->get('mail')->value;
}
/**
* {@inheritdoc}
*/
public function setEmail($mail) {
$this->get('mail')->value = $mail;
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
}
/**
* {@inheritdoc}
*/
public function getSignature() {
return $this->get('signature')->value;
}
/**
* {@inheritdoc}
*/
public function getSignatureFormat() {
return $this->get('signature_format')->value;
}
/**
* {@inheritdoc}
*/
public function getCreatedTime() {
return $this->get('created')->value;
}
/**
* {@inheritdoc}
*/
public function getLastAccessedTime() {
return $this->get('access')->value;
}
/**
* {@inheritdoc}
*/
public function setLastAccessTime($timestamp) {
$this->get('access')->value = $timestamp;
}
/**
* {@inheritdoc}
*/
public function getLastLoginTime() {
return $this->get('login')->value;
}
/**
* {@inheritdoc}
*/
public function setLastLoginTime($timestamp) {
$this->get('login')->value = $timestamp;
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
}
/**
* {@inheritdoc}
*/
public function isActive() {
return $this->get('status')->value == 1;
}
/**
* {@inheritdoc}
*/
public function isBlocked() {
return $this->get('status')->value == 0;
}
/**
* {@inheritdoc}
*/
public function activate() {
$this->get('status')->value = 1;
return $this;
}
/**
* {@inheritdoc}
*/
public function block() {
$this->get('status')->value = 0;
return $this;
}
/**
* {@inheritdoc}
*/
public function getTimeZone() {
return $this->get('timezone')->value;
}
/**
* {@inheritdoc}
*/
catch
committed
function getPreferredLangcode($fallback_to_default = TRUE) {
$language_list = language_list();
$preferred_langcode = $this->get('preferred_langcode')->value;
if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
return $language_list[$preferred_langcode]->id;
}
else {
catch
committed
return $fallback_to_default ? language_default()->id : '';
}
}
/**
* {@inheritdoc}
*/
catch
committed
function getPreferredAdminLangcode($fallback_to_default = TRUE) {
$language_list = language_list();
$preferred_langcode = $this->get('preferred_admin_langcode')->value;
if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
return $language_list[$preferred_langcode]->id;
}
else {
catch
committed
return $fallback_to_default ? language_default()->id : '';
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
}
}
/**
* {@inheritdoc}
*/
public function getInitialEmail() {
return $this->get('init')->value;
}
/**
* {@inheritdoc}
*/
public function isAuthenticated() {
return $this->id() > 0;
}
/**
* {@inheritdoc}
*/
public function isAnonymous() {
return $this->id() == 0;
}
/**
* {@inheritdoc}
*/
public function getUsername() {
$name = $this->get('name')->value ?: \Drupal::config('user.settings')->get('anonymous');
\Drupal::moduleHandler()->alter('user_format_name', $name, $this);
return $name;
}
/**
* {@inheritdoc}
*/
public function setUsername($username) {
$this->set('name', $username);
return $this;
}
/**
* {@inheritdoc}
*/
public function getChangedTime() {
return $this->get('changed')->value;
}
Alex Pott
committed
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
Alex Pott
committed
$fields['uid'] = BaseFieldDefinition::create('integer')
->setLabel(t('User ID'))
->setDescription(t('The user ID.'))
catch
committed
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
Alex Pott
committed
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The user UUID.'))
->setReadOnly(TRUE);
Alex Pott
committed
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code'))
->setDescription(t('The user language code.'));
Alex Pott
committed
$fields['preferred_langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Preferred admin language code'))
->setDescription(t("The user's preferred language code for receiving emails and viewing the site."));
Alex Pott
committed
$fields['preferred_admin_langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Preferred language code'))
->setDescription(t("The user's preferred language code for viewing administration pages."));
// The name should not vary per language. The username is the visual
// identifier for a user and needs to be consistent in all languages.
Alex Pott
committed
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of this user.'))
Alex Pott
committed
->setDefaultValue('')
->setPropertyConstraints('value', array(
// No Length constraint here because the UserName constraint also covers
catch
committed
// that.
'UserName' => array(),
'UserNameUnique' => array(),
));
Alex Pott
committed
$fields['pass'] = BaseFieldDefinition::create('string')
->setLabel(t('Password'))
->setDescription(t('The password of this user (hashed).'));
Alex Pott
committed
$fields['mail'] = BaseFieldDefinition::create('email')
->setLabel(t('Email'))
->setDescription(t('The email of this user.'))
Alex Pott
committed
->setDefaultValue('')
->setPropertyConstraints('value', array('UserMailUnique' => array()));
// @todo Convert to a text field in https://drupal.org/node/1548204.
Alex Pott
committed
$fields['signature'] = BaseFieldDefinition::create('string')
->setLabel(t('Signature'))
Alex Pott
committed
->setDescription(t('The signature of this user.'))
->setTranslatable(TRUE);
Alex Pott
committed
$fields['signature_format'] = BaseFieldDefinition::create('string')
->setLabel(t('Signature format'))
->setDescription(t('The signature format of this user.'));
Alex Pott
committed
$fields['timezone'] = BaseFieldDefinition::create('string')
->setLabel(t('Timezone'))
->setDescription(t('The timezone of this user.'))
->setSetting('max_length', 32);
Alex Pott
committed
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('User status'))
->setDescription(t('Whether the user is active or blocked.'))
Alex Pott
committed
->setDefaultValue(FALSE);
Alex Pott
committed
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the user was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the user was last edited.'));
Alex Pott
committed
$fields['access'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('Last access'))
->setDescription(t('The time that the user last accessed the site.'))
Alex Pott
committed
->setDefaultValue(0);
Alex Pott
committed
$fields['login'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('Last login'))
->setDescription(t('The time that the user last logged in.'))
Alex Pott
committed
->setDefaultValue(0);
Alex Pott
committed
$fields['init'] = BaseFieldDefinition::create('email')
->setLabel(t('Initial email'))
->setDescription(t('The email address used for initial account creation.'))
Alex Pott
committed
->setDefaultValue('');
// @todo Convert this to entity_reference_field, see
// https://drupal.org/node/2044859.
Alex Pott
committed
$fields['roles'] = BaseFieldDefinition::create('string')
->setCustomStorage(TRUE)
->setLabel(t('Roles'))
Alex Pott
committed
->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
->setDescription(t('The roles the user has.'));
return $fields;
Alex Pott
committed
}
/**
* Returns the role storage object.
*
* @return \Drupal\user\RoleStorageInterface
* The role storage object.
*/
protected function getRoleStorage() {
return \Drupal::entityManager()->getStorage('user_role');
}