Mercurial > hg > isophonics-drupal-site
comparison core/modules/user/src/Entity/User.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\user\Entity; | |
4 | |
5 use Drupal\Core\Entity\ContentEntityBase; | |
6 use Drupal\Core\Entity\EntityChangedTrait; | |
7 use Drupal\Core\Entity\EntityStorageInterface; | |
8 use Drupal\Core\Entity\EntityTypeInterface; | |
9 use Drupal\Core\Field\BaseFieldDefinition; | |
10 use Drupal\Core\Language\LanguageInterface; | |
11 use Drupal\user\RoleInterface; | |
12 use Drupal\user\UserInterface; | |
13 | |
14 /** | |
15 * Defines the user entity class. | |
16 * | |
17 * The base table name here is plural, despite Drupal table naming standards, | |
18 * because "user" is a reserved word in many databases. | |
19 * | |
20 * @ContentEntityType( | |
21 * id = "user", | |
22 * label = @Translation("User"), | |
23 * handlers = { | |
24 * "storage" = "Drupal\user\UserStorage", | |
25 * "storage_schema" = "Drupal\user\UserStorageSchema", | |
26 * "access" = "Drupal\user\UserAccessControlHandler", | |
27 * "list_builder" = "Drupal\user\UserListBuilder", | |
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 users", | |
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 * common_reference_target = TRUE | |
57 * ) | |
58 */ | |
59 class User extends ContentEntityBase implements UserInterface { | |
60 | |
61 use EntityChangedTrait; | |
62 | |
63 /** | |
64 * Stores a reference for a reusable anonymous user entity. | |
65 * | |
66 * @var \Drupal\user\UserInterface | |
67 */ | |
68 protected static $anonymousUser; | |
69 | |
70 /** | |
71 * {@inheritdoc} | |
72 */ | |
73 public function isNew() { | |
74 return !empty($this->enforceIsNew) || $this->id() === NULL; | |
75 } | |
76 | |
77 /** | |
78 * {@inheritdoc} | |
79 */ | |
80 public function preSave(EntityStorageInterface $storage) { | |
81 parent::preSave($storage); | |
82 | |
83 // Make sure that the authenticated/anonymous roles are not persisted. | |
84 foreach ($this->get('roles') as $index => $item) { | |
85 if (in_array($item->target_id, [RoleInterface::ANONYMOUS_ID, RoleInterface::AUTHENTICATED_ID])) { | |
86 $this->get('roles')->offsetUnset($index); | |
87 } | |
88 } | |
89 | |
90 // Store account cancellation information. | |
91 foreach (['user_cancel_method', 'user_cancel_notify'] as $key) { | |
92 if (isset($this->{$key})) { | |
93 \Drupal::service('user.data')->set('user', $this->id(), substr($key, 5), $this->{$key}); | |
94 } | |
95 } | |
96 } | |
97 | |
98 /** | |
99 * {@inheritdoc} | |
100 */ | |
101 public function postSave(EntityStorageInterface $storage, $update = TRUE) { | |
102 parent::postSave($storage, $update); | |
103 | |
104 if ($update) { | |
105 $session_manager = \Drupal::service('session_manager'); | |
106 // If the password has been changed, delete all open sessions for the | |
107 // user and recreate the current one. | |
108 if ($this->pass->value != $this->original->pass->value) { | |
109 $session_manager->delete($this->id()); | |
110 if ($this->id() == \Drupal::currentUser()->id()) { | |
111 \Drupal::service('session')->migrate(); | |
112 } | |
113 } | |
114 | |
115 // If the user was blocked, delete the user's sessions to force a logout. | |
116 if ($this->original->status->value != $this->status->value && $this->status->value == 0) { | |
117 $session_manager->delete($this->id()); | |
118 } | |
119 | |
120 // Send emails after we have the new user object. | |
121 if ($this->status->value != $this->original->status->value) { | |
122 // The user's status is changing; conditionally send notification email. | |
123 $op = $this->status->value == 1 ? 'status_activated' : 'status_blocked'; | |
124 _user_mail_notify($op, $this); | |
125 } | |
126 } | |
127 } | |
128 | |
129 /** | |
130 * {@inheritdoc} | |
131 */ | |
132 public static function postDelete(EntityStorageInterface $storage, array $entities) { | |
133 parent::postDelete($storage, $entities); | |
134 | |
135 $uids = array_keys($entities); | |
136 \Drupal::service('user.data')->delete(NULL, $uids); | |
137 } | |
138 | |
139 /** | |
140 * {@inheritdoc} | |
141 */ | |
142 public function getRoles($exclude_locked_roles = FALSE) { | |
143 $roles = []; | |
144 | |
145 // Users with an ID always have the authenticated user role. | |
146 if (!$exclude_locked_roles) { | |
147 if ($this->isAuthenticated()) { | |
148 $roles[] = RoleInterface::AUTHENTICATED_ID; | |
149 } | |
150 else { | |
151 $roles[] = RoleInterface::ANONYMOUS_ID; | |
152 } | |
153 } | |
154 | |
155 foreach ($this->get('roles') as $role) { | |
156 if ($role->target_id) { | |
157 $roles[] = $role->target_id; | |
158 } | |
159 } | |
160 | |
161 return $roles; | |
162 } | |
163 | |
164 /** | |
165 * {@inheritdoc} | |
166 */ | |
167 public function hasRole($rid) { | |
168 return in_array($rid, $this->getRoles()); | |
169 } | |
170 | |
171 /** | |
172 * {@inheritdoc} | |
173 */ | |
174 public function addRole($rid) { | |
175 | |
176 if (in_array($rid, [RoleInterface::AUTHENTICATED_ID, RoleInterface::ANONYMOUS_ID])) { | |
177 throw new \InvalidArgumentException('Anonymous or authenticated role ID must not be assigned manually.'); | |
178 } | |
179 | |
180 $roles = $this->getRoles(TRUE); | |
181 $roles[] = $rid; | |
182 $this->set('roles', array_unique($roles)); | |
183 } | |
184 | |
185 /** | |
186 * {@inheritdoc} | |
187 */ | |
188 public function removeRole($rid) { | |
189 $this->set('roles', array_diff($this->getRoles(TRUE), [$rid])); | |
190 } | |
191 | |
192 /** | |
193 * {@inheritdoc} | |
194 */ | |
195 public function hasPermission($permission) { | |
196 // User #1 has all privileges. | |
197 if ((int) $this->id() === 1) { | |
198 return TRUE; | |
199 } | |
200 | |
201 return $this->getRoleStorage()->isPermissionInRoles($permission, $this->getRoles()); | |
202 } | |
203 | |
204 /** | |
205 * {@inheritdoc} | |
206 */ | |
207 public function getPassword() { | |
208 return $this->get('pass')->value; | |
209 } | |
210 | |
211 /** | |
212 * {@inheritdoc} | |
213 */ | |
214 public function setPassword($password) { | |
215 $this->get('pass')->value = $password; | |
216 return $this; | |
217 } | |
218 | |
219 /** | |
220 * {@inheritdoc} | |
221 */ | |
222 public function getEmail() { | |
223 return $this->get('mail')->value; | |
224 } | |
225 | |
226 /** | |
227 * {@inheritdoc} | |
228 */ | |
229 public function setEmail($mail) { | |
230 $this->get('mail')->value = $mail; | |
231 return $this; | |
232 } | |
233 | |
234 /** | |
235 * {@inheritdoc} | |
236 */ | |
237 public function getCreatedTime() { | |
238 return $this->get('created')->value; | |
239 } | |
240 | |
241 /** | |
242 * {@inheritdoc} | |
243 */ | |
244 public function getLastAccessedTime() { | |
245 return $this->get('access')->value; | |
246 } | |
247 | |
248 /** | |
249 * {@inheritdoc} | |
250 */ | |
251 public function setLastAccessTime($timestamp) { | |
252 $this->get('access')->value = $timestamp; | |
253 return $this; | |
254 } | |
255 | |
256 /** | |
257 * {@inheritdoc} | |
258 */ | |
259 public function getLastLoginTime() { | |
260 return $this->get('login')->value; | |
261 } | |
262 | |
263 /** | |
264 * {@inheritdoc} | |
265 */ | |
266 public function setLastLoginTime($timestamp) { | |
267 $this->get('login')->value = $timestamp; | |
268 return $this; | |
269 } | |
270 | |
271 /** | |
272 * {@inheritdoc} | |
273 */ | |
274 public function isActive() { | |
275 return $this->get('status')->value == 1; | |
276 } | |
277 | |
278 /** | |
279 * {@inheritdoc} | |
280 */ | |
281 public function isBlocked() { | |
282 return $this->get('status')->value == 0; | |
283 } | |
284 | |
285 /** | |
286 * {@inheritdoc} | |
287 */ | |
288 public function activate() { | |
289 $this->get('status')->value = 1; | |
290 return $this; | |
291 } | |
292 | |
293 /** | |
294 * {@inheritdoc} | |
295 */ | |
296 public function block() { | |
297 $this->get('status')->value = 0; | |
298 return $this; | |
299 } | |
300 | |
301 /** | |
302 * {@inheritdoc} | |
303 */ | |
304 public function getTimeZone() { | |
305 return $this->get('timezone')->value; | |
306 } | |
307 | |
308 /** | |
309 * {@inheritdoc} | |
310 */ | |
311 public function getPreferredLangcode($fallback_to_default = TRUE) { | |
312 $language_list = $this->languageManager()->getLanguages(); | |
313 $preferred_langcode = $this->get('preferred_langcode')->value; | |
314 if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) { | |
315 return $language_list[$preferred_langcode]->getId(); | |
316 } | |
317 else { | |
318 return $fallback_to_default ? $this->languageManager()->getDefaultLanguage()->getId() : ''; | |
319 } | |
320 } | |
321 | |
322 /** | |
323 * {@inheritdoc} | |
324 */ | |
325 public function getPreferredAdminLangcode($fallback_to_default = TRUE) { | |
326 $language_list = $this->languageManager()->getLanguages(); | |
327 $preferred_langcode = $this->get('preferred_admin_langcode')->value; | |
328 if (!empty($preferred_langcode) && isset($language_list[$preferred_langcode])) { | |
329 return $language_list[$preferred_langcode]->getId(); | |
330 } | |
331 else { | |
332 return $fallback_to_default ? $this->languageManager()->getDefaultLanguage()->getId() : ''; | |
333 } | |
334 } | |
335 | |
336 /** | |
337 * {@inheritdoc} | |
338 */ | |
339 public function getInitialEmail() { | |
340 return $this->get('init')->value; | |
341 } | |
342 | |
343 /** | |
344 * {@inheritdoc} | |
345 */ | |
346 public function isAuthenticated() { | |
347 return $this->id() > 0; | |
348 } | |
349 /** | |
350 * {@inheritdoc} | |
351 */ | |
352 public function isAnonymous() { | |
353 return $this->id() == 0; | |
354 } | |
355 | |
356 /** | |
357 * {@inheritdoc} | |
358 */ | |
359 public function getUsername() { | |
360 return $this->getAccountName(); | |
361 } | |
362 | |
363 /** | |
364 * {@inheritdoc} | |
365 */ | |
366 public function getAccountName() { | |
367 return $this->get('name')->value ?: ''; | |
368 } | |
369 | |
370 /** | |
371 * {@inheritdoc} | |
372 */ | |
373 public function getDisplayName() { | |
374 $name = $this->getAccountName() ?: \Drupal::config('user.settings')->get('anonymous'); | |
375 \Drupal::moduleHandler()->alter('user_format_name', $name, $this); | |
376 return $name; | |
377 } | |
378 | |
379 /** | |
380 * {@inheritdoc} | |
381 */ | |
382 public function setUsername($username) { | |
383 $this->set('name', $username); | |
384 return $this; | |
385 } | |
386 | |
387 /** | |
388 * {@inheritdoc} | |
389 */ | |
390 public function setExistingPassword($password) { | |
391 $this->get('pass')->existing = $password; | |
392 } | |
393 | |
394 /** | |
395 * {@inheritdoc} | |
396 */ | |
397 public function checkExistingPassword(UserInterface $account_unchanged) { | |
398 return strlen($this->get('pass')->existing) > 0 && \Drupal::service('password')->check(trim($this->get('pass')->existing), $account_unchanged->getPassword()); | |
399 } | |
400 | |
401 /** | |
402 * Returns an anonymous user entity. | |
403 * | |
404 * @return \Drupal\user\UserInterface | |
405 * An anonymous user entity. | |
406 */ | |
407 public static function getAnonymousUser() { | |
408 if (!isset(static::$anonymousUser)) { | |
409 | |
410 // @todo Use the entity factory once available, see | |
411 // https://www.drupal.org/node/1867228. | |
412 $entity_manager = \Drupal::entityManager(); | |
413 $entity_type = $entity_manager->getDefinition('user'); | |
414 $class = $entity_type->getClass(); | |
415 | |
416 static::$anonymousUser = new $class([ | |
417 'uid' => [LanguageInterface::LANGCODE_DEFAULT => 0], | |
418 'name' => [LanguageInterface::LANGCODE_DEFAULT => ''], | |
419 // Explicitly set the langcode to ensure that field definitions do not | |
420 // need to be fetched to figure out a default. | |
421 'langcode' => [LanguageInterface::LANGCODE_DEFAULT => LanguageInterface::LANGCODE_NOT_SPECIFIED] | |
422 ], $entity_type->id()); | |
423 } | |
424 return clone static::$anonymousUser; | |
425 } | |
426 | |
427 /** | |
428 * {@inheritdoc} | |
429 */ | |
430 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { | |
431 /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ | |
432 $fields = parent::baseFieldDefinitions($entity_type); | |
433 | |
434 $fields['uid']->setLabel(t('User ID')) | |
435 ->setDescription(t('The user ID.')); | |
436 | |
437 $fields['uuid']->setDescription(t('The user UUID.')); | |
438 | |
439 $fields['langcode']->setLabel(t('Language code')) | |
440 ->setDescription(t('The user language code.')) | |
441 ->setDisplayOptions('form', ['region' => 'hidden']); | |
442 | |
443 $fields['preferred_langcode'] = BaseFieldDefinition::create('language') | |
444 ->setLabel(t('Preferred language code')) | |
445 ->setDescription(t("The user's preferred language code for receiving emails and viewing the site.")) | |
446 // @todo: Define this via an options provider once | |
447 // https://www.drupal.org/node/2329937 is completed. | |
448 ->addPropertyConstraints('value', [ | |
449 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'], | |
450 ]); | |
451 | |
452 $fields['preferred_admin_langcode'] = BaseFieldDefinition::create('language') | |
453 ->setLabel(t('Preferred admin language code')) | |
454 ->setDescription(t("The user's preferred language code for viewing administration pages.")) | |
455 // @todo: A default value of NULL is ignored, so we have to specify | |
456 // an empty field item structure instead. Fix this in | |
457 // https://www.drupal.org/node/2318605. | |
458 ->setDefaultValue([0 => ['value' => NULL]]) | |
459 // @todo: Define this via an options provider once | |
460 // https://www.drupal.org/node/2329937 is completed. | |
461 ->addPropertyConstraints('value', [ | |
462 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedConfigurableLanguageCodes'], | |
463 ]); | |
464 | |
465 // The name should not vary per language. The username is the visual | |
466 // identifier for a user and needs to be consistent in all languages. | |
467 $fields['name'] = BaseFieldDefinition::create('string') | |
468 ->setLabel(t('Name')) | |
469 ->setDescription(t('The name of this user.')) | |
470 ->setRequired(TRUE) | |
471 ->setConstraints([ | |
472 // No Length constraint here because the UserName constraint also covers | |
473 // that. | |
474 'UserName' => [], | |
475 'UserNameUnique' => [], | |
476 ]); | |
477 $fields['name']->getItemDefinition()->setClass('\Drupal\user\UserNameItem'); | |
478 | |
479 $fields['pass'] = BaseFieldDefinition::create('password') | |
480 ->setLabel(t('Password')) | |
481 ->setDescription(t('The password of this user (hashed).')) | |
482 ->addConstraint('ProtectedUserField'); | |
483 | |
484 $fields['mail'] = BaseFieldDefinition::create('email') | |
485 ->setLabel(t('Email')) | |
486 ->setDescription(t('The email of this user.')) | |
487 ->setDefaultValue('') | |
488 ->addConstraint('UserMailUnique') | |
489 ->addConstraint('UserMailRequired') | |
490 ->addConstraint('ProtectedUserField'); | |
491 | |
492 $fields['timezone'] = BaseFieldDefinition::create('string') | |
493 ->setLabel(t('Timezone')) | |
494 ->setDescription(t('The timezone of this user.')) | |
495 ->setSetting('max_length', 32) | |
496 // @todo: Define this via an options provider once | |
497 // https://www.drupal.org/node/2329937 is completed. | |
498 ->addPropertyConstraints('value', [ | |
499 'AllowedValues' => ['callback' => __CLASS__ . '::getAllowedTimezones'], | |
500 ]); | |
501 | |
502 $fields['status'] = BaseFieldDefinition::create('boolean') | |
503 ->setLabel(t('User status')) | |
504 ->setDescription(t('Whether the user is active or blocked.')) | |
505 ->setDefaultValue(FALSE); | |
506 | |
507 $fields['created'] = BaseFieldDefinition::create('created') | |
508 ->setLabel(t('Created')) | |
509 ->setDescription(t('The time that the user was created.')); | |
510 | |
511 $fields['changed'] = BaseFieldDefinition::create('changed') | |
512 ->setLabel(t('Changed')) | |
513 ->setDescription(t('The time that the user was last edited.')) | |
514 ->setTranslatable(TRUE); | |
515 | |
516 $fields['access'] = BaseFieldDefinition::create('timestamp') | |
517 ->setLabel(t('Last access')) | |
518 ->setDescription(t('The time that the user last accessed the site.')) | |
519 ->setDefaultValue(0); | |
520 | |
521 $fields['login'] = BaseFieldDefinition::create('timestamp') | |
522 ->setLabel(t('Last login')) | |
523 ->setDescription(t('The time that the user last logged in.')) | |
524 ->setDefaultValue(0); | |
525 | |
526 $fields['init'] = BaseFieldDefinition::create('email') | |
527 ->setLabel(t('Initial email')) | |
528 ->setDescription(t('The email address used for initial account creation.')) | |
529 ->setDefaultValue(''); | |
530 | |
531 $fields['roles'] = BaseFieldDefinition::create('entity_reference') | |
532 ->setLabel(t('Roles')) | |
533 ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED) | |
534 ->setDescription(t('The roles the user has.')) | |
535 ->setSetting('target_type', 'user_role'); | |
536 | |
537 return $fields; | |
538 } | |
539 | |
540 /** | |
541 * Returns the role storage object. | |
542 * | |
543 * @return \Drupal\user\RoleStorageInterface | |
544 * The role storage object. | |
545 */ | |
546 protected function getRoleStorage() { | |
547 return \Drupal::entityManager()->getStorage('user_role'); | |
548 } | |
549 | |
550 /** | |
551 * Defines allowed timezones for the field's AllowedValues constraint. | |
552 * | |
553 * @return string[] | |
554 * The allowed values. | |
555 */ | |
556 public static function getAllowedTimezones() { | |
557 return array_keys(system_time_zones()); | |
558 } | |
559 | |
560 /** | |
561 * Defines allowed configurable language codes for AllowedValues constraints. | |
562 * | |
563 * @return string[] | |
564 * The allowed values. | |
565 */ | |
566 public static function getAllowedConfigurableLanguageCodes() { | |
567 return array_keys(\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_CONFIGURABLE)); | |
568 } | |
569 | |
570 } |