PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.3.5
Pods – Custom Content Types and Fields v3.3.5
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
570 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 if ( ! in_array( $capability, $new_capabilities, true ) && false === strpos( $capability, 'level_' ) ) {
386 $role->remove_cap( $capability );
387 }
388 }
389
390 return true;
391 }
392
393 /**
394 * Basic logic from Members plugin, it counts users of a specific role
395 *
396 * @param $role
397 *
398 * @return array
399 */
400 public function count_users( $role ) {
401
402 $count_users = count_users();
403
404 $avail_roles = [];
405
406 foreach ( $count_users['avail_roles'] as $count_role => $count ) {
407 $avail_roles[ $count_role ] = $count;
408 }
409
410 if ( empty( $role ) ) {
411 return $avail_roles;
412 }
413
414 if ( ! isset( $avail_roles[ $role ] ) ) {
415 $avail_roles[ $role ] = 0;
416 }
417
418 return $avail_roles[ $role ];
419 }
420
421 /**
422 * @return array|mixed|void
423 */
424 public function get_capabilities() {
425
426 global $wp_roles;
427
428 $default_caps = $this->get_wp_capabilities();
429
430 $role_caps = [];
431
432 foreach ( $wp_roles->role_objects as $key => $role ) {
433 if ( is_array( $role->capabilities ) ) {
434 foreach ( $role->capabilities as $cap => $grant ) {
435 $role_caps[ $cap ] = $cap;
436 }
437 }
438 }
439
440 $role_caps = array_unique( $role_caps );
441
442 $plugin_caps = [
443 'pods_roles_add',
444 'pods_roles_delete',
445 'pods_roles_edit',
446 ];
447
448 $capabilities = array_merge( $default_caps, $role_caps, $plugin_caps );
449
450 // Gravity Forms.
451 if ( class_exists( 'GFCommon' ) && is_callable( 'GFCommon::all_caps' ) ) {
452 $capabilities = array_merge( $capabilities, GFCommon::all_caps() );
453 }
454
455 // To support Members filters.
456 $capabilities = apply_filters( 'members_get_capabilities', $capabilities ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
457
458 $capabilities = apply_filters( 'pods_roles_get_capabilities', $capabilities );
459
460 sort( $capabilities );
461
462 $capabilities = array_unique( $capabilities );
463
464 return $capabilities;
465 }
466
467 /**
468 * @return array
469 */
470 public function get_wp_capabilities() {
471
472 $defaults = [
473 'activate_plugins',
474 'add_users',
475 'create_users',
476 'delete_others_pages',
477 'delete_others_posts',
478 'delete_pages',
479 'delete_plugins',
480 'delete_posts',
481 'delete_private_pages',
482 'delete_private_posts',
483 'delete_published_pages',
484 'delete_published_posts',
485 'delete_users',
486 'edit_dashboard',
487 'edit_files',
488 'edit_others_pages',
489 'edit_others_posts',
490 'edit_pages',
491 'edit_plugins',
492 'edit_posts',
493 'edit_private_pages',
494 'edit_private_posts',
495 'edit_published_pages',
496 'edit_published_posts',
497 'edit_theme_options',
498 'edit_themes',
499 'edit_users',
500 'import',
501 'install_plugins',
502 'install_themes',
503 'list_users',
504 'manage_categories',
505 'manage_links',
506 'manage_options',
507 'moderate_comments',
508 'promote_users',
509 'publish_pages',
510 'publish_posts',
511 'read',
512 'read_private_pages',
513 'read_private_posts',
514 'remove_users',
515 'switch_themes',
516 'unfiltered_html',
517 'unfiltered_upload',
518 'update_core',
519 'update_plugins',
520 'update_themes',
521 'upload_files',
522 ];
523
524 return $defaults;
525 }
526
527 /**
528 * @return array|mixed|void
529 */
530 public function get_default_capabilities() {
531
532 $capabilities = [
533 'read',
534 ];
535
536 // To support Members filters
537 $capabilities = apply_filters( 'members_new_role_default_capabilities', $capabilities ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
538
539 $capabilities = apply_filters( 'pods_roles_default_capabilities', $capabilities );
540
541 return $capabilities;
542 }
543
544 /**
545 * @param $capabilities
546 *
547 * @return array
548 */
549 public function remove_deprecated_capabilities( $capabilities ) {
550
551 $deprecated_capabilities = [
552 'level_0',
553 'level_1',
554 'level_2',
555 'level_3',
556 'level_4',
557 'level_5',
558 'level_6',
559 'level_7',
560 'level_8',
561 'level_9',
562 'level_10',
563 ];
564
565 $capabilities = array_diff( $capabilities, $deprecated_capabilities );
566
567 return $capabilities;
568 }
569 }
570