PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / trunk
Pods – Custom Content Types and Fields vtrunk
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / components / Roles / Roles.php
pods / components / Roles Last commit date
ui 4 months ago Roles.php 4 months ago
Roles.php
572 lines
1 <?php
2
3 // Don't load directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 die( '-1' );
6 }
7
8 /**
9 * Name: Roles and Capabilities
10 *
11 * Menu Name: Roles &amp; Capabilities
12 *
13 * Description: Create and Manage WordPress User Roles and Capabilities; Uses the '<a href="http://wordpress.org/plugins/members/" target="_blank" rel="noopener noreferrer">Members</a>' plugin filters for additional plugin integrations; Portions of code based on the '<a href="http://wordpress.org/plugins/members/" target="_blank" rel="noopener noreferrer">Members</a>' plugin by Justin Tadlock
14 *
15 * Version: 1.0
16 *
17 * Category: Tools
18 *
19 * @package Pods\Components
20 * @subpackage Roles
21 */
22
23 if ( class_exists( 'Pods_Roles' ) ) {
24 return;
25 }
26
27 /**
28 * Class Pods_Roles
29 */
30 class Pods_Roles extends PodsComponent {
31
32 /**
33 * {@inheritdoc}
34 */
35 public function init() {
36
37 add_filter( 'pods_roles_get_capabilities', [ $this, 'remove_deprecated_capabilities' ] );
38 }
39
40 /**
41 * Enqueue styles
42 *
43 * @since 2.0.0
44 */
45 public function admin_assets() {
46
47 wp_enqueue_style( 'pods-wizard' );
48 }
49
50 /**
51 * Build admin area
52 *
53 * @param $options
54 * @param $component
55 *
56 * @return void
57 * @since 2.0.0
58 */
59 public function admin( $options, $component ) {
60
61 global $wp_roles;
62
63 $default_role = get_option( 'default_role' );
64
65 $roles = [];
66
67 foreach ( $wp_roles->role_objects as $key => $role ) {
68 $count = $this->count_users( $key );
69
70 $roles[ $key ] = [
71 'id' => $key,
72 'label' => $wp_roles->role_names[ $key ],
73 'name' => $key,
74 'capabilities' => count( (array) $role->capabilities ),
75 // translators: %s is the number of users.
76 'users' => sprintf( _n( '%s User', '%s Users', $count, 'pods' ), $count ),
77 ];
78
79 if ( $default_role == $key ) {
80 $roles[ $key ]['label'] .= ' (site default)';
81 }
82
83 if ( 0 < $count && pods_is_admin( [ 'list_users' ] ) ) {
84 $roles[ $key ]['users'] .= '<br /><a href="' . admin_url( esc_url( 'users.php?role=' . $key ) ) . '">' . __( 'View Users', 'pods' ) . '</a>';
85 }
86 }
87
88 $ui = [
89 'component' => $component,
90 'data' => $roles,
91 'total' => count( $roles ),
92 'total_found' => count( $roles ),
93 'items' => __( 'Roles', 'pods' ),
94 'item' => __( 'Role', 'pods' ),
95 'fields' => [
96 'manage' => [
97 'label' => [ 'label' => __( 'Label', 'pods' ) ],
98 'name' => [ 'label' => __( 'Name', 'pods' ) ],
99 'capabilities' => [ 'label' => __( 'Capabilities', 'pods' ) ],
100 'users' => [
101 'label' => __( 'Users', 'pods' ),
102 'type' => 'text',
103 'options' => [
104 'text_allow_html' => 1,
105 'text_allowed_html_tags' => 'strong em a ul ol li b i br',
106 ],
107 ],
108 ],
109 ],
110 'actions_disabled' => [ 'duplicate', 'view', 'export' ],
111 'actions_custom' => [
112 'add' => [ $this, 'admin_add' ],
113 'edit' => [ $this, 'admin_edit' ],
114 'delete' => [ $this, 'admin_delete' ],
115 ],
116 'search' => false,
117 'searchable' => false,
118 'sortable' => false,
119 'pagination' => false,
120 ];
121
122 if ( isset( $roles[ pods_v( 'id', 'get', - 1 ) ] ) ) {
123 $ui['row'] = $roles[ pods_v( 'id', 'get', - 1 ) ];
124 }
125
126 if ( ! pods_is_admin( [ 'pods_roles_add' ] ) ) {
127 $ui['actions_disabled'][] = 'add';
128 }
129
130 if ( ! pods_is_admin( [ 'pods_roles_edit' ] ) ) {
131 $ui['actions_disabled'][] = 'edit';
132 }
133
134 if ( count( $roles ) < 2 || ! pods_is_admin( [ 'pods_roles_delete' ] ) ) {
135 $ui['actions_disabled'][] = 'delete';
136 }
137
138 pods_ui( $ui );
139 }
140
141 /**
142 * @param $obj
143 */
144 public function admin_add( $obj ) {
145
146 global $wp_roles;
147
148 $capabilities = $this->get_capabilities();
149
150 $defaults = $this->get_default_capabilities();
151
152 $component = $obj->x['component'];
153
154 $method = 'add';
155 // ajax_add
156 pods_view( PODS_DIR . 'components/Roles/ui/add.php', compact( array_keys( get_defined_vars() ) ) );
157 }
158
159 /**
160 * @param $duplicate
161 * @param $obj
162 *
163 * @return mixed
164 */
165 public function admin_edit( $duplicate, $obj ) {
166
167 global $wp_roles;
168
169 $id = $obj->id;
170
171 $capabilities = $this->get_capabilities();
172
173 $role_name = null;
174 $role_label = null;
175 $role_capabilities = null;
176
177 foreach ( $wp_roles->role_objects as $key => $role ) {
178 if ( $key != $id ) {
179 continue;
180 }
181
182 $role_name = $key;
183 $role_label = $wp_roles->role_names[ $key ];
184 $role_capabilities = $role->capabilities;
185 }
186
187 if ( empty( $role ) ) {
188 return $obj->error( __( 'Role not found, cannot edit it.', 'pods' ) );
189 }
190
191 $component = $obj->x['component'];
192
193 $method = 'edit';
194 // ajax_edit
195 pods_view( PODS_DIR . 'components/Roles/ui/edit.php', compact( array_keys( get_defined_vars() ) ) );
196 }
197
198 /**
199 * @param $id
200 * @param $obj
201 *
202 * @return mixed
203 */
204 public function admin_delete( $id, $obj ) {
205
206 global $wp_roles;
207
208 $id = $obj->id;
209
210 if ( ! isset( $obj->data[ $id ] ) ) {
211 return $obj->error( __( 'Role not found, it cannot be deleted.', 'pods' ) );
212 }
213
214 $default_role = get_option( 'default_role' );
215
216 if ( $id == $default_role ) {
217 // translators: %s is the role name.
218 return $obj->error( sprintf( __( 'You cannot remove the <strong>%s</strong> role, you must set a new default role for the site first.', 'pods' ), $obj->data[ $id ]['name'] ) );
219 }
220
221 $wp_user_query = new WP_User_Query( [ 'role' => $id ] );
222
223 $users = $wp_user_query->get_results();
224
225 if ( ! empty( $users ) && is_array( $users ) ) {
226 foreach ( $users as $user ) {
227 $user_object = new WP_User( $user );
228
229 if ( $user_object->has_cap( $id ) ) {
230 $user_object->remove_role( $id );
231 $user_object->set_role( $default_role );
232 }
233 }
234 }
235
236 remove_role( $id );
237
238 $roles = [];
239
240 foreach ( $wp_roles->role_objects as $key => $role ) {
241 $count = $this->count_users( $key );
242
243 $roles[ $key ] = [
244 'id' => $key,
245 'label' => wp_strip_all_tags( $wp_roles->role_names[ $key ] ),
246 'name' => $key,
247 'capabilities' => count( (array) $role->capabilities ),
248 // translators: %s is the number of users.
249 'users' => sprintf( _n( '%s User', '%s Users', $count, 'pods' ), $count ),
250 ];
251
252 if ( $default_role == $key ) {
253 $roles[ $key ]['label'] .= ' (site default)';
254 }
255
256 if ( 0 < $count && pods_is_admin( [ 'list_users' ] ) ) {
257 $roles[ $key ]['users'] .= '<br /><a href="' . admin_url( esc_url( 'users.php?role=' . $key ) ) . '">' . __( 'View Users', 'pods' ) . '</a>';
258 }
259 }
260
261 $name = $obj->data[ $id ]['label'] . ' (' . $obj->data[ $id ]['name'] . ')';
262
263 $obj->data = $roles;
264 $obj->total = count( $roles );
265 $obj->total_found = count( $roles );
266
267 $obj->message( '<strong>' . $name . '</strong> ' . __( 'role removed from site.', 'pods' ) );
268 }
269
270 /**
271 * Handle the Add Role AJAX
272 *
273 * @param $params
274 *
275 * @return mixed|void
276 */
277 public function ajax_add( $params ) {
278
279 global $wp_roles;
280
281 $role_name = sanitize_title( sanitize_text_field( pods_v( 'role_name', $params ) ) );
282 $role_label = sanitize_text_field( pods_v( 'role_label', $params ) );
283
284 $params->capabilities = (array) pods_v( 'capabilities', $params, [] );
285
286 $params->custom_capabilities = (array) pods_v( 'custom_capabilities', $params, [] );
287 $params->custom_capabilities = array_filter( array_unique( array_map( 'sanitize_text_field', $params->custom_capabilities ) ) );
288
289 $capabilities = [];
290
291 foreach ( $params->capabilities as $capability => $x ) {
292 if ( empty( $capability ) || true !== (boolean) $x ) {
293 continue;
294 }
295
296 $capabilities[ esc_attr( $capability ) ] = true;
297 }
298
299 foreach ( $params->custom_capabilities as $x => $capability ) {
300 if ( empty( $capability ) || '--1' === $x ) {
301 continue;
302 }
303
304 $capabilities[ esc_attr( $capability ) ] = true;
305 }
306
307 if ( empty( $role_name ) ) {
308 return pods_error( __( 'Role name is required', 'pods' ) );
309 }
310
311 if ( empty( $role_label ) ) {
312 return pods_error( __( 'Role label is required', 'pods' ) );
313 }
314
315 if ( wp_roles()->is_role( $role_name ) ) {
316 return pods_error( __( 'This role already exists', 'pods' ) );
317 }
318
319 return add_role( $role_name, $role_label, $capabilities ) instanceof WP_Role;
320 }
321
322 /**
323 * Handle the Edit Role AJAX
324 *
325 * @todo allow rename role_label
326 *
327 * @param $params
328 *
329 * @return bool|mixed|void
330 */
331 public function ajax_edit( $params ) {
332
333 global $wp_roles;
334
335 $capabilities = $this->get_capabilities();
336
337 $params->capabilities = (array) pods_v( 'capabilities', $params, [] );
338
339 $params->custom_capabilities = (array) pods_v( 'custom_capabilities', $params, [] );
340 $params->custom_capabilities = array_filter( array_unique( $params->custom_capabilities ) );
341
342 if ( ! isset( $params->id ) || empty( $params->id ) || ! isset( $wp_roles->role_objects[ $params->id ] ) ) {
343 return pods_error( __( 'Role not found, cannot edit it.', 'pods' ) );
344 }
345
346 /**
347 * @var $role WP_Role
348 */
349 $role = $wp_roles->role_objects[ $params->id ];
350 $role_name = $params->id;
351 $role_label = $wp_roles->role_names[ $params->id ];
352 $role_capabilities = $role->capabilities;
353
354 $new_capabilities = [];
355
356 foreach ( $params->capabilities as $capability => $x ) {
357 if ( empty( $capability ) || true !== (boolean) $x ) {
358 continue;
359 }
360
361 $new_capabilities[] = esc_attr( $capability );
362
363 if ( ! $role->has_cap( $capability ) ) {
364 $role->add_cap( $capability );
365 }
366 }
367
368 foreach ( $params->custom_capabilities as $x => $capability ) {
369 if ( empty( $capability ) ) {
370 continue;
371 }
372
373 if ( in_array( $capability, $new_capabilities, true ) ) {
374 continue;
375 }
376
377 $new_capabilities[] = esc_attr( $capability );
378
379 if ( ! $role->has_cap( $capability ) ) {
380 $role->add_cap( $capability );
381 }
382 }
383
384 foreach ( $role_capabilities as $capability => $x ) {
385 $capability = (string) $capability;
386
387 if ( ! in_array( $capability, $new_capabilities, true ) && false === strpos( $capability, 'level_' ) ) {
388 $role->remove_cap( $capability );
389 }
390 }
391
392 return true;
393 }
394
395 /**
396 * Basic logic from Members plugin, it counts users of a specific role
397 *
398 * @param $role
399 *
400 * @return array
401 */
402 public function count_users( $role ) {
403
404 $count_users = count_users();
405
406 $avail_roles = [];
407
408 foreach ( $count_users['avail_roles'] as $count_role => $count ) {
409 $avail_roles[ $count_role ] = $count;
410 }
411
412 if ( empty( $role ) ) {
413 return $avail_roles;
414 }
415
416 if ( ! isset( $avail_roles[ $role ] ) ) {
417 $avail_roles[ $role ] = 0;
418 }
419
420 return $avail_roles[ $role ];
421 }
422
423 /**
424 * @return array|mixed|void
425 */
426 public function get_capabilities() {
427
428 global $wp_roles;
429
430 $default_caps = $this->get_wp_capabilities();
431
432 $role_caps = [];
433
434 foreach ( $wp_roles->role_objects as $key => $role ) {
435 if ( is_array( $role->capabilities ) ) {
436 foreach ( $role->capabilities as $cap => $grant ) {
437 $role_caps[ $cap ] = $cap;
438 }
439 }
440 }
441
442 $role_caps = array_unique( $role_caps );
443
444 $plugin_caps = [
445 'pods_roles_add',
446 'pods_roles_delete',
447 'pods_roles_edit',
448 ];
449
450 $capabilities = array_merge( $default_caps, $role_caps, $plugin_caps );
451
452 // Gravity Forms.
453 if ( class_exists( 'GFCommon' ) && is_callable( 'GFCommon::all_caps' ) ) {
454 $capabilities = array_merge( $capabilities, GFCommon::all_caps() );
455 }
456
457 // To support Members filters.
458 $capabilities = apply_filters( 'members_get_capabilities', $capabilities ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
459
460 $capabilities = apply_filters( 'pods_roles_get_capabilities', $capabilities );
461
462 sort( $capabilities );
463
464 $capabilities = array_unique( $capabilities );
465
466 return $capabilities;
467 }
468
469 /**
470 * @return array
471 */
472 public function get_wp_capabilities() {
473
474 $defaults = [
475 'activate_plugins',
476 'add_users',
477 'create_users',
478 'delete_others_pages',
479 'delete_others_posts',
480 'delete_pages',
481 'delete_plugins',
482 'delete_posts',
483 'delete_private_pages',
484 'delete_private_posts',
485 'delete_published_pages',
486 'delete_published_posts',
487 'delete_users',
488 'edit_dashboard',
489 'edit_files',
490 'edit_others_pages',
491 'edit_others_posts',
492 'edit_pages',
493 'edit_plugins',
494 'edit_posts',
495 'edit_private_pages',
496 'edit_private_posts',
497 'edit_published_pages',
498 'edit_published_posts',
499 'edit_theme_options',
500 'edit_themes',
501 'edit_users',
502 'import',
503 'install_plugins',
504 'install_themes',
505 'list_users',
506 'manage_categories',
507 'manage_links',
508 'manage_options',
509 'moderate_comments',
510 'promote_users',
511 'publish_pages',
512 'publish_posts',
513 'read',
514 'read_private_pages',
515 'read_private_posts',
516 'remove_users',
517 'switch_themes',
518 'unfiltered_html',
519 'unfiltered_upload',
520 'update_core',
521 'update_plugins',
522 'update_themes',
523 'upload_files',
524 ];
525
526 return $defaults;
527 }
528
529 /**
530 * @return array|mixed|void
531 */
532 public function get_default_capabilities() {
533
534 $capabilities = [
535 'read',
536 ];
537
538 // To support Members filters
539 $capabilities = apply_filters( 'members_new_role_default_capabilities', $capabilities ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
540
541 $capabilities = apply_filters( 'pods_roles_default_capabilities', $capabilities );
542
543 return $capabilities;
544 }
545
546 /**
547 * @param $capabilities
548 *
549 * @return array
550 */
551 public function remove_deprecated_capabilities( $capabilities ) {
552
553 $deprecated_capabilities = [
554 'level_0',
555 'level_1',
556 'level_2',
557 'level_3',
558 'level_4',
559 'level_5',
560 'level_6',
561 'level_7',
562 'level_8',
563 'level_9',
564 'level_10',
565 ];
566
567 $capabilities = array_diff( $capabilities, $deprecated_capabilities );
568
569 return $capabilities;
570 }
571 }
572