PluginProbe
Groups – Memberships and Access Control / 4.7.1
Groups – Memberships and Access Control v4.7.1
4.7.1 4.7.0 4.6.0 4.5.0 4.4.0 4.3.0 trunk 1.0.0-beta-1 1.0.0-beta-2 1.0.0-beta-3 1.0.0-beta-3b 1.0.0-beta-3c 1.0.0-beta-3d 1.1.4 1.1.5 1.10.0 1.10.1 1.10.2 1.10.3 1.11.0 1.11.1 1.11.2 1.11.3 1.12.0 1.13.0 All 131 releases
groups / lib / admin / groups-admin-capabilities.php

groups-admin-capabilities.php in Groups – Memberships and Access Control 4.7.1, at lib/admin/groups-admin-capabilities.php

513 lines 17.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * groups-admin-capabilities.php
4 *
5 * Copyright (c) "kento" Karim Rahimpur www.itthinx.com
6 *
7 * This code is released under the GNU General Public License.
8 * See COPYRIGHT.txt and LICENSE.txt.
9 *
10 * This code is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This header and all notices must be kept intact.
16 *
17 * @author Karim Rahimpur
18 * @package groups
19 * @since groups 1.0.0
20 */
21
22 if ( !defined( 'ABSPATH' ) ) {
23 exit;
24 }
25
26 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
27
28 define( 'GROUPS_CAPABILITIES_PER_PAGE', 10 );
29 define( 'GROUPS_ADMIN_CAPABILITIES_NONCE', 'groups-admin-caps-nonce');
30 define( 'GROUPS_ADMIN_CAPABILITIES_ACTION_NONCE', 'groups-cap-action-nonce');
31 define( 'GROUPS_ADMIN_CAPABILITIES_FILTER_NONCE', 'groups-cap-filter-nonce' );
32
33 require_once GROUPS_CORE_LIB . '/class-groups-pagination.php';
34 require_once GROUPS_ADMIN_LIB . '/groups-admin-capabilities-add.php';
35 require_once GROUPS_ADMIN_LIB . '/groups-admin-capabilities-edit.php';
36 require_once GROUPS_ADMIN_LIB . '/groups-admin-capabilities-remove.php';
37
38 /**
39 * Manage capabilities: table of capabilities and add, edit, remove actions.
40 */
41 function groups_admin_capabilities() {
42
43 global $wpdb;
44
45 $output = '';
46 $today = date( 'Y-m-d', time() ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
47
48 if ( !Groups_User::current_user_can( GROUPS_ADMINISTER_GROUPS ) ) {
49 wp_die( esc_html__( 'Access denied.', 'groups' ) );
50 }
51
52 //
53 // handle actions
54 //
55 if ( isset( $_POST['action'] ) ) {
56 // handle action submit - do it
57 switch ( groups_sanitize_post( 'action' ) ) {
58 case 'add' :
59 if ( !( $capability_id = groups_admin_capabilities_add_submit() ) ) {
60 return groups_admin_capabilities_add();
61 } else {
62 $capability = Groups_Capability::read( $capability_id );
63 Groups_Admin::add_message( sprintf(
64 /* translators: capability name */
65 __( 'The <em>%s</em> capability has been created.', 'groups' ),
66 $capability->capability ? stripslashes( wp_filter_nohtml_kses( $capability->capability ) ) : ''
67 ) );
68 }
69 break;
70 case 'edit' :
71 if ( !( $capability_id = groups_admin_capabilities_edit_submit() ) ) {
72 return groups_admin_capabilities_edit( groups_sanitize_post( 'capability-id-field' ) );
73 } else {
74 $capability = Groups_Capability::read( $capability_id );
75 Groups_Admin::add_message( sprintf(
76 /* translators: capability name */
77 __( 'The <em>%s</em> capability has been updated.', 'groups' ),
78 $capability->capability ? stripslashes( wp_filter_nohtml_kses( $capability->capability ) ) : ''
79 ) );
80 }
81 break;
82 case 'remove' :
83 if ( $capability_id = groups_admin_capabilities_remove_submit() ) {
84 Groups_Admin::add_message( __( 'The capability has been deleted.', 'groups' ) );
85 }
86 break;
87 // bulk actions on groups: capabilities
88 case 'groups-action' :
89 if ( groups_verify_post_nonce( GROUPS_ADMIN_GROUPS_ACTION_NONCE, 'admin' ) ) {
90 $capability_ids = groups_sanitize_post( 'capability_ids' );
91 $bulk = groups_sanitize_post( 'bulk' );
92 if ( is_array( $capability_ids ) && ( $bulk !== null ) ) {
93 foreach ( $capability_ids as $capability_id ) {
94 $bulk_action = groups_sanitize_post( 'bulk-action' );
95 switch ( $bulk_action ) {
96 case 'remove' :
97 if ( isset( $_POST['confirm'] ) ) {
98 groups_admin_capabilities_bulk_remove_submit();
99 } else {
100 return groups_admin_capabilities_bulk_remove();
101 }
102 break;
103 }
104 break;
105 }
106 }
107 }
108 break;
109 }
110 } else if ( isset ( $_GET['action'] ) ) {
111 // handle action request - show form
112 switch ( groups_sanitize_get( 'action' ) ) {
113 case 'add' :
114 return groups_admin_capabilities_add();
115 break;
116 case 'edit' :
117 if ( isset( $_GET['capability_id'] ) ) {
118 return groups_admin_capabilities_edit( groups_sanitize_get( 'capability_id' ) );
119 }
120 break;
121 case 'remove' :
122 if ( isset( $_GET['capability_id'] ) ) {
123 return groups_admin_capabilities_remove( groups_sanitize_get( 'capability_id' ) );
124 }
125 break;
126 case 'refresh' :
127 if ( check_admin_referer( 'refresh' ) ) {
128 $n = Groups_WordPress::refresh_capabilities();
129 if ( $n > 0 ) {
130 /* translators: count */
131 $output .= '<div class="updated fade"><p>' . esc_html( sprintf( _n( 'One capability has been added.', '%d capabilities have been added.', $n, 'groups' ), $n ) ) . '</p></div>'; // phpcs:ignore WordPress.WP.I18n.MissingSingularPlaceholder
132 } else {
133 $output .= '<div class="updated fade"><p>' . esc_html__( 'No new capabilities have been found.', 'groups' ) . '</p></div>';
134 }
135 } else {
136 wp_die( esc_html__( 'A Duck!', 'groups' ) );
137 }
138 break;
139 }
140 }
141
142 //
143 // capabilities table
144 //
145 if (
146 isset( $_POST['clear_filters'] ) ||
147 isset( $_POST['capability_id'] ) ||
148 isset( $_POST['capability'] )
149 ) {
150 if ( !groups_verify_post_nonce( GROUPS_ADMIN_CAPABILITIES_FILTER_NONCE, 'admin' ) ) {
151 wp_die( esc_html__( 'Access denied.', 'groups' ) );
152 }
153 }
154
155 // filters
156 $capability_id = Groups_Options::get_user_option( 'capabilities_capability_id', null );
157 $capability = Groups_Options::get_user_option( 'capabilities_capability', null );
158
159 if ( isset( $_POST['clear_filters'] ) ) {
160 Groups_Options::delete_user_option( 'capabilities_capability_id' );
161 Groups_Options::delete_user_option( 'capabilities_capability' );
162 $capability_id = null;
163 $capability = null;
164 } else if ( isset( $_POST['submitted'] ) ) {
165 // filter by name
166 if ( !empty( $_POST['capability'] ) ) {
167 $capability = groups_sanitize_post( 'capability' );
168 Groups_Options::update_user_option( 'capabilities_capability', $capability );
169 }
170 // filter by capability id
171 if ( !empty( $_POST['capability_id'] ) ) {
172 $capability_id = intval( groups_sanitize_post( 'capability_id' ) );
173 Groups_Options::update_user_option( 'capabilities_capability_id', $capability_id );
174 } else if ( isset( $_POST['capability_id'] ) ) { // empty && isset => '' => all
175 $capability_id = null;
176 Groups_Options::delete_user_option( 'capabilities_capability_id' );
177 }
178 }
179
180 if ( isset( $_POST['row_count'] ) ) {
181 if ( !groups_verify_post_nonce( GROUPS_ADMIN_CAPABILITIES_NONCE, 'admin' ) ) {
182 wp_die( esc_html__( 'Access denied.', 'groups' ) );
183 }
184 }
185
186 if ( isset( $_POST['paged'] ) ) {
187 if ( !groups_verify_post_nonce( GROUPS_ADMIN_CAPABILITIES_NONCE, 'admin' ) ) {
188 wp_die( esc_html__( 'Access denied.', 'groups' ) );
189 }
190 }
191
192 $current_url = groups_get_current_url();
193 $current_url = remove_query_arg( 'paged', $current_url );
194 $current_url = remove_query_arg( 'action', $current_url );
195 $current_url = remove_query_arg( 'capability_id', $current_url );
196
197 $capability_table = _groups_get_tablename( 'capability' );
198
199 $output .=
200 '<div class="manage-capabilities wrap">' .
201 '<h1>' .
202 esc_html__( 'Capabilities', 'groups' ) .
203 // add capability
204 sprintf(
205 '<a title="%s" class="add page-title-action" href="%s">',
206 esc_attr__( 'Click to add a new capability', 'groups' ),
207 esc_url( $current_url . '&action=add' )
208 ) .
209 sprintf(
210 '<img class="icon" alt="%s" src="%s" />',
211 esc_attr__( 'Add', 'groups' ),
212 esc_url( GROUPS_PLUGIN_URL . 'images/add.png' )
213 ) .
214 sprintf(
215 '<span class="label">%s</span>',
216 esc_html__( 'New Capability', 'groups' )
217 ) .
218 '</a>' .
219 // refresh capabilities
220 sprintf(
221 '<a title="%s" class="refresh page-title-action" href="%s">',
222 esc_attr__( 'Click to refresh capabilities', 'groups' ),
223 esc_url( wp_nonce_url( $current_url . '&action=refresh', 'refresh' ) )
224 ) .
225 sprintf(
226 '<img class="icon" alt="%s" src="%s" />',
227 esc_attr__( 'Refresh', 'groups' ),
228 esc_url( GROUPS_PLUGIN_URL . 'images/refresh.png' )
229 ) .
230 sprintf(
231 '<span class="label">%s</span>',
232 esc_html__( 'Refresh', 'groups' )
233 ) .
234 '</a>' .
235 '</h1>';
236
237 $output .= Groups_Admin::render_messages();
238
239 $row_count = intval( groups_sanitize_post( 'row_count' ) ?? 0 );
240
241 if ($row_count <= 0) {
242 $row_count = Groups_Options::get_user_option( 'capabilities_per_page', GROUPS_CAPABILITIES_PER_PAGE );
243 } else {
244 Groups_Options::update_user_option('capabilities_per_page', $row_count );
245 }
246 $offset = intval( groups_sanitize_get( 'offset' ) ?? 0 );
247 if ( $offset < 0 ) {
248 $offset = 0;
249 }
250 $paged = intval( groups_sanitize_request( 'paged' ) ?? 0 );
251 if ( $paged < 0 ) {
252 $paged = 0;
253 }
254
255 $orderby = groups_sanitize_get( 'orderby' );
256 switch ( $orderby ) {
257 case 'capability_id' :
258 case 'capability' :
259 case 'description' :
260 break;
261 default:
262 $orderby = 'name';
263 }
264
265 $order = groups_sanitize_get( 'order' );
266 switch ( $order ) {
267 case 'asc' :
268 case 'ASC' :
269 $switch_order = 'DESC';
270 break;
271 case 'desc' :
272 case 'DESC' :
273 $switch_order = 'ASC';
274 break;
275 default:
276 $order = 'ASC';
277 $switch_order = 'DESC';
278 }
279
280 $filters = array( " 1=%d " );
281 $filter_params = array( 1 );
282 if ( $capability_id ) {
283 $filters[] = " $capability_table.capability_id = %d ";
284 $filter_params[] = $capability_id;
285 }
286 if ( $capability ) {
287 $filters[] = " $capability_table.capability LIKE %s ";
288 $filter_params[] = '%' . $wpdb->esc_like( $capability ) . '%';
289 }
290
291 if ( !empty( $filters ) ) { // @phpstan-ignore empty.variable
292 $filters = " WHERE " . implode( " AND ", $filters );
293 } else {
294 $filters = '';
295 }
296
297 $count_query = $wpdb->prepare( "SELECT COUNT(*) FROM $capability_table $filters", $filter_params ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
298 $count = $wpdb->get_var( $count_query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
299 if ( $count > $row_count ) {
300 $paginate = true;
301 } else {
302 $paginate = false;
303 }
304 $pages = ceil ( $count / $row_count );
305 if ( $paged > $pages ) {
306 $paged = $pages;
307 }
308 if ( $paged != 0 ) {
309 $offset = ( $paged - 1 ) * $row_count;
310 }
311
312 $query = $wpdb->prepare(
313 // nosemgrep: audit.php.wp.security.sqli.input-in-sinks
314 "SELECT * FROM $capability_table $filters ORDER BY $orderby $order LIMIT $row_count OFFSET $offset", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
315 $filter_params
316 );
317
318 // nosemgrep: audit.php.wp.security.sqli.input-in-sinks
319 $results = $wpdb->get_results( $query, OBJECT ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
320
321 $column_display_names = array(
322 'capability_id' => __( 'ID', 'groups' ),
323 'capability' => __( 'Capability', 'groups' ),
324 'description' => __( 'Description', 'groups' )
325 );
326
327 $output .= '<div class="capabilities-overview">';
328
329 $output .=
330 '<div class="filters">' .
331 '<form id="setfilters" action="" method="post">' .
332 '<fieldset>' .
333 '<legend>' . esc_html__( 'Filters', 'groups' ) . '</legend>' .
334 '<label class="capability-id-filter">' .
335 esc_html__( 'Capability ID', 'groups' ) . ' ' .
336 '<input class="capability-id-filter" name="capability_id" type="text" value="' . esc_attr( $capability_id ) . '"/>' .
337 '</label>' . ' ' .
338 '<label class="capability-filter">' .
339 esc_html__( 'Capability', 'groups' ) . ' ' .
340 '<input class="capability-filter" name="capability" type="text" value="' . esc_attr( $capability ? stripslashes( $capability ) : '' ) . '"/>' .
341 '</label>' . ' ' .
342 wp_nonce_field( 'admin', GROUPS_ADMIN_CAPABILITIES_FILTER_NONCE, true, false ) .
343 '<input class="button" type="submit" value="' . esc_attr__( 'Apply', 'groups' ) . '"/>' . ' ' .
344 '<input class="button" type="submit" name="clear_filters" value="' . esc_attr__( 'Clear', 'groups' ) . '"/>' .
345 '<input type="hidden" value="submitted" name="submitted"/>' .
346 '</fieldset>' .
347 '</form>' .
348 '</div>';
349
350 $output .= '<form id="groups-action" method="post" action="">';
351
352 $output .= '<div class="tablenav top">';
353
354 $output .= '<div class="capabilities-bulk-container">';
355 $output .= '<div class="alignleft actions">';
356 $output .= '<select name="bulk-action">';
357 $output .= '<option selected="selected" value="-1">' . esc_html__( 'Bulk Actions', 'groups' ) . '</option>';
358 $output .= '<option value="remove">' . esc_html__( 'Remove', 'groups' ) . '</option>';
359 $output .= '</select>';
360 $output .= '<input class="button" type="submit" name="bulk" value="' . esc_attr__( 'Apply', 'groups' ) . '"/>';
361 $output .= '</div>'; // .alignleft.actions
362 $output .= '</div>'; // .capabilities-bulk-container
363
364 if ( $paginate ) {
365 require_once GROUPS_CORE_LIB . '/class-groups-pagination.php';
366 $pagination = new Groups_Pagination( $count, null, $row_count );
367 $output .= $pagination->pagination( 'top' );
368 }
369
370 $output .= '<div class="page-options right">';
371 $output .= '<label for="row_count">' . esc_html__( 'Results per page', 'groups' ) . '</label>';
372 $output .= '<input name="row_count" type="text" size="2" value="' . esc_attr( $row_count ) .'" />';
373 $output .= '<input class="button" type="submit" value="' . esc_attr__( 'Apply', 'groups' ) . '"/>';
374 $output .= '</div>'; // .page-options.right
375
376 $output .= '</div>'; // .tablenav.top
377
378 $output .= wp_nonce_field( 'admin', GROUPS_ADMIN_GROUPS_ACTION_NONCE, true, false );
379 $output .= wp_nonce_field( 'admin', GROUPS_ADMIN_CAPABILITIES_NONCE, true, false );
380 $output .= '<input type="hidden" name="action" value="groups-action"/>';
381
382 $output .= '<table id="" class="wp-list-table widefat fixed" cellspacing="0">';
383 $output .= '<thead>';
384 $output .= '<tr>';
385
386 $output .= '<th id="cb" class="manage-column column-cb check-column" scope="col"><input type="checkbox"></th>';
387
388 foreach ( $column_display_names as $key => $column_display_name ) {
389 $options = array(
390 'orderby' => $key,
391 'order' => $switch_order
392 );
393 $class = $key;
394 if ( !in_array($key, array( 'capabilities', 'edit', 'remove' ) ) ) {
395 if ( strcmp( $key, $orderby ) == 0 ) {
396 $lorder = strtolower( $order );
397 $class = "$key manage-column sorted $lorder";
398 } else {
399 $class = "$key manage-column sortable";
400 }
401 $column_display_name =
402 sprintf(
403 '<a href="%s"><span>%s</span>'.
404 '<span class="sorting-indicators">' .
405 '<span class="sorting-indicator asc" aria-hidden="true"></span>'.
406 '<span class="sorting-indicator desc" aria-hidden="true"></span>'.
407 '</span>' . // .sorting-indicators
408 '</a>',
409 esc_url( add_query_arg( $options, $current_url ) ),
410 esc_html( $column_display_name )
411 );
412 } else {
413 $column_display_name = esc_html( $column_display_name );
414 }
415 $output .= sprintf(
416 '<th scope="col" class="%s">%s</th>',
417 esc_attr( $class ),
418 $column_display_name
419 );
420 }
421
422 $output .= '</tr>';
423 $output .= '</thead>';
424 $output .= '<tbody>';
425
426 if ( count( $results ) > 0 ) {
427 for ( $i = 0; $i < count( $results ); $i++ ) {
428 $result = $results[$i];
429
430 // Construct the "edit" URL.
431 $edit_url = add_query_arg(
432 array(
433 'capability_id' => intval( $result->capability_id ),
434 'action' => 'edit',
435 'paged' => $paged
436 ),
437 $current_url
438 );
439 // Construct the "delete" URL.
440 $delete_url = add_query_arg(
441 array(
442 'capability_id' => intval( $result->capability_id ),
443 'action' => 'remove',
444 'paged' => $paged
445 ),
446 $current_url
447 );
448
449 // Construct row actions for this group.
450 $row_actions =
451 '<div class="row-actions">' .
452 '<span class="edit">' .
453 '<a href="' . esc_url( $edit_url ) . '">' .
454 '<img src="' . GROUPS_PLUGIN_URL . 'images/edit.png"/>' .
455 __( 'Edit', 'groups' ) .
456 '</a>';
457 if ( $result->capability !== Groups_Post_Access::READ_POST_CAPABILITY ) {
458 $row_actions .=
459 ' | '.
460 '</span>' .
461 '<span class="remove trash">' .
462 '<a href="' . esc_url( $delete_url ) . '" class="submitdelete">' .
463 '<img src="' . GROUPS_PLUGIN_URL . 'images/remove.png"/>' .
464 __( 'Remove', 'groups' ) .
465 '</a>' .
466 '</span>';
467 }
468 $row_actions .= '</div>'; // .row-actions
469
470 $output .= '<tr class="' . ( $i % 2 == 0 ? 'even' : 'odd' ) . '">';
471
472 $output .= '<th class="check-column">';
473 $output .= '<input type="checkbox" value="' . esc_attr( $result->capability_id ) . '" name="capability_ids[]"/>';
474 $output .= '</th>';
475
476 $output .= '<td class="capability-id">';
477 $output .= $result->capability_id;
478 $output .= '</td>';
479 $output .= '<td class="capability">';
480 $output .= sprintf( '<a href="%s">%s</a>', esc_url( $edit_url ), $result->capability ? stripslashes( wp_filter_nohtml_kses( $result->capability ) ) : '' );
481 $output .= $row_actions;
482 $output .= '</td>';
483 $output .= '<td class="description">';
484 $output .= $result->description ? stripslashes( wp_filter_nohtml_kses( $result->description ) ) : '';
485 $output .= '</td>';
486
487 $output .= '</tr>';
488 }
489 } else {
490 $output .= '<tr><td colspan="3">' . esc_html__( 'There are no results.', 'groups' ) . '</td></tr>';
491 }
492
493 $output .= '</tbody>';
494 $output .= '</table>';
495
496 $output .= Groups_UIE::render_add_titles( '.capabilities-overview table td' );
497
498 $output .= '</form>'; // #groups-action
499
500 if ( $paginate ) {
501 require_once GROUPS_CORE_LIB . '/class-groups-pagination.php';
502 $pagination = new Groups_Pagination($count, null, $row_count);
503 $output .= '<div class="tablenav bottom">';
504 $output .= $pagination->pagination( 'bottom' );
505 $output .= '</div>';
506 }
507
508 $output .= '</div>'; // .capabilities-overview
509 $output .= '</div>'; // .manage-capabilities
510
511 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
512 } // function groups_admin_capabilities()
513