PluginProbe
Groups – Memberships and Access Control / 3.9.0
Groups – Memberships and Access Control v3.9.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
groups / lib / admin / groups-admin-options.php

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

476 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * groups-admin-options.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 /**
27 * @var string GROUPS_ADMIN_OPTIONS_NONCE options form nonce name
28 */
29 define( 'GROUPS_ADMIN_OPTIONS_NONCE', 'groups-admin-nonce' );
30
31 /**
32 * @var int GROUPS_SHOW_EXTENSIONS_BOX_INTERVAL 14 days in seconds
33 */
34 define( 'GROUPS_SHOW_EXTENSIONS_BOX_INTERVAL', 1209600 );
35
36 /**
37 * Options admin screen.
38 */
39 function groups_admin_options() {
40
41 global $wp_roles, $groups_version;
42
43 if ( !Groups_User::current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
44 wp_die( esc_html__( 'Access denied.', 'groups' ) );
45 }
46
47 $is_sitewide_plugin = false;
48 if ( is_multisite() ) {
49 $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
50 $active_sitewide_plugins = array_keys( $active_sitewide_plugins );
51 $is_sitewide_plugin = in_array( 'groups/groups.php', $active_sitewide_plugins );
52 }
53
54 $caps = array(
55 GROUPS_ACCESS_GROUPS => __( 'Access Groups', 'groups' ),
56 GROUPS_ADMINISTER_GROUPS => __( 'Administer Groups', 'groups' ),
57 GROUPS_ADMINISTER_OPTIONS => __( 'Administer Groups plugin options', 'groups' ),
58 GROUPS_RESTRICT_ACCESS => __( 'Restrict Access', 'groups' )
59 );
60
61 $previous_legacy_enable = Groups_Options::get_option( GROUPS_LEGACY_ENABLE, GROUPS_LEGACY_ENABLE_DEFAULT );
62
63 //
64 // handle options form submission
65 //
66 if ( isset( $_POST['submit'] ) ) {
67 if ( wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
68
69 $post_types = get_post_types();
70 $selected_post_types = !empty( $_POST['add_meta_boxes'] ) && is_array( $_POST['add_meta_boxes'] ) ? $_POST['add_meta_boxes'] : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
71 $handle_post_types = array();
72 foreach( $post_types as $post_type ) {
73 $handle_post_types[$post_type] = in_array( $post_type, $selected_post_types );
74 }
75 Groups_Post_Access::set_handles_post_types( $handle_post_types );
76
77 // tree view
78 if ( !empty( $_POST[GROUPS_SHOW_TREE_VIEW] ) ) {
79 Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, true );
80 } else {
81 Groups_Options::update_option( GROUPS_SHOW_TREE_VIEW, false );
82 }
83
84 // show in user profiles
85 Groups_Options::update_option( GROUPS_SHOW_IN_USER_PROFILE, !empty( $_POST[GROUPS_SHOW_IN_USER_PROFILE] ) );
86
87 // roles & capabilities
88 $rolenames = $wp_roles->get_names();
89 foreach ( $rolenames as $rolekey => $rolename ) {
90 $role = $wp_roles->get_role( $rolekey );
91 foreach ( $caps as $capkey => $capname ) {
92 $role_cap_id = $rolekey.'-'.$capkey;
93 if ( !empty($_POST[$role_cap_id] ) ) {
94 $role->add_cap( $capkey );
95 } else {
96 $role->remove_cap( $capkey );
97 }
98 }
99 }
100 Groups_Controller::assure_capabilities();
101
102 if ( !$is_sitewide_plugin ) {
103 // delete data
104 if ( !empty( $_POST['delete-data'] ) ) {
105 Groups_Options::update_option( 'groups_delete_data', true );
106 } else {
107 Groups_Options::update_option( 'groups_delete_data', false );
108 }
109 }
110
111 // legacy enable ?
112 if ( !empty( $_POST[GROUPS_LEGACY_ENABLE] ) ) {
113 Groups_Options::update_option( GROUPS_LEGACY_ENABLE, true );
114 } else {
115 Groups_Options::update_option( GROUPS_LEGACY_ENABLE, false );
116 }
117
118 Groups_Admin::add_message( __( 'Options saved.', 'groups' ) );
119 }
120 }
121
122 echo '<div class="groups-options wrap">';
123
124 echo
125 '<h1>' .
126 esc_html__( 'Groups Options', 'groups' ) .
127 '</h1>';
128
129 echo Groups_Admin::render_messages(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
130
131 $show_tree_view = Groups_Options::get_option( GROUPS_SHOW_TREE_VIEW, GROUPS_SHOW_TREE_VIEW_DEFAULT );
132 $show_in_user_profile = Groups_Options::get_option( GROUPS_SHOW_IN_USER_PROFILE, GROUPS_SHOW_IN_USER_PROFILE_DEFAULT );
133
134 $rolenames = $wp_roles->get_names();
135 $caps_table = '<table class="groups-permissions">';
136 $caps_table .= '<thead>';
137 $caps_table .= '<tr>';
138 $caps_table .= '<td class="role">';
139 $caps_table .= esc_html__( 'Role', 'groups' );
140 $caps_table .= '</td>';
141 foreach ( $caps as $cap ) {
142 $caps_table .= '<td class="cap">';
143 $caps_table .= esc_html( $cap );
144 $caps_table .= '</td>';
145 }
146
147 $caps_table .= '</tr>';
148 $caps_table .= '</thead>';
149 $caps_table .= '<tbody>';
150 foreach ( $rolenames as $rolekey => $rolename ) {
151 $role = $wp_roles->get_role( $rolekey );
152 $caps_table .= '<tr>';
153 $caps_table .= '<td>';
154 $caps_table .= esc_html( translate_user_role( $rolename ) );
155 $caps_table .= '</td>';
156 foreach ( $caps as $capkey => $capname ) {
157
158 if ( $role->has_cap( $capkey ) ) {
159 $checked = ' checked="checked" ';
160 } else {
161 $checked = '';
162 }
163
164 $caps_table .= '<td class="checkbox">';
165 $role_cap_id = $rolekey.'-'.$capkey;
166 $caps_table .= '<input type="checkbox" name="' . esc_attr( $role_cap_id ) . '" id="' . esc_attr( $role_cap_id ) . '" ' . $checked . '/>';
167 $caps_table .= '</td>';
168 }
169 $caps_table .= '</tr>';
170 }
171 $caps_table .= '</tbody>';
172 $caps_table .= '</table>';
173
174 $delete_data = Groups_Options::get_option( 'groups_delete_data', false );
175
176 if ( isset( $_GET['dismiss-groups-extensions-box'] ) && isset( $_GET['groups-extensions-box-nonce'] ) && wp_verify_nonce( $_GET['groups-extensions-box-nonce'], 'dismiss-box' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
177 Groups_Options::update_user_option( 'show-extensions-box', time() );
178 }
179 $extensions_box = '';
180 $show_extensions_box = Groups_Options::get_user_option( 'show-extensions-box', 0 );
181 if ( ( time() - $show_extensions_box ) > GROUPS_SHOW_EXTENSIONS_BOX_INTERVAL ) {
182 $dismiss_url = wp_nonce_url( add_query_arg( 'dismiss-groups-extensions-box', '1', admin_url( 'admin.php?page=groups-admin-options' ) ), 'dismiss-box', 'groups-extensions-box-nonce' );
183 $extensions_box = '<div id="groups-extensions-box">';
184 $extensions_box .= sprintf( '<a title="%s" class="close" href="%s"></a>', esc_attr_x( 'Dismiss', 'title of dismiss notice link', 'groups' ), esc_url( $dismiss_url ) );
185 $extensions_box .= '<h3>';
186 $extensions_box .= esc_html__( 'Your support matters!', 'groups' );
187 $extensions_box .= '</h3>';
188 $extensions_box .= '<p>';
189 $extensions_box .= sprintf(
190 /* translators: 1: opening tag 2: closing tag */
191 esc_html__( 'Enhanced functionality is available via official %1$sExtensions%2$s for Groups.', 'groups' ),
192 '<a href="https://www.itthinx.com/shop/">',
193 '</a>'
194 );
195 $extensions_box .= '</p>';
196 $extensions_box .= '<p>';
197 $extensions_box .= esc_html__( 'By getting an official extension, you fund the work that is necessary to maintain and improve Groups.', 'groups' );
198 $extensions_box .= '</p>';
199 $extensions_box .= '</div>';
200 }
201
202 $bitcoin_box = Groups_Admin_Notice::get_groups_bitcoin_box( array( 'where' => 'options' ) );
203
204 //
205 // print the options form
206 //
207 echo
208 '<form action="" name="options" method="post">' .
209 '<div>' .
210
211 '<p>' .
212 '<input class="button button-primary" type="submit" name="submit" value="' . esc_attr__( 'Save', 'groups' ) . '"/>' .
213 $bitcoin_box . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
214 $extensions_box . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
215 '</p>';
216
217 if ( _groups_admin_override() ) {
218 echo
219 '<h2 style="color:red">' .
220 esc_html__( 'Administrator Access Override', 'groups' ) .
221 '</h2>' .
222 '<p>' .
223 esc_html__( 'Administrators override all access permissions derived from Groups capabilities.', 'groups' ) .
224 '</p>' .
225 '<p>' .
226 wp_kses_post( __( 'To disable, do not define the constant <code>GROUPS_ADMINISTRATOR_OVERRIDE</code> or set it to <code>false</code>.', 'groups' ) ) .
227 '</p>' .
228 '<p>' .
229 wp_kses_post( __( 'Enabling this on production sites is <strong>not</strong> recommended.', 'groups' ) ) .
230 '</p>';
231 }
232
233 echo '<h2>';
234 echo esc_html__( 'Access restricions', 'groups' );
235 echo '</h2>';
236
237 echo '<h3>';
238 echo esc_html__( 'Post types', 'groups' );
239 echo '</h3>';
240
241 echo '<p class="description">';
242 echo esc_html__( 'Show access restrictions for these post types.', 'groups' ); // @todo change wording to '...handles access...' ?
243 echo '</p>';
244
245 $post_type_objects = get_post_types( array(), 'objects' );
246 uasort( $post_type_objects, 'groups_admin_options_compare_post_types' );
247
248 echo '<ul>';
249 foreach( $post_type_objects as $post_type => $post_type_object ) {
250 echo '<li>';
251 echo '<label>';
252 $label = $post_type;
253 $labels = isset( $post_type_object->labels ) ? $post_type_object->labels : null;
254 if ( ( $labels !== null ) && isset( $labels->singular_name ) ) {
255 $label = $labels->singular_name; // this is already translated
256 }
257 $checked = Groups_Post_Access::handles_post_type( $post_type ) ? ' checked="checked" ' : '';
258 echo '<input name="add_meta_boxes[]" type="checkbox" value="' . esc_attr( $post_type ) . '" ' . $checked . '/>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
259 $is_public = isset( $post_type_object->public ) && $post_type_object->public;
260 echo $is_public ? '<strong>' : '';
261 echo esc_html( $label );
262 echo $is_public ? '</strong>' : '';
263 if ( $post_type != $label ) {
264 echo ' ';
265 echo '<code><small>';
266 echo esc_html( $post_type );
267 echo '</small></code>';
268 }
269 echo '</label>';
270 echo '</li>';
271 }
272 echo '<ul>';
273 echo '<p class="description">';
274 esc_html_e( 'This determines for which post types access restriction settings are offered.', 'groups' );
275 echo ' ';
276 esc_html_e( 'Disabling this setting for a post type also disables existing access restrictions on individual posts of that type.', 'groups' );
277 echo ' ';
278 esc_html_e( 'Some post types shown may not offer access restrictions even though they appear enabled here.', 'groups' );
279 echo '</p>';
280
281 echo
282 '<h2>' . esc_html__( 'User profiles', 'groups' ) . '</h2>' .
283 '<p>' .
284 '<label>' .
285 '<input name="' . GROUPS_SHOW_IN_USER_PROFILE . '" type="checkbox" ' . ( $show_in_user_profile ? 'checked="checked"' : '' ) . '/>' . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
286 esc_html__( 'Show groups in user profiles.', 'groups' ) .
287 '</label>' .
288 '</p>';
289
290 echo
291 '<h2>' . esc_html__( 'Tree view', 'groups' ) . '</h2>' .
292 '<p>' .
293 '<label>' .
294 '<input name="' . GROUPS_SHOW_TREE_VIEW . '" type="checkbox" ' . ( $show_tree_view ? 'checked="checked"' : '' ) . '/>' . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
295 esc_html__( 'Show the Groups tree view.', 'groups' ) .
296 '</label>' .
297 '</p>';
298
299 echo
300 '<h2>' . esc_html__( 'Permissions', 'groups' ) . '</h2>' .
301 '<p>' . esc_html__( 'These permissions apply to Groups management. They do not apply to access permissions derived from Groups capabilities.', 'groups' ) . '</p>' .
302 $caps_table . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
303 '<p class="description">' .
304 esc_html__( 'A minimum set of permissions will be preserved.', 'groups' ) .
305 '<br/>' .
306 esc_html__( 'If you lock yourself out, please ask an administrator to help.', 'groups' ) .
307 '</p>';
308 if ( !$is_sitewide_plugin ) {
309 echo
310 '<h2>' . esc_html__( 'Deactivation and data persistence', 'groups' ) . '</h2>' .
311 '<p>' .
312 '<label>' .
313 '<input name="delete-data" type="checkbox" ' . ( $delete_data ? 'checked="checked"' : '' ) . '/>' .
314 esc_html__( 'Delete all Groups plugin data on deactivation', 'groups' ) .
315 '</label>' .
316 '</p>' .
317 '<p class="description warning">' .
318 esc_html__( 'CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', 'groups' ) .
319 '</p>';
320 }
321
322 $groups_legacy_enable = Groups_Options::get_option( GROUPS_LEGACY_ENABLE, GROUPS_LEGACY_ENABLE_DEFAULT );
323 if (
324 defined( 'GROUPS_SHOW_LEGACY_SETTINGS' ) && GROUPS_SHOW_LEGACY_SETTINGS === true || $groups_legacy_enable
325 ) {
326 echo '<h2>' . esc_html__( 'Legacy Settings', 'groups' ) . '</h2>';
327 echo '<p>' .
328 '<label>' .
329 '<input name="' . esc_attr( GROUPS_LEGACY_ENABLE ) . '" type="checkbox" ' . ( $groups_legacy_enable ? 'checked="checked"' : '' ) . '/>' . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
330 esc_html__( 'Enable legacy access control based on capabilities.', 'groups' ) .
331 '</label>' .
332 '</p>';
333 if ( $groups_legacy_enable ) {
334 require_once GROUPS_LEGACY_LIB . '/admin/groups-admin-options-legacy.php';
335 do_action( 'groups_admin_options_legacy', $groups_legacy_enable !== $previous_legacy_enable );
336 }
337
338 $legacy_enabled = Groups_Options::get_option( GROUPS_LEGACY_ENABLE );
339 echo '<h3>';
340 /* translators: version number */
341 printf( esc_html__( 'Switching to Groups %s', 'groups' ), esc_html( $groups_version ) );
342 echo '</h3>';
343 echo '<p>';
344 /* translators: version number */
345 printf( esc_html__( 'Groups %s features a simpler model for access restrictions based on groups instead of capabilities used in Groups 1.x.', 'groups' ), esc_html( $groups_version ) );
346 echo ' ';
347 esc_html_e( 'To put it simple, previously you would have used capabilities to restrict access to posts and now you simply use groups.', 'groups' );
348 echo ' ';
349 esc_html_e( 'To make it easier to transition to the new model for those who migrate from a previous version, we have included legacy access control based on capabilities.', 'groups' );
350 echo '</p>';
351 echo '<div class="indent">';
352 echo '<p>';
353 esc_html_e( 'The following is only of interest if you have upgraded from Groups 1.x:', 'groups' );
354 echo '<br/>';
355 if ( $legacy_enabled ) {
356 esc_html_e( 'You are running the system with legacy access control based on capabilities enabled.', 'groups' );
357 echo ' ';
358 esc_html_e( 'This means that if you had access restrictions in place that were based on capabilities, your entries will still be protected.', 'groups' );
359 } else {
360 esc_html_e( 'You are running the system with legacy access control based on capabilities disabled.', 'groups' );
361 echo ' ';
362 esc_html_e( 'This could be important!', 'groups' );
363 echo ' ';
364 esc_html_e( 'If you had any access restrictions in place based on capabilities, the entries will now be unprotected, unless you enable legacy access restrictions or place appropriate access restrictions based on groups on the desired entries.', 'groups' );
365 }
366 echo '</p>';
367 echo '<p>';
368 esc_html_e( 'If you would like to switch to access restrictions based on groups (recommended) instead of capabilities, you can easily do so by setting the appropriate groups on your protected posts, pages and other entries to restrict access.', 'groups' );
369 echo ' ';
370 esc_html_e( 'Once you have adjusted your access restrictions based on groups, you can disable legacy access control.', 'groups' );
371 echo ' ';
372 echo sprintf(
373 /* translators: documentation pages link */
374 esc_html__( 'Please refer to the %s for details on how to switch to and use the new access restrictions.', 'groups' ),
375 sprintf( '<a target="_blank" href="https://docs.itthinx.com/document/groups/">%s</a>', esc_html__( 'Documentation', 'groups' ) )
376 );
377 echo '</p>';
378 echo '</div>'; // .indent
379 }
380
381 echo
382 '<p>' .
383 wp_nonce_field( 'admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
384 '<input class="button button-primary" type="submit" name="submit" value="' . esc_attr__( 'Save', 'groups' ) . '"/>' .
385 '</p>' .
386 '</div>' .
387 '</form>';
388
389 echo '</div>'; // .groups-options
390 }
391
392 /**
393 * Network administration options.
394 */
395 function groups_network_admin_options() {
396
397 if ( !Groups_User::current_user_can( GROUPS_ADMINISTER_OPTIONS ) ) {
398 wp_die( esc_html__( 'Access denied.', 'groups' ) );
399 }
400
401 echo
402 '<div>' .
403 '<h1>' .
404 esc_html__( 'Groups network options', 'groups' ) .
405 '</h1>' .
406 '</div>';
407
408 // handle options form submission
409 if ( isset( $_POST['submit'] ) ) {
410 if ( wp_verify_nonce( $_POST[GROUPS_ADMIN_OPTIONS_NONCE], 'admin' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
411 // delete data
412 if ( !empty( $_POST['delete-data'] ) ) {
413 Groups_Options::update_option( 'groups_network_delete_data', true );
414 } else {
415 Groups_Options::update_option( 'groups_network_delete_data', false );
416 }
417 }
418 }
419
420 $delete_data = Groups_Options::get_option( 'groups_network_delete_data', false );
421
422 // options form
423 echo
424 '<form action="" name="options" method="post">' .
425 '<div>' .
426 '<h2>' . esc_html__( 'Network deactivation and data persistence', 'groups' ) . '</h2>' .
427 '<p>' .
428 '<label>' .
429 '<input name="delete-data" type="checkbox" ' . ( $delete_data ? 'checked="checked"' : '' ) . '/>' .
430 ' ' .
431 esc_html__( 'Delete all Groups plugin data for ALL sites on network deactivation', 'groups' ) .
432 '</label>' .
433 '</p>' .
434 '<p class="description warning">' .
435 wp_kses_post( __( 'CAUTION: If this option is active while the plugin is deactivated, ALL plugin settings and data will be DELETED for <strong>all sites</strong>. If you are going to use this option, now would be a good time to make a backup. By enabling this option you agree to be solely responsible for any loss of data or any other consequences thereof.', 'groups' ) ) .
436 '</p>' .
437 '<p>' .
438 wp_nonce_field( 'admin', GROUPS_ADMIN_OPTIONS_NONCE, true, false ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
439 '<input class="button button-primary" type="submit" name="submit" value="' . esc_attr__( 'Save', 'groups' ) . '"/>' .
440 '</p>' .
441 '</div>' .
442 '</form>';
443 }
444
445 /**
446 * Compare two post types, considering those that have $public and/or $show_ui true as coming first.
447 *
448 * @param object $o1
449 * @param object $o2
450 *
451 * @return int
452 */
453 function groups_admin_options_compare_post_types( $o1, $o2 ) {
454 $name_1 = isset( $o1->name ) ? $o1->name : '';
455 $name_2 = isset( $o2->name ) ? $o2->name : '';
456 $public_1 = isset( $o1->public ) && $o1->public;
457 $public_2 = isset( $o2->public ) && $o2->public;
458 $show_ui_1 = isset( $o1->show_ui ) && $o1->show_ui;
459 $show_ui_2 = isset( $o2->show_ui ) && $o2->show_ui;
460 $n1 = 0;
461 $n2 = 0;
462 if ( $public_1 ) {
463 $n1--;
464 }
465 if ( $show_ui_1 ) {
466 $n1--;
467 }
468 if ( $public_2 ) {
469 $n2--;
470 }
471 if ( $show_ui_2 ) {
472 $n2--;
473 }
474 return ( $n1 - $n2 ) * 10 + strcmp( $name_1, $name_2 );
475 }
476