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