PageRenderTime 36ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/core/modules/user/src/Entity/User.php

https://gitlab.com/longphu/drupal8
PHP | 556 lines | 289 code | 74 blank | 193 comment | 40 complexity | 07c1859dcb33066b4d8ec23a7ef37aef MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, LGPL-2.1, CC-BY-SA-3.0
  1. <?php
  2. /**
  3. * @file
  4. * Contains \Drupal\user\Entity\User.
  5. */
  6. namespace Drupal\user\Entity;
  7. use Drupal\Core\Entity\ContentEntityBase;
  8. use Drupal\Core\Entity\EntityMalformedException;
  9. use Drupal\Core\Entity\EntityStorageInterface;
  10. use Drupal\Core\Entity\EntityTypeInterface;
  11. use Drupal\Core\Field\BaseFieldDefinition;
  12. use Drupal\user\UserInterface;
  13. /**
  14. * Defines the user entity class.
  15. *
  16. * The base table name here is plural, despite Drupal table naming standards,
  17. * because "user" is a reserved word in many databases.
  18. *
  19. * @ContentEntityType(
  20. * id = "user",
  21. * label = @Translation("User"),
  22. * handlers = {
  23. * "storage" = "Drupal\user\UserStorage",
  24. * "storage_schema" = "Drupal\user\UserStorageSchema",
  25. * "access" = "Drupal\user\UserAccessControlHandler",
  26. * "list_builder" = "Drupal\user\UserListBuilder",
  27. * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
  28. * "views_data" = "Drupal\user\UserViewsData",
  29. * "route_provider" = {
  30. * "html" = "Drupal\user\Entity\UserRouteProvider",
  31. * },
  32. * "form" = {
  33. * "default" = "Drupal\user\ProfileForm",
  34. * "cancel" = "Drupal\user\Form\UserCancelForm",
  35. * "register" = "Drupal\user\RegisterForm"
  36. * },
  37. * "translation" = "Drupal\user\ProfileTranslationHandler"
  38. * },
  39. * admin_permission = "administer user",
  40. * base_table = "users",
  41. * data_table = "users_field_data",
  42. * label_callback = "user_format_name",
  43. * translatable = TRUE,
  44. * entity_keys = {
  45. * "id" = "uid",
  46. * "langcode" = "langcode",
  47. * "uuid" = "uuid"
  48. * },
  49. * links = {
  50. * "canonical" = "/user/{user}",
  51. * "edit-form" = "/user/{user}/edit",
  52. * "cancel-form" = "/user/{user}/cancel",
  53. * "collection" = "/admin/people",
  54. * },
  55. * field_ui_base_route = "entity.user.admin_form"
  56. * )
  57. */
  58. class User extends ContentEntityBase implements UserInterface {
  59. /**
  60. * The hostname for this user.
  61. *
  62. * @var string
  63. */
  64. protected $hostname;
  65. /**
  66. * {@inheritdoc}
  67. */
  68. public function isNew() {
  69. return !empty($this->enforceIsNew) || $this->id() === NULL;
  70. }
  71. /**
  72. * {@inheritdoc}
  73. */
  74. public function preSave(EntityStorageInterface $storage) {
  75. parent::preSave($storage);
  76. // Make sure that the authenticated/anonymous roles are not persisted.
  77. foreach ($this->get('roles') as $index => $item) {
  78. if (in_array($item->target_id, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
  79. $this->get('roles')->offsetUnset($index);
  80. }
  81. }
  82. // Update the user password if it has changed.
  83. if ($this->isNew() || ($this->pass->value && $this->pass->value != $this->original->pass->value)) {
  84. // Allow alternate password hashing schemes.
  85. $this->pass->value = \Drupal::service('password')->hash(trim($this->pass->value));
  86. // Abort if the hashing failed and returned FALSE.
  87. if (!$this->pass->value) {
  88. throw new EntityMalformedException('The entity does not have a password.');
  89. }
  90. }
  91. if (!$this->isNew()) {
  92. // If the password is empty, that means it was not changed, so use the
  93. // original password.
  94. if (empty($this->pass->value)) {
  95. $this->pass->value = $this->original->pass->value;
  96. }
  97. }
  98. // Store account cancellation information.
  99. foreach (array('user_cancel_method', 'user_cancel_notify') as $key) {
  100. if (isset($this->{$key})) {
  101. \Drupal::service('user.data')->set('user', $this->id(), substr($key, 5), $this->{$key});
  102. }
  103. }
  104. }
  105. /**
  106. * {@inheritdoc}
  107. */
  108. public function postSave(EntityStorageInterface $storage, $update = TRUE) {
  109. parent::postSave($storage, $update);
  110. if ($update) {
  111. $session_manager = \Drupal::service('session_manager');
  112. // If the password has been changed, delete all open sessions for the
  113. // user and recreate the current one.
  114. if ($this->pass->value != $this->original->pass->value) {
  115. $session_manager->delete($this->id());
  116. if ($this->id() == \Drupal::currentUser()->id()) {
  117. $session_manager->regenerate();
  118. }
  119. }
  120. // If the user was blocked, delete the user's sessions to force a logout.
  121. if ($this->original->status->value != $this->status->value && $this->status->value == 0) {
  122. $session_manager->delete($this->id());
  123. }
  124. // Send emails after we have the new user object.
  125. if ($this->status->value != $this->original->status->value) {
  126. // The user's status is changing; conditionally send notification email.
  127. $op = $this->status->value == 1 ? 'status_activated' : 'status_blocked';
  128. _user_mail_notify($op, $this);
  129. }
  130. }
  131. }
  132. /**
  133. * {@inheritdoc}
  134. */
  135. public static function postDelete(EntityStorageInterface $storage, array $entities) {
  136. parent::postDelete($storage, $entities);
  137. $uids = array_keys($entities);
  138. \Drupal::service('user.data')->delete(NULL, $uids);
  139. }
  140. /**
  141. * {@inheritdoc}
  142. */
  143. public function getRoles($exclude_locked_roles = FALSE) {
  144. $roles = array();
  145. // Users with an ID always have the authenticated user role.
  146. if (!$exclude_locked_roles) {
  147. if ($this->isAuthenticated()) {
  148. $roles[] = DRUPAL_AUTHENTICATED_RID;
  149. }
  150. else {
  151. $roles[] = DRUPAL_ANONYMOUS_RID;
  152. }
  153. }
  154. foreach ($this->get('roles') as $role) {
  155. if ($role->target_id) {
  156. $roles[] = $role->target_id;
  157. }
  158. }
  159. return $roles;
  160. }
  161. /**
  162. * {@inheritdoc}
  163. */
  164. public function getSecureSessionId() {
  165. return NULL;
  166. }
  167. /**
  168. * {@inheritdoc}
  169. */
  170. public function getSessionData() {
  171. return array();
  172. }
  173. /**
  174. * {@inheritdoc}
  175. */
  176. public function getSessionId() {
  177. return NULL;
  178. }
  179. /**
  180. * {@inheritdoc}
  181. */
  182. public function getHostname() {
  183. if (!isset($this->hostname) && \Drupal::hasRequest()) {
  184. $this->hostname = \Drupal::request()->getClientIp();
  185. }
  186. return $this->hostname;
  187. }
  188. /**
  189. * {@inheritdoc}
  190. */
  191. public function hasRole($rid) {
  192. return in_array($rid, $this->getRoles());
  193. }
  194. /**
  195. * {@inheritdoc}
  196. */
  197. public function addRole($rid) {
  198. if (in_array($rid, [DRUPAL_AUTHENTICATED_RID, DRUPAL_ANONYMOUS_RID])) {
  199. throw new \InvalidArgumentException('Anonymous or authenticated role ID must not be assigned manually.');
  200. }
  201. $roles = $this->getRoles(TRUE);
  202. $roles[] = $rid;
  203. $this->set('roles', array_unique($roles));
  204. }
  205. /**
  206. * {@inheritdoc}
  207. */
  208. public function removeRole($rid) {
  209. $this->set('roles', array_diff($this->getRoles(TRUE), array($rid)));
  210. }
  211. /**
  212. * {@inheritdoc}
  213. */
  214. public function hasPermission($permission) {
  215. // User #1 has all privileges.
  216. if ((int) $this->id() === 1) {
  217. return TRUE;
  218. }
  219. return $this->getRoleStorage()->isPermissionInRoles($permission, $this->getRoles());
  220. }
  221. /**
  222. * {@inheritdoc}
  223. */
  224. public function getPassword() {
  225. return $this->get('pass')->value;
  226. }
  227. /**
  228. * {@inheritdoc}
  229. */
  230. public function setPassword($password) {
  231. $this->get('pass')->value = $password;
  232. return $this;
  233. }
  234. /**
  235. * {@inheritdoc}
  236. */
  237. public function getEmail() {
  238. return $this->get('mail')->value;
  239. }
  240. /**
  241. * {@inheritdoc}
  242. */
  243. public function setEmail($mail) {
  244. $this->get('mail')->value = $mail;
  245. return $this;
  246. }
  247. /**
  248. * {@inheritdoc}
  249. */
  250. public function getSignature() {
  251. return $this->get('signature')->value;
  252. }
  253. /**
  254. * {@inheritdoc}
  255. */
  256. public function getSignatureFormat() {
  257. return $this->get('signature_format')->value;
  258. }
  259. /**
  260. * {@inheritdoc}
  261. */
  262. public function getCreatedTime() {
  263. return $this->get('created')->value;
  264. }
  265. /**
  266. * {@inheritdoc}
  267. */
  268. public function getLastAccessedTime() {
  269. return $this->get('access')->value;
  270. }
  271. /**
  272. * {@inheritdoc}
  273. */
  274. public function setLastAccessTime($timestamp) {
  275. $this->get('access')->value = $timestamp;
  276. return $this;
  277. }
  278. /**
  279. * {@inheritdoc}
  280. */
  281. public function getLastLoginTime() {
  282. return $this->get('login')->value;
  283. }
  284. /**
  285. * {@inheritdoc}
  286. */
  287. public function setLastLoginTime($timestamp) {
  288. $this->get('login')->value = $timestamp;
  289. return $this;
  290. }
  291. /**
  292. * {@inheritdoc}
  293. */
  294. public function isActive() {
  295. return $this->get('status')->value == 1;
  296. }
  297. /**
  298. * {@inheritdoc}
  299. */
  300. public function isBlocked() {
  301. return $this->get('status')->value == 0;
  302. }
  303. /**
  304. * {@inheritdoc}
  305. */
  306. public function activate() {
  307. $this->get('status')->value = 1;
  308. return $this;
  309. }
  310. /**
  311. * {@inheritdoc}
  312. */
  313. public function block() {
  314. $this->get('status')->value = 0;
  315. return $this;
  316. }
  317. /**
  318. * {@inheritdoc}
  319. */
  320. public function getTimeZone() {
  321. return $this->get('timezone')->value;
  322. }
  323. /**
  324. * {@inheritdoc}
  325. */
  326. function getPreferredLangcode($fallback_to_default = TRUE) {
  327. $language_list = $this->languageManager()->getLanguages();
  328. $preferred_langcode = $this->get('preferred_langcode')->value;
  329. if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
  330. return $language_list[$preferred_langcode]->getId();
  331. }
  332. else {
  333. return $fallback_to_default ? $this->languageManager()->getDefaultLanguage()->getId() : '';
  334. }
  335. }
  336. /**
  337. * {@inheritdoc}
  338. */
  339. function getPreferredAdminLangcode($fallback_to_default = TRUE) {
  340. $language_list = $this->languageManager()->getLanguages();
  341. $preferred_langcode = $this->get('preferred_admin_langcode')->value;
  342. if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) {
  343. return $language_list[$preferred_langcode]->getId();
  344. }
  345. else {
  346. return $fallback_to_default ? $this->languageManager()->getDefaultLanguage()->getId() : '';
  347. }
  348. }
  349. /**
  350. * {@inheritdoc}
  351. */
  352. public function getInitialEmail() {
  353. return $this->get('init')->value;
  354. }
  355. /**
  356. * {@inheritdoc}
  357. */
  358. public function isAuthenticated() {
  359. return $this->id() > 0;
  360. }
  361. /**
  362. * {@inheritdoc}
  363. */
  364. public function isAnonymous() {
  365. return $this->id() == 0;
  366. }
  367. /**
  368. * {@inheritdoc}
  369. */
  370. public function getUsername() {
  371. $name = $this->get('name')->value ?: \Drupal::config('user.settings')->get('anonymous');
  372. \Drupal::moduleHandler()->alter('user_format_name', $name, $this);
  373. return $name;
  374. }
  375. /**
  376. * {@inheritdoc}
  377. */
  378. public function setUsername($username) {
  379. $this->set('name', $username);
  380. return $this;
  381. }
  382. /**
  383. * {@inheritdoc}
  384. */
  385. public function getChangedTime() {
  386. return $this->get('changed')->value;
  387. }
  388. /**
  389. * {@inheritdoc}
  390. */
  391. public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
  392. $fields['uid'] = BaseFieldDefinition::create('integer')
  393. ->setLabel(t('User ID'))
  394. ->setDescription(t('The user ID.'))
  395. ->setReadOnly(TRUE)
  396. ->setSetting('unsigned', TRUE);
  397. $fields['uuid'] = BaseFieldDefinition::create('uuid')
  398. ->setLabel(t('UUID'))
  399. ->setDescription(t('The user UUID.'))
  400. ->setReadOnly(TRUE);
  401. $fields['langcode'] = BaseFieldDefinition::create('language')
  402. ->setLabel(t('Language code'))
  403. ->setDescription(t('The user language code.'));
  404. $fields['preferred_langcode'] = BaseFieldDefinition::create('language')
  405. ->setLabel(t('Preferred language code'))
  406. ->setDescription(t("The user's preferred language code for receiving emails and viewing the site."));
  407. $fields['preferred_admin_langcode'] = BaseFieldDefinition::create('language')
  408. ->setLabel(t('Preferred admin language code'))
  409. ->setDescription(t("The user's preferred language code for viewing administration pages."))
  410. ->setDefaultValue('');
  411. // The name should not vary per language. The username is the visual
  412. // identifier for a user and needs to be consistent in all languages.
  413. $fields['name'] = BaseFieldDefinition::create('string')
  414. ->setLabel(t('Name'))
  415. ->setDescription(t('The name of this user.'))
  416. ->setDefaultValue('')
  417. ->setConstraints(array(
  418. // No Length constraint here because the UserName constraint also covers
  419. // that.
  420. 'UserName' => array(),
  421. 'UserNameUnique' => array(),
  422. ));
  423. $fields['pass'] = BaseFieldDefinition::create('string')
  424. ->setLabel(t('Password'))
  425. ->setDescription(t('The password of this user (hashed).'));
  426. $fields['mail'] = BaseFieldDefinition::create('email')
  427. ->setLabel(t('Email'))
  428. ->setDescription(t('The email of this user.'))
  429. ->setDefaultValue('')
  430. ->setConstraints(array('UserMailUnique' => array()));
  431. // @todo Convert to a text field in https://drupal.org/node/1548204.
  432. $fields['signature'] = BaseFieldDefinition::create('string')
  433. ->setLabel(t('Signature'))
  434. ->setDescription(t('The signature of this user.'))
  435. ->setTranslatable(TRUE);
  436. $fields['signature_format'] = BaseFieldDefinition::create('string')
  437. ->setLabel(t('Signature format'))
  438. ->setDescription(t('The signature format of this user.'));
  439. $fields['timezone'] = BaseFieldDefinition::create('string')
  440. ->setLabel(t('Timezone'))
  441. ->setDescription(t('The timezone of this user.'))
  442. ->setSetting('max_length', 32);
  443. $fields['status'] = BaseFieldDefinition::create('boolean')
  444. ->setLabel(t('User status'))
  445. ->setDescription(t('Whether the user is active or blocked.'))
  446. ->setDefaultValue(FALSE);
  447. $fields['created'] = BaseFieldDefinition::create('created')
  448. ->setLabel(t('Created'))
  449. ->setDescription(t('The time that the user was created.'));
  450. $fields['changed'] = BaseFieldDefinition::create('changed')
  451. ->setLabel(t('Changed'))
  452. ->setDescription(t('The time that the user was last edited.'));
  453. $fields['access'] = BaseFieldDefinition::create('timestamp')
  454. ->setLabel(t('Last access'))
  455. ->setDescription(t('The time that the user last accessed the site.'))
  456. ->setDefaultValue(0);
  457. $fields['login'] = BaseFieldDefinition::create('timestamp')
  458. ->setLabel(t('Last login'))
  459. ->setDescription(t('The time that the user last logged in.'))
  460. ->setDefaultValue(0);
  461. $fields['init'] = BaseFieldDefinition::create('email')
  462. ->setLabel(t('Initial email'))
  463. ->setDescription(t('The email address used for initial account creation.'))
  464. ->setDefaultValue('');
  465. $fields['roles'] = BaseFieldDefinition::create('entity_reference')
  466. ->setLabel(t('Roles'))
  467. ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
  468. ->setDescription(t('The roles the user has.'))
  469. ->setSetting('target_type', 'user_role');
  470. return $fields;
  471. }
  472. /**
  473. * Returns the role storage object.
  474. *
  475. * @return \Drupal\user\RoleStorageInterface
  476. * The role storage object.
  477. */
  478. protected function getRoleStorage() {
  479. return \Drupal::entityManager()->getStorage('user_role');
  480. }
  481. }