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