ccccfa77ff5ecc9468b54e85cedcc6cb684e3237
[yaffs-website] / web / core / modules / user / tests / src / Traits / UserCreationTrait.php
1 <?php
2
3 namespace Drupal\Tests\user\Traits;
4
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\Core\Session\AccountInterface;
7 use Drupal\user\Entity\Role;
8 use Drupal\user\Entity\User;
9 use Drupal\user\RoleInterface;
10
11 /**
12  * Provides methods to create additional test users and switch the currently
13  * logged in one.
14  *
15  * This trait is meant to be used only by test classes.
16  */
17 trait UserCreationTrait {
18
19   /**
20    * Switch the current logged in user.
21    *
22    * @param \Drupal\Core\Session\AccountInterface $account
23    *   The user account object.
24    */
25   protected function setCurrentUser(AccountInterface $account) {
26     \Drupal::currentUser()->setAccount($account);
27   }
28
29   /**
30    * Create a user with a given set of permissions.
31    *
32    * @param array $permissions
33    *   Array of permission names to assign to user. Note that the user always
34    *   has the default permissions derived from the "authenticated users" role.
35    * @param string $name
36    *   The user name.
37    * @param bool $admin
38    *   (optional) Whether the user should be an administrator
39    *   with all the available permissions.
40    *
41    * @return \Drupal\user\Entity\User|false
42    *   A fully loaded user object with pass_raw property, or FALSE if account
43    *   creation fails.
44    */
45   protected function createUser(array $permissions = [], $name = NULL, $admin = FALSE) {
46     // Create a role with the given permission set, if any.
47     $rid = FALSE;
48     if ($permissions) {
49       $rid = $this->createRole($permissions);
50       if (!$rid) {
51         return FALSE;
52       }
53     }
54
55     // Create a user assigned to that role.
56     $edit = [];
57     $edit['name'] = !empty($name) ? $name : $this->randomMachineName();
58     $edit['mail'] = $edit['name'] . '@example.com';
59     $edit['pass'] = user_password();
60     $edit['status'] = 1;
61     if ($rid) {
62       $edit['roles'] = [$rid];
63     }
64
65     if ($admin) {
66       $edit['roles'][] = $this->createAdminRole();
67     }
68
69     $account = User::create($edit);
70     $account->save();
71
72     $this->assertTrue($account->id(), SafeMarkup::format('User created with name %name and pass %pass', ['%name' => $edit['name'], '%pass' => $edit['pass']]), 'User login');
73     if (!$account->id()) {
74       return FALSE;
75     }
76
77     // Add the raw password so that we can log in as this user.
78     $account->pass_raw = $edit['pass'];
79     // Support BrowserTestBase as well.
80     $account->passRaw = $account->pass_raw;
81     return $account;
82   }
83
84   /**
85    * Creates an administrative role.
86    *
87    * @param string $rid
88    *   (optional) The role ID (machine name). Defaults to a random name.
89    * @param string $name
90    *   (optional) The label for the role. Defaults to a random string.
91    * @param int $weight
92    *   (optional) The weight for the role. Defaults NULL so that entity_create()
93    *   sets the weight to maximum + 1.
94    *
95    * @return string
96    *   Role ID of newly created role, or FALSE if role creation failed.
97    */
98   protected function createAdminRole($rid = NULL, $name = NULL, $weight = NULL) {
99     $rid = $this->createRole([], $rid, $name, $weight);
100     if ($rid) {
101       /** @var \Drupal\user\RoleInterface $role */
102       $role = Role::load($rid);
103       $role->setIsAdmin(TRUE);
104       $role->save();
105     }
106     return $rid;
107   }
108
109   /**
110    * Creates a role with specified permissions.
111    *
112    * @param array $permissions
113    *   Array of permission names to assign to role.
114    * @param string $rid
115    *   (optional) The role ID (machine name). Defaults to a random name.
116    * @param string $name
117    *   (optional) The label for the role. Defaults to a random string.
118    * @param int $weight
119    *   (optional) The weight for the role. Defaults NULL so that entity_create()
120    *   sets the weight to maximum + 1.
121    *
122    * @return string
123    *   Role ID of newly created role, or FALSE if role creation failed.
124    */
125   protected function createRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) {
126     // Generate a random, lowercase machine name if none was passed.
127     if (!isset($rid)) {
128       $rid = strtolower($this->randomMachineName(8));
129     }
130     // Generate a random label.
131     if (!isset($name)) {
132       // In the role UI role names are trimmed and random string can start or
133       // end with a space.
134       $name = trim($this->randomString(8));
135     }
136
137     // Check the all the permissions strings are valid.
138     if (!$this->checkPermissions($permissions)) {
139       return FALSE;
140     }
141
142     // Create new role.
143     $role = Role::create([
144       'id' => $rid,
145       'label' => $name,
146     ]);
147     if (isset($weight)) {
148       $role->set('weight', $weight);
149     }
150     $result = $role->save();
151
152     $this->assertIdentical($result, SAVED_NEW, SafeMarkup::format('Created role ID @rid with name @name.', [
153       '@name' => var_export($role->label(), TRUE),
154       '@rid' => var_export($role->id(), TRUE),
155     ]), 'Role');
156
157     if ($result === SAVED_NEW) {
158       // Grant the specified permissions to the role, if any.
159       if (!empty($permissions)) {
160         $this->grantPermissions($role, $permissions);
161         $assigned_permissions = Role::load($role->id())->getPermissions();
162         $missing_permissions = array_diff($permissions, $assigned_permissions);
163         if (!$missing_permissions) {
164           $this->pass(SafeMarkup::format('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role');
165         }
166         else {
167           $this->fail(SafeMarkup::format('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role');
168         }
169       }
170       return $role->id();
171     }
172     else {
173       return FALSE;
174     }
175   }
176
177   /**
178    * Checks whether a given list of permission names is valid.
179    *
180    * @param array $permissions
181    *   The permission names to check.
182    *
183    * @return bool
184    *   TRUE if the permissions are valid, FALSE otherwise.
185    */
186   protected function checkPermissions(array $permissions) {
187     $available = array_keys(\Drupal::service('user.permissions')->getPermissions());
188     $valid = TRUE;
189     foreach ($permissions as $permission) {
190       if (!in_array($permission, $available)) {
191         $this->fail(SafeMarkup::format('Invalid permission %permission.', ['%permission' => $permission]), 'Role');
192         $valid = FALSE;
193       }
194     }
195     return $valid;
196   }
197
198   /**
199    * Grant permissions to a user role.
200    *
201    * @param \Drupal\user\RoleInterface $role
202    *   The ID of a user role to alter.
203    * @param array $permissions
204    *   (optional) A list of permission names to grant.
205    */
206   protected function grantPermissions(RoleInterface $role, array $permissions) {
207     foreach ($permissions as $permission) {
208       $role->grantPermission($permission);
209     }
210     $role->trustData()->save();
211   }
212
213 }