Merge pull request #15338 from totten/master-poc-postcommit
[civicrm-core.git] / CRM / ACL / Form / WordPress / Permissions.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * This class provides the functionality to Grant access to CiviCRM components and other CiviCRM permissions.
20 */
21 class CRM_ACL_Form_WordPress_Permissions extends CRM_Core_Form {
22
23 /**
24 * Build the form object.
25 */
26 public function buildQuickForm() {
27
28 CRM_Utils_System::setTitle('WordPress Access Control');
29
30 // Get the core permissions array
31 $permissionsArray = self::getPermissionArray();
32 $permissionsDesc = self::getPermissionArray(TRUE);
33
34 // Get the WordPress roles, default capabilities and assign to the form
35 global $wp_roles;
36 if (!isset($wp_roles)) {
37 $wp_roles = new WP_Roles();
38 }
39 foreach ($wp_roles->role_names as $role => $name) {
40 // Unless it's Multisite, don't show the permissions options for administrator, as they have all permissions
41 if (is_multisite() or $role !== 'administrator') {
42 $roleObj = $wp_roles->get_role($role);
43 if (!empty($roleObj->capabilities)) {
44 foreach ($roleObj->capabilities as $ckey => $cname) {
45 if (array_key_exists($ckey, $permissionsArray)) {
46 $elementName = $role . '[' . $ckey . ']';
47 $defaults[$elementName] = 1;
48 }
49 }
50 }
51
52 // Compose the checkbox array for each role, to assign to form
53 $rolePerms[$role] = $permissionsArray;
54 foreach ($rolePerms[$role] as $key => $value) {
55 $elementName = $role . '[' . $key . ']';
56 $this->add('checkbox', $elementName, $value);
57 }
58 $roles[$role] = $name;
59 }
60 }
61
62 $this->setDefaults($defaults);
63
64 $descArray = [];
65 foreach ($permissionsDesc as $perm => $attr) {
66 if (count($attr) > 1) {
67 $descArray[$perm] = $attr[1];
68 }
69 }
70
71 // build table rows by merging role perms
72 $rows = [];
73 foreach ($rolePerms as $role => $perms) {
74 foreach ($perms as $name => $title) {
75 $rows[$name] = $title;
76 }
77 }
78
79 // Build array keyed by permission
80 $table = [];
81 foreach ($rows as $perm => $label) {
82
83 // Init row with permission label
84 $table[$perm] = [
85 'label' => $label,
86 'roles' => [],
87 ];
88
89 // Add permission description and role names
90 foreach ($roles as $key => $label) {
91 if (isset($descArray[$perm])) {
92 $table[$perm]['desc'] = $descArray[$perm];
93 }
94 $table[$perm]['roles'][] = $key;
95 }
96
97 }
98
99 $this->assign('table', $table);
100 $this->assign('rolePerms', $rolePerms);
101 $this->assign('roles', $roles);
102
103 $this->addButtons(
104 [
105 [
106 'type' => 'next',
107 'name' => ts('Save'),
108 'spacing' => '',
109 'isDefault' => FALSE,
110 ],
111 ]
112 );
113
114 }
115
116 /**
117 * Process the form submission.
118 */
119 public function postProcess() {
120 $params = $this->controller->exportValues($this->_name);
121
122 $permissionsArray = self::getPermissionArray();
123
124 // Function to get Wordpress roles
125 global $wp_roles;
126 if (!isset($wp_roles)) {
127 $wp_roles = new WP_Roles();
128 }
129 foreach ($wp_roles->role_names as $role => $name) {
130 $roleObj = $wp_roles->get_role($role);
131
132 //Remove all civicrm capabilities for the role, as there may be some capabilities checkbox unticked
133 foreach ($permissionsArray as $key => $capability) {
134 $roleObj->remove_cap($key);
135 }
136
137 //Add the selected wordpress capabilities for the role
138 $rolePermissions = $params[$role];
139 if (!empty($rolePermissions)) {
140 foreach ($rolePermissions as $key => $capability) {
141 $roleObj->add_cap($key);
142 }
143 }
144
145 if ($role == 'anonymous_user') {
146 // Get the permissions into a format that matches what we get from WP
147 $allWarningPermissions = CRM_Core_Permission::getAnonymousPermissionsWarnings();
148 foreach ($allWarningPermissions as $key => $permission) {
149 $allWarningPermissions[$key] = CRM_Utils_String::munge(strtolower($permission));
150 }
151 $warningPermissions = array_intersect($allWarningPermissions, array_keys($rolePermissions));
152 $warningPermissionNames = [];
153 foreach ($warningPermissions as $permission) {
154 $warningPermissionNames[$permission] = $permissionsArray[$permission];
155 }
156 if (!empty($warningPermissionNames)) {
157 CRM_Core_Session::setStatus(
158 ts('The %1 role was assigned one or more permissions that may prove dangerous for users of that role to have. Please reconsider assigning %2 to them.', [
159 1 => $wp_roles->role_names[$role],
160 2 => implode(', ', $warningPermissionNames),
161 ]),
162 ts('Unsafe Permission Settings')
163 );
164 }
165 }
166 }
167
168 // FIXME
169 // Changed the 'access_civicrm_nav_link' capability in civicrm.php file
170 // But for some reason, if i remove 'Access CiviCRM' administrator and save, it is showing
171 // 'You do not have sufficient permissions to access this page'
172 // which should not happen for Super Admin and Administrators, as checking permissions for Super
173 // Admin and Administrators always gives TRUE
174 wp_civicrm_capability();
175
176 CRM_Core_Session::setStatus("", ts('Wordpress Access Control Updated'), "success");
177
178 // rebuild the menus to comply with the new permissions/capabilites
179 CRM_Core_Invoke::rebuildMenuAndCaches();
180
181 CRM_Utils_System::redirect('admin.php?page=CiviCRM&q=civicrm/admin/access&reset=1');
182 CRM_Utils_System::civiExit();
183 }
184
185 /**
186 * Get the core civicrm permissions array.
187 * This function should be shared from a similar one in
188 * distmaker/utils/joomlaxml.php
189 *
190 * @param bool $descriptions
191 * Whether to return permission descriptions
192 *
193 * @return array
194 * civicrm permissions
195 */
196 public static function getPermissionArray($descriptions = FALSE) {
197
198 $permissions = CRM_Core_Permission::basicPermissions(FALSE, $descriptions);
199
200 $perms_array = [];
201 foreach ($permissions as $perm => $title) {
202 //order matters here, but we deal with that later
203 $perms_array[CRM_Utils_String::munge(strtolower($perm))] = $title;
204 }
205
206 return $perms_array;
207 }
208
209 }