Capability Manager Enhanced - Version 2.4.0

Version Description

  • 28 Apr 2022 =
    • Fixed : Post title not working with editor features #370
    • Fixed : Issue with revision metabox and some plugin metabox in Editor features. #369
    • Fixed : Editor Features compability with taxonomies created by the "Toolset" plugin. #367
    • Fixed : Backup Features text missing some "s" #365
    • Update : Change import upload file delete to use WordPress function #364
    • Update : Make sure "Copy" feature for roles works with Editor Features and more #362
    • Update : Add short description for "Role Level" #361
    • Update : Make "Roles" into the top menu link #326
    • Update : Vertical tabs similar to the "Capabilities" for Editor Features #257
    • Fixed : Can't hide the "Profile" link with "Admin Menus" #337
    • Update : More Columns on Roles Screen #181
Download this release

Release Info

Developer olatechpro
Plugin Icon 128x128 Capability Manager Enhanced
Version 2.4.0
Comparing to
See all releases

Code changes from version 2.3.6 to 2.4.0

Files changed (54) hide show
  1. capsman-enhanced.php +149 -149
  2. classes/pp-capabilities-notices.php +153 -153
  3. common/css/admin.css +852 -835
  4. common/js/admin.dev.js +236 -236
  5. common/js/profile.js +34 -34
  6. composer.json +24 -24
  7. composer.lock +1 -1
  8. framework/lib/users.php +109 -109
  9. framework/styles/admin.css +134 -134
  10. includes-core/CoreAdmin.php +84 -84
  11. includes-core/admin-core.css +184 -184
  12. includes-core/admin-features-promo.php +136 -136
  13. includes-core/admin-menus-promo.php +157 -157
  14. includes-core/editor-features-promo.php +126 -147
  15. includes-core/nav-menus-promo.php +88 -88
  16. includes/admin-load.php +353 -330
  17. includes/admin.php +1427 -1427
  18. includes/backup-handler.php +315 -315
  19. includes/backup.php +451 -451
  20. includes/cap-helper.php +378 -378
  21. includes/features/admin-features.php +349 -349
  22. includes/features/editor-features-classic.php +76 -107
  23. includes/features/editor-features-gutenberg.php +75 -106
  24. includes/features/editor-features.php +400 -257
  25. includes/features/features-block-script.js +34 -34
  26. includes/features/restrict-admin-features.php +401 -401
  27. includes/features/restrict-editor-features.php +353 -353
  28. includes/filters-admin.php +44 -44
  29. includes/filters-woocommerce.php +35 -35
  30. includes/filters-wp_rest_workarounds.php +269 -269
  31. includes/filters.php +259 -259
  32. includes/functions-admin.php +249 -232
  33. includes/functions.php +289 -289
  34. includes/handler.php +379 -379
  35. includes/inflect-cme.php +136 -136
  36. includes/manager.php +1027 -1008
  37. includes/network.php +85 -85
  38. includes/pp-handler.php +102 -102
  39. includes/pp-ui.php +294 -294
  40. includes/publishpress-roles.php +36 -36
  41. includes/roles/class/class-pp-roles-actions.php +659 -615
  42. includes/roles/class/class-pp-roles-admin.php +502 -491
  43. includes/roles/class/class-pp-roles-list-table.php +749 -594
  44. includes/roles/class/class-pp-roles-loader.php +156 -156
  45. includes/roles/class/class-pp-roles-manager.php +232 -232
  46. includes/roles/class/class-pp-roles.php +163 -163
  47. includes/roles/css/pp-roles-admin.css +39 -25
  48. includes/roles/js/pp-roles-admin.js +114 -114
  49. includes/roles/roles-functions.php +120 -120
  50. includes/roles/roles.php +51 -51
  51. includes/settings-handler.php +26 -26
  52. includes/settings.php +62 -62
  53. languages/capsman-enhanced-ca.mo +0 -0
  54. languages/capsman-enhanced-ca.po +247 -47
capsman-enhanced.php CHANGED
@@ -1,149 +1,149 @@
1
- <?php
2
- /**
3
- * Plugin Name: PublishPress Capabilities
4
- * Plugin URI: https://publishpress.com/capability-manager/
5
- * Description: Manage WordPress role definitions, per-site or network-wide. Organizes post capabilities by post type and operation.
6
- * Version: 2.3.6
7
- * Author: PublishPress
8
- * Author URI: https://publishpress.com/
9
- * Text Domain: capsman-enhanced
10
- * Domain Path: /languages/
11
- * Min WP Version: 4.9.7
12
- * Requires PHP: 5.6.20
13
- * License: GPLv3
14
- *
15
- * Copyright (c) 2022 PublishPress
16
- *
17
- * ------------------------------------------------------------------------------
18
- * Based on Capability Manager
19
- * Author: Jordi Canals
20
- * Copyright (c) 2009, 2010 Jordi Canals
21
- * ------------------------------------------------------------------------------
22
- *
23
- * @package capability-manager-enhanced
24
- * @author PublishPress
25
- * @copyright Copyright (C) 2009, 2010 Jordi Canals; modifications Copyright (C) 2022 PublishPress
26
- * @license GNU General Public License version 3
27
- * @link https://publishpress.com/
28
- * @version 2.3.6
29
- */
30
-
31
- if (!defined('CAPSMAN_VERSION')) {
32
- define('CAPSMAN_VERSION', '2.3.6');
33
- define('CAPSMAN_ENH_VERSION', '2.3.6');
34
- define('PUBLISHPRESS_CAPS_VERSION', '2.3.6');
35
- }
36
-
37
- foreach (get_option('active_plugins') as $plugin_file) {
38
- if ( false !== strpos($plugin_file, 'capsman.php') ) {
39
- add_action('admin_notices', function() {
40
- echo '<div id="message" class="error fade" style="color: black">' . sprintf(esc_html__('%1s Error: %2s PublishPress Capabilities cannot function because another copy of Capability Manager is active.', 'capsman-enhanced'), '<strong>', '</strong>') . '</div>';
41
- });
42
- return;
43
- }
44
- }
45
-
46
- $pro_active = false;
47
-
48
- foreach ((array)get_option('active_plugins') as $plugin_file) {
49
- if (false !== strpos($plugin_file, 'capabilities-pro.php')) {
50
- $pro_active = true;
51
- break;
52
- }
53
- }
54
-
55
- if (!$pro_active && is_multisite()) {
56
- foreach (array_keys((array)get_site_option('active_sitewide_plugins')) as $plugin_file) {
57
- if (false !== strpos($plugin_file, 'capabilities-pro.php')) {
58
- $pro_active = true;
59
- break;
60
- }
61
- }
62
- }
63
-
64
- if ($pro_active) {
65
- add_filter(
66
- 'plugin_row_meta',
67
- function($links, $file)
68
- {
69
- if ($file == plugin_basename(__FILE__)) {
70
- $links[]= '<strong>' . esc_html__('This plugin can be deleted.', 'capsman-enhanced') . '</strong>';
71
- }
72
-
73
- return $links;
74
- },
75
- 10, 2
76
- );
77
- }
78
-
79
- if (defined('CME_FILE') || $pro_active) {
80
- return;
81
- }
82
-
83
- define ( 'CME_FILE', __FILE__ );
84
- define ('PUBLISHPRESS_CAPS_ABSPATH', __DIR__);
85
-
86
- require_once (dirname(__FILE__) . '/includes/functions.php');
87
-
88
- // ============================================ START PROCEDURE ==========
89
-
90
- // Check required PHP version.
91
- if ( version_compare(PHP_VERSION, '5.4.0', '<') ) {
92
- // Send an armin warning
93
- add_action('admin_notices', function() {
94
- $data = get_plugin_data(__FILE__);
95
- load_plugin_textdomain('capsman-enhanced', false, basename(dirname(__FILE__)) .'/languages');
96
-
97
- echo '<div class="error"><p><strong>' . esc_html__('Warning:', 'capsman-enhanced') . '</strong> '
98
- . sprintf(esc_html__('The active plugin %s is not compatible with your PHP version.', 'capsman-enhanced') .'</p><p>',
99
- '&laquo;' . esc_html($data['Name']) . ' ' . esc_html($data['Version']) . '&raquo;')
100
- . sprintf(esc_html__('%s is required for this plugin.', 'capsman-enhanced'), 'PHP-5 ')
101
- . '</p></div>';
102
- });
103
- } else {
104
- global $pagenow;
105
-
106
- // redirect legacy URLs
107
- if (!empty($_REQUEST['page'])) {
108
- foreach(['capsman' => 'pp-capabilities', 'capsman-tool' => 'pp-capabilities-backup'] as $find => $replace) {
109
- if (isset($_REQUEST['page']) && ($find == $_REQUEST['page']) && !empty($_SERVER['REQUEST_URI'])) {
110
- $location = str_replace("page=$find", "page=$replace", esc_url_raw($_SERVER['REQUEST_URI']));
111
- header( "Location: $location", true);
112
- exit;
113
- }
114
- }
115
- }
116
-
117
- if (is_admin()) {
118
- load_plugin_textdomain('capsman-enhanced', false, basename(dirname(__FILE__)) .'/languages');
119
-
120
- // @todo: refactor
121
- require_once (dirname(__FILE__) . '/includes/functions-admin.php');
122
-
123
- global $capsman_admin;
124
- require_once (dirname(__FILE__) . '/includes/admin-load.php');
125
- $capsman_admin = new PP_Capabilities_Admin_UI();
126
- }
127
-
128
- if (is_admin() && !defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
129
- require_once(__DIR__ . '/includes-core/CoreAdmin.php');
130
- new \PublishPress\Capabilities\CoreAdmin();
131
- }
132
- }
133
-
134
- add_action( 'init', '_cme_init' );
135
- add_action( 'plugins_loaded', '_cme_act_pp_active', 1 );
136
-
137
- add_action( 'init', '_cme_cap_helper', 49 ); // Press Permit Cap Helper, registered at 50, will leave caps which we've already defined
138
- //add_action( 'wp_loaded', '_cme_cap_helper_late_init', 99 ); // now instead adding registered_post_type, registered_taxonomy action handlers for latecomers
139
- // @todo: do this in PP Core also
140
-
141
- if ( is_multisite() )
142
- require_once ( dirname(__FILE__) . '/includes/network.php' );
143
-
144
- // Check if Permissions is installed
145
- if (!cme_is_plugin_active('press-permit-core.php') && !cme_is_plugin_active('presspermit-pro.php')) {
146
- define('CAPSMAN_PERMISSIONS_INSTALLED', false);
147
- } else {
148
- define('CAPSMAN_PERMISSIONS_INSTALLED', true);
149
- }
1
+ <?php
2
+ /**
3
+ * Plugin Name: PublishPress Capabilities
4
+ * Plugin URI: https://publishpress.com/capability-manager/
5
+ * Description: Manage WordPress role definitions, per-site or network-wide. Organizes post capabilities by post type and operation.
6
+ * Version: 2.4.0
7
+ * Author: PublishPress
8
+ * Author URI: https://publishpress.com/
9
+ * Text Domain: capsman-enhanced
10
+ * Domain Path: /languages/
11
+ * Min WP Version: 4.9.7
12
+ * Requires PHP: 5.6.20
13
+ * License: GPLv3
14
+ *
15
+ * Copyright (c) 2022 PublishPress
16
+ *
17
+ * ------------------------------------------------------------------------------
18
+ * Based on Capability Manager
19
+ * Author: Jordi Canals
20
+ * Copyright (c) 2009, 2010 Jordi Canals
21
+ * ------------------------------------------------------------------------------
22
+ *
23
+ * @package capability-manager-enhanced
24
+ * @author PublishPress
25
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals; modifications Copyright (C) 2022 PublishPress
26
+ * @license GNU General Public License version 3
27
+ * @link https://publishpress.com/
28
+ * @version 2.4.0
29
+ */
30
+
31
+ if (!defined('CAPSMAN_VERSION')) {
32
+ define('CAPSMAN_VERSION', '2.4.0');
33
+ define('CAPSMAN_ENH_VERSION', '2.4.0');
34
+ define('PUBLISHPRESS_CAPS_VERSION', '2.4.0');
35
+ }
36
+
37
+ foreach (get_option('active_plugins') as $plugin_file) {
38
+ if ( false !== strpos($plugin_file, 'capsman.php') ) {
39
+ add_action('admin_notices', function() {
40
+ echo '<div id="message" class="error fade" style="color: black">' . sprintf(esc_html__('%1s Error: %2s PublishPress Capabilities cannot function because another copy of Capability Manager is active.', 'capsman-enhanced'), '<strong>', '</strong>') . '</div>';
41
+ });
42
+ return;
43
+ }
44
+ }
45
+
46
+ $pro_active = false;
47
+
48
+ foreach ((array)get_option('active_plugins') as $plugin_file) {
49
+ if (false !== strpos($plugin_file, 'capabilities-pro.php')) {
50
+ $pro_active = true;
51
+ break;
52
+ }
53
+ }
54
+
55
+ if (!$pro_active && is_multisite()) {
56
+ foreach (array_keys((array)get_site_option('active_sitewide_plugins')) as $plugin_file) {
57
+ if (false !== strpos($plugin_file, 'capabilities-pro.php')) {
58
+ $pro_active = true;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+
64
+ if ($pro_active) {
65
+ add_filter(
66
+ 'plugin_row_meta',
67
+ function($links, $file)
68
+ {
69
+ if ($file == plugin_basename(__FILE__)) {
70
+ $links[]= '<strong>' . esc_html__('This plugin can be deleted.', 'capsman-enhanced') . '</strong>';
71
+ }
72
+
73
+ return $links;
74
+ },
75
+ 10, 2
76
+ );
77
+ }
78
+
79
+ if (defined('CME_FILE') || $pro_active) {
80
+ return;
81
+ }
82
+
83
+ define ( 'CME_FILE', __FILE__ );
84
+ define ('PUBLISHPRESS_CAPS_ABSPATH', __DIR__);
85
+
86
+ require_once (dirname(__FILE__) . '/includes/functions.php');
87
+
88
+ // ============================================ START PROCEDURE ==========
89
+
90
+ // Check required PHP version.
91
+ if ( version_compare(PHP_VERSION, '5.4.0', '<') ) {
92
+ // Send an armin warning
93
+ add_action('admin_notices', function() {
94
+ $data = get_plugin_data(__FILE__);
95
+ load_plugin_textdomain('capsman-enhanced', false, basename(dirname(__FILE__)) .'/languages');
96
+
97
+ echo '<div class="error"><p><strong>' . esc_html__('Warning:', 'capsman-enhanced') . '</strong> '
98
+ . sprintf(esc_html__('The active plugin %s is not compatible with your PHP version.', 'capsman-enhanced') .'</p><p>',
99
+ '&laquo;' . esc_html($data['Name']) . ' ' . esc_html($data['Version']) . '&raquo;')
100
+ . sprintf(esc_html__('%s is required for this plugin.', 'capsman-enhanced'), 'PHP-5 ')
101
+ . '</p></div>';
102
+ });
103
+ } else {
104
+ global $pagenow;
105
+
106
+ // redirect legacy URLs
107
+ if (!empty($_REQUEST['page'])) {
108
+ foreach(['capsman' => 'pp-capabilities', 'capsman-tool' => 'pp-capabilities-backup'] as $find => $replace) {
109
+ if (isset($_REQUEST['page']) && ($find == $_REQUEST['page']) && !empty($_SERVER['REQUEST_URI'])) {
110
+ $location = str_replace("page=$find", "page=$replace", esc_url_raw($_SERVER['REQUEST_URI']));
111
+ header( "Location: $location", true);
112
+ exit;
113
+ }
114
+ }
115
+ }
116
+
117
+ if (is_admin()) {
118
+ load_plugin_textdomain('capsman-enhanced', false, basename(dirname(__FILE__)) .'/languages');
119
+
120
+ // @todo: refactor
121
+ require_once (dirname(__FILE__) . '/includes/functions-admin.php');
122
+
123
+ global $capsman_admin;
124
+ require_once (dirname(__FILE__) . '/includes/admin-load.php');
125
+ $capsman_admin = new PP_Capabilities_Admin_UI();
126
+ }
127
+
128
+ if (is_admin() && !defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
129
+ require_once(__DIR__ . '/includes-core/CoreAdmin.php');
130
+ new \PublishPress\Capabilities\CoreAdmin();
131
+ }
132
+ }
133
+
134
+ add_action( 'init', '_cme_init' );
135
+ add_action( 'plugins_loaded', '_cme_act_pp_active', 1 );
136
+
137
+ add_action( 'init', '_cme_cap_helper', 49 ); // Press Permit Cap Helper, registered at 50, will leave caps which we've already defined
138
+ //add_action( 'wp_loaded', '_cme_cap_helper_late_init', 99 ); // now instead adding registered_post_type, registered_taxonomy action handlers for latecomers
139
+ // @todo: do this in PP Core also
140
+
141
+ if ( is_multisite() )
142
+ require_once ( dirname(__FILE__) . '/includes/network.php' );
143
+
144
+ // Check if Permissions is installed
145
+ if (!cme_is_plugin_active('press-permit-core.php') && !cme_is_plugin_active('presspermit-pro.php')) {
146
+ define('CAPSMAN_PERMISSIONS_INSTALLED', false);
147
+ } else {
148
+ define('CAPSMAN_PERMISSIONS_INSTALLED', true);
149
+ }
classes/pp-capabilities-notices.php CHANGED
@@ -1,153 +1,153 @@
1
- <?php
2
-
3
- class PP_Capabilities_Notices
4
- {
5
-
6
- /**
7
- * Notification name to use
8
- *
9
- */
10
- protected $notification = 'pp_roles_notification';
11
-
12
- /**
13
- * All types of notifications allowed
14
- *
15
- * @var string[]
16
- */
17
- protected $types = array('error', 'success', 'warning', 'info');
18
-
19
- /**
20
- * All current messages
21
- *
22
- * @var array
23
- */
24
- protected $messages = array();
25
-
26
- /**
27
- * Pp_Roles_Notifications constructor.
28
- *
29
- */
30
- public function __construct()
31
- {
32
- /**
33
- * Read notification if exist
34
- */
35
- if (get_option($this->notification)) {
36
- $messages = get_option($this->notification);
37
- $messages = @json_decode($messages, true);
38
- if (is_array($messages)) {
39
- $this->messages = [];
40
- foreach($messages as $message_type => $message_content){
41
- $this->messages[$message_type] = array_map('esc_html', $message_content);
42
- }
43
- }
44
- }
45
- }
46
-
47
- /**
48
- * Display all messages
49
- *
50
- */
51
- public function display()
52
- {
53
- $html = '';
54
- foreach ($this->types as $type) {
55
- $messages = $this->get($type);
56
- foreach ($messages as $message) {
57
- if (is_string($message)) {
58
- printf('<div class="notice notice-%s is-dismissible"><p>%s</p></div>', esc_attr($type), esc_html($message));
59
- }
60
- }
61
- }
62
-
63
- /**
64
- * Delete the notification after display
65
- */
66
- delete_option($this->notification);
67
- }
68
-
69
- /**
70
- * Get all messages for a given type
71
- *
72
- * @param string $type
73
- *
74
- * @return array The messages
75
- */
76
- protected function get($type)
77
- {
78
- $messages = array();
79
- if (isset($this->messages[$type]) && is_array($this->messages[$type])) {
80
- $messages = $this->messages[$type];
81
- }
82
-
83
- return $messages;
84
- }
85
-
86
- /**
87
- * @param string $type The type of notification to show to the user
88
- * [error|success|warning|info]
89
- * @param string $msg The message to show to the user
90
- *
91
- * @return bool If notification was added successfully
92
- */
93
- public function add($type, $msg)
94
- {
95
- if (!in_array($type, $this->types) || !is_string($msg)) {
96
- return false;
97
- }
98
-
99
- $messages = $this->get($type);
100
- $messages[] = $msg;
101
-
102
- //Update the messages
103
- $this->messages[$type] = $messages;
104
-
105
- update_option($this->notification, json_encode($this->messages));
106
-
107
- return true;
108
- }
109
-
110
- /**
111
- * Show an error message
112
- *
113
- * @param string $msg
114
- *
115
- */
116
- public function error($msg)
117
- {
118
- $this->add('error', $msg);
119
- }
120
-
121
- /**
122
- * Show a success message
123
- *
124
- * @param string $msg
125
- *
126
- */
127
- public function success($msg)
128
- {
129
- $this->add('success', $msg);
130
- }
131
-
132
- /**
133
- * Show a warning message
134
- *
135
- * @param string $msg
136
- *
137
- */
138
- public function warning($msg)
139
- {
140
- $this->add('warning', $msg);
141
- }
142
-
143
- /**
144
- * Show an info message
145
- *
146
- * @param string $msg
147
- *
148
- */
149
- public function info($msg)
150
- {
151
- $this->add('info', $msg);
152
- }
153
- }
1
+ <?php
2
+
3
+ class PP_Capabilities_Notices
4
+ {
5
+
6
+ /**
7
+ * Notification name to use
8
+ *
9
+ */
10
+ protected $notification = 'pp_roles_notification';
11
+
12
+ /**
13
+ * All types of notifications allowed
14
+ *
15
+ * @var string[]
16
+ */
17
+ protected $types = array('error', 'success', 'warning', 'info');
18
+
19
+ /**
20
+ * All current messages
21
+ *
22
+ * @var array
23
+ */
24
+ protected $messages = array();
25
+
26
+ /**
27
+ * Pp_Roles_Notifications constructor.
28
+ *
29
+ */
30
+ public function __construct()
31
+ {
32
+ /**
33
+ * Read notification if exist
34
+ */
35
+ if (get_option($this->notification)) {
36
+ $messages = get_option($this->notification);
37
+ $messages = @json_decode($messages, true);
38
+ if (is_array($messages)) {
39
+ $this->messages = [];
40
+ foreach($messages as $message_type => $message_content){
41
+ $this->messages[$message_type] = array_map('esc_html', $message_content);
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Display all messages
49
+ *
50
+ */
51
+ public function display()
52
+ {
53
+ $html = '';
54
+ foreach ($this->types as $type) {
55
+ $messages = $this->get($type);
56
+ foreach ($messages as $message) {
57
+ if (is_string($message)) {
58
+ printf('<div class="notice notice-%s is-dismissible"><p>%s</p></div>', esc_attr($type), esc_html($message));
59
+ }
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Delete the notification after display
65
+ */
66
+ delete_option($this->notification);
67
+ }
68
+
69
+ /**
70
+ * Get all messages for a given type
71
+ *
72
+ * @param string $type
73
+ *
74
+ * @return array The messages
75
+ */
76
+ protected function get($type)
77
+ {
78
+ $messages = array();
79
+ if (isset($this->messages[$type]) && is_array($this->messages[$type])) {
80
+ $messages = $this->messages[$type];
81
+ }
82
+
83
+ return $messages;
84
+ }
85
+
86
+ /**
87
+ * @param string $type The type of notification to show to the user
88
+ * [error|success|warning|info]
89
+ * @param string $msg The message to show to the user
90
+ *
91
+ * @return bool If notification was added successfully
92
+ */
93
+ public function add($type, $msg)
94
+ {
95
+ if (!in_array($type, $this->types) || !is_string($msg)) {
96
+ return false;
97
+ }
98
+
99
+ $messages = $this->get($type);
100
+ $messages[] = $msg;
101
+
102
+ //Update the messages
103
+ $this->messages[$type] = $messages;
104
+
105
+ update_option($this->notification, json_encode($this->messages));
106
+
107
+ return true;
108
+ }
109
+
110
+ /**
111
+ * Show an error message
112
+ *
113
+ * @param string $msg
114
+ *
115
+ */
116
+ public function error($msg)
117
+ {
118
+ $this->add('error', $msg);
119
+ }
120
+
121
+ /**
122
+ * Show a success message
123
+ *
124
+ * @param string $msg
125
+ *
126
+ */
127
+ public function success($msg)
128
+ {
129
+ $this->add('success', $msg);
130
+ }
131
+
132
+ /**
133
+ * Show a warning message
134
+ *
135
+ * @param string $msg
136
+ *
137
+ */
138
+ public function warning($msg)
139
+ {
140
+ $this->add('warning', $msg);
141
+ }
142
+
143
+ /**
144
+ * Show an info message
145
+ *
146
+ * @param string $msg
147
+ *
148
+ */
149
+ public function info($msg)
150
+ {
151
+ $this->add('info', $msg);
152
+ }
153
+ }
common/css/admin.css CHANGED
@@ -1,835 +1,852 @@
1
- /**
2
- * Settings for admin dashboard.
3
- * Based on the styles for Maintenance Mode plugin by Michael Wöhrer
4
- *
5
- * @version $Rev: 198515 $
6
- * @author Jordi Canals
7
- * @copyright Copyright (C) 2009, 2010 Jordi Canals
8
- * @license GNU General Public License version 2
9
- * @link http://alkivia.org
10
- * @package Alkivia
11
- * @subpackage CapsMan
12
- *
13
-
14
- Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
-
16
- This program is free software; you can redistribute it and/or
17
- modify it under the terms of the GNU General Public License
18
- version 2 as published by the Free Software Foundation.
19
-
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU General Public License for more details.
24
-
25
- You should have received a copy of the GNU General Public License
26
- along with this program. If not, see <http://www.gnu.org/licenses/>.
27
- */
28
-
29
-
30
- /* ====================================================== SIDEBAR ICONS */
31
-
32
- a.cap_type {
33
- text-decoration: none;
34
- }
35
-
36
- a.cap_type:hover {
37
- text-decoration: underline;
38
- }
39
-
40
- ul.cme-listhoriz li {
41
- text-align: center;
42
- padding-right: 1em;
43
- }
44
-
45
- ul.cme-listhoriz li table{
46
- text-align: center;
47
- }
48
-
49
-
50
- ul.cme-listhoriz {
51
- width: 100%;
52
- clear: both;
53
- float: left;
54
- margin: 0;
55
- padding: 0;
56
- }
57
-
58
- ul.cme-listhoriz li {
59
- list-style: none;
60
- float: left;
61
- margin: 0;
62
- }
63
-
64
-
65
- div.cme-listhoriz h3 {
66
- margin: 0.2em;
67
- }
68
-
69
- div.cme-cap-type-tables {
70
- border: 1px solid black;
71
- }
72
-
73
- /*
74
- table.cme-typecaps {
75
-
76
- }
77
- */
78
-
79
- table .cme-typecaps td:first-of-type {
80
- text-align: left;
81
- }
82
-
83
- table .cme-typecaps td {
84
- text-align: center;
85
- height: 2em;
86
- }
87
-
88
- table .cme-typecaps th:first-of-type {
89
- width: 160px;
90
- }
91
-
92
- table .cme-typecaps th {
93
- cursor: pointer;
94
- text-align: center;
95
- }
96
-
97
- table.cme-typecaps span.cap-x {
98
- display: none;
99
- cursor: pointer;
100
- }
101
-
102
- table.cme-checklist span.cap-x {
103
- cursor: pointer;
104
- }
105
-
106
- table.cme-checklist tr td input[type="checkbox"] {
107
- margin-right: 10px !important;
108
- }
109
-
110
- h3.cme-cap-section {
111
- margin-top:0;
112
- }
113
-
114
- a.neg-cap, a.cap-on, a.type-on, a.neg-type-caps, a.cme-neg-all {
115
- text-decoration: none;
116
- }
117
-
118
- span.cap-x, a.cme-neg-all {
119
- color: red;
120
- font-size: 1.5em;
121
- padding-left: 1px;
122
- padding-right: 1px;
123
- vertical-align: middle;
124
- }
125
-
126
- a.cme-switch-all {
127
- color: black;
128
- font-size: 1.5em;
129
- padding-right: 1px;
130
- padding-right: 1px;
131
- vertical-align: middle;
132
- text-decoration: line-through !important;
133
- }
134
-
135
- td.cap-yes span {
136
- color:green;font-weight:bold;
137
- }
138
-
139
- td.cap-no {
140
- color:#777;
141
- }
142
-
143
- td.cap-neg label span {
144
- color: red;
145
- }
146
-
147
- td.cap-neg input {
148
- display:none;
149
- }
150
-
151
- td.cap-no span.cap-x, td.cap-yes span.cap-x {
152
- display:none;
153
- }
154
-
155
- td.cap-neg span.cap-x {
156
- display:inline;
157
- }
158
-
159
- td.cap-neg a.neg-cap {
160
- display:none;
161
- }
162
-
163
- td.cap-metagroup label span {
164
- color: #080 !important;
165
- }
166
-
167
- td.cap-locked a.neg-cap {
168
- display: none !important;
169
- }
170
-
171
- tr.cme-bulk-select td {
172
- padding-top: 8px;
173
- padding-bottom: 8px;
174
- color: black;
175
- -webkit-user-select: none;
176
- -moz-user-select: none;
177
- -ms-user-select: none;
178
- user-select: none;
179
- }
180
-
181
- tr.cme-bulk-select span {
182
- vertical-align: bottom;
183
- }
184
-
185
- a.type-off, a.neg-cap, a.cme-neg-all, a.neg-type-caps {
186
- color: #800;
187
- }
188
-
189
- a.type-on, a.cap-on, a.cme-switch-all {
190
- color: black;
191
- }
192
-
193
- input.cme-check-all, a.cme-neg-all {
194
- margin-right: 10px;
195
- padding-right: 10px;
196
- }
197
-
198
- #akmin input.button {
199
- margin-top: 5px;
200
- }
201
-
202
- #akmin input.button-primary {
203
- margin: 0;
204
- }
205
-
206
- #akmin td.sidebar {
207
- width: 300px;
208
- }
209
-
210
- #akmin .cme-backup-tool a {
211
- padding-left:0;
212
- }
213
-
214
- #akmin input.regular-text {
215
- width: 200px;
216
- }
217
-
218
- #akmin input.tight-text {
219
- width: 125px;
220
- }
221
-
222
- .cme-subtext {
223
- color: #686868;
224
- font-style: italic;
225
- margin-top:5px;
226
- }
227
-
228
- td.cm-has-via-pp {
229
- background-color: #84fb84;
230
- }
231
-
232
- div.pressshack-admin-wrapper footer {
233
- padding-right: 5px;
234
- }
235
-
236
- #akmin div.publishpress-headline {
237
- line-height:25px;
238
- }
239
-
240
- #akmin div.publishpress-filters {
241
- margin-bottom: 20px; margin-top: 10px;
242
- }
243
-
244
- #akmin span.publishpress-thanks{
245
- margin-left:5px;
246
- color:#655997;
247
- white-space:nowrap;
248
- }
249
-
250
- #akmin span.publishpress-thanks,#akmin span.publishpress-thanks a,#akmin span.publishpress-thanks a:visited {
251
- color:#655997;
252
- font-weight:bold;
253
- }
254
-
255
- table#akmin td li.publishpress-contact{
256
- text-align:center;
257
- }
258
-
259
- table#akmin td li.publishpress-contact a{
260
- padding:5px 0 5px 0;
261
- }
262
-
263
- #pp_features {
264
- display:none;
265
- border:1px solid #eee;
266
- padding:5px;
267
- text-align:center;
268
- min-width:600px;
269
- }
270
-
271
- #pp_features div.pp-logo {
272
- text-align: center;
273
- }
274
-
275
- #pp_features div.features-wrap {
276
- margin-left: auto;
277
- margin-right: auto;
278
- text-align: center;
279
- width: 600px;
280
- }
281
-
282
- #pp_features ul.pp-features {
283
- list-style: none;
284
- padding-top:10px;
285
- text-align:left;
286
- margin-left: auto;
287
- }
288
-
289
- #pp_features ul.pp-features li:before {
290
- content: "\2713\0020";
291
- }
292
-
293
- #pp_features ul.pp-features li {
294
- padding-bottom: 5px;
295
- }
296
-
297
- #pp_features img.cme-play {
298
- margin-bottom: -3px;
299
- margin-left: 5px;
300
- }
301
-
302
- div.publishpress-caps-manage span.manage-members {
303
- margin-left:5px;
304
- font-weight:normal;
305
- color: #777;
306
- }
307
-
308
- div.publishpress-caps-manage span.manage-members a {
309
- color: #777;
310
- }
311
-
312
- div.publishpress-caps-manage span.manage-members a:hover {
313
- text-decoration: underline;
314
- color:#655997;
315
- }
316
-
317
- div.publishpress-headline .cme-subtext a {
318
- font-weight: bold;
319
- }
320
-
321
- div.publishpress-headline .cme-subtext a:hover {
322
- text-decoration: underline;
323
- }
324
-
325
- div.publishpress-caps-backup th {
326
- text-align:right;
327
- padding-top:28px;
328
- width: 140px;
329
- }
330
-
331
- div.publishpress-caps-backup p.description {max-width:620px !important;}
332
-
333
- div.publishpress-caps-backup #cme_select_restore_div {height:250px;}
334
- div.publishpress-caps-backup #cme_select_restore {
335
- list-style:none;
336
- max-height:250px;
337
- margin:0;
338
- overflow:auto;
339
- padding:0;
340
- background-color: #eee;
341
- padding: 5px;
342
- text-indent:10px;
343
- }
344
- div.publishpress-caps-backup #cme_select_restore li {
345
- padding: 7px 15px 7px 7px;
346
- background-color: #f4f4f4;
347
- margin: 0;
348
- line-height:25px;
349
- }
350
-
351
- div.publishpress-caps-backup #cme_select_restore li label {
352
- font-size: 13px;
353
- }
354
-
355
- div.publishpress-caps-backup #cme_select_restore li:nth-child(even){
356
- background-color:white;
357
- }
358
-
359
- div.cme-selected-backup-caption {
360
- padding-left: 5px;
361
- }
362
-
363
- div.pp-caps-backup-button {
364
- margin-top: 10px;
365
- }
366
-
367
- div.cme-restore-button {
368
- margin-top: 25px;
369
- padding-left: 5px;
370
- }
371
-
372
- div.publishpress-caps-backup td.cme-backup-info{
373
- padding:0;
374
- }
375
-
376
- div.cme-show-backup {
377
- padding-left:20px;
378
- }
379
-
380
- div.publishpress-caps-backup td.cme-backup-info li {
381
- display:none;
382
- }
383
-
384
- div.publishpress-caps-backup td.cme-backup-info li.cme-change {
385
- display: list-item;
386
- }
387
-
388
- div.publishpress-caps-backup td.cme-backup-info .cme-plus {
389
- font-weight: bold;
390
- color: green;
391
- }
392
-
393
- .cme-backup-info ul.pp-restore-caps {
394
- display: inline-block;
395
- }
396
-
397
- ul.pp-restore-caps li {
398
- margin-left: 20px;
399
- }
400
-
401
- span.pp-restore-caps-no-change {
402
- font-style: italic;
403
- padding-left : 20px;
404
- }
405
-
406
- div.publishpress-caps-backup td.cme-backup-info .cme-minus {
407
- font-weight: bold;
408
- color: #a00;
409
- text-decoration: line-through;
410
- }
411
-
412
- div.publishpress-caps-backup td.cme-backup-info .cme-negate {
413
- font-weight: bold;
414
- background-color: #a00;
415
- color: white;
416
- text-decoration: line-through;
417
- }
418
-
419
- .cme-backup-info ul.toplevel_page_pp-capabilities {
420
- display: inline-block;
421
- padding-left:30px;
422
- }
423
-
424
- .restrict-column input[type=checkbox]:checked:focus {
425
- border-color: crimson;
426
- box-shadow: 0 0 0 1px crimson;
427
- }
428
-
429
- .restrict-column input[type=checkbox]:checked::before {
430
- content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiIHZpZXdCb3g9IjAgMCAyMCAyMCIgc3R5bGU9Ii1tcy10cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7IHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7Ij48cGF0aCBkPSJNMTQuOTUgNi40NkwxMS40MSAxMGwzLjU0IDMuNTRsLTEuNDEgMS40MUwxMCAxMS40MmwtMy41MyAzLjUzbC0xLjQyLTEuNDJMOC41OCAxMEw1LjA1IDYuNDdsMS40Mi0xLjQyTDEwIDguNThsMy41NC0zLjUzeiIgZmlsbD0iI2RjMTQzYyIvPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0icmdiYSgwLCAwLCAwLCAwKSIgLz48L3N2Zz4=");
431
- }
432
-
433
- #ppcb-tab-reset p {
434
- text-align:center;
435
- }
436
-
437
- .publishpress-caps-backup span.pp-caps-warning {
438
- color:red;
439
- }
440
-
441
- table#akmin tr td input[type=checkbox] {
442
- margin: 0;
443
- }
444
-
445
-
446
- .pp-capability-menus {
447
- width: 100%;
448
- overflow: hidden;
449
- background: #fff;
450
- background: linear-gradient(90deg, #fafafa 0%, #fafafa 20%, #fff 20%, #fff 100%);
451
- }
452
-
453
- .pp-capability-menus .pp-capability-menus-wrap {
454
- float: left;
455
- width: 100%;
456
- margin-left: -1px;
457
- margin-right: 20px;
458
- }
459
-
460
-
461
- #pp-capability-menu-wrapper table {
462
- border-right: none;
463
- border-top: none;
464
- border-bottom: none;
465
- }
466
-
467
- #pp-capability-menu-wrapper table td,
468
- #pp-capability-menu-wrapper table th {
469
- padding: 10px;
470
- padding-bottom: 10px;
471
- font-size: 13px;
472
- line-height: 20px;
473
- }
474
-
475
- #pp-capability-menu-wrapper table td h4.ppc-menu-row-section {
476
- margin-bottom: 0;
477
- }
478
-
479
- #pp-capability-menu-wrapper table td {
480
- padding: 9px;
481
- }
482
-
483
- #pp-capability-menu-wrapper tbody tr:last-of-type td {
484
- border-bottom: none;
485
- }
486
-
487
- #pp-capability-menu-wrapper tfoot th {
488
- border-color: #eee;
489
- }
490
-
491
-
492
- table#akmin .pp-capability-menus-select .restrict-column {
493
- min-width: 90px;
494
- text-align: center;
495
- display: table-cell !important;
496
- clear: none !important;
497
- }
498
-
499
- .pp-capability-menus .menu-item-link {
500
- display: inline;
501
- color: #0073aa;
502
- margin: -4px;
503
- line-height: inherit;
504
- padding: 4px 8px;
505
- border: 1px solid transparent;
506
- background: transparent;
507
- border-radius: 0;
508
- outline: none;
509
- -webkit-transition: all 0.25s ease-out;
510
- -moz-transition: all 0.25s ease-out;
511
- -o-transition: all 0.25s ease-out;
512
- transition: all 0.25s ease-out;
513
- }
514
-
515
- .pp-capability-menus .menu-item-link:hover,
516
- .pp-capability-menus .menu-item-link:focus {
517
- border-color: #eee;
518
- background: #fafafa;
519
- cursor: pointer;
520
- }
521
-
522
- .pp-capability-menus .menu-item-link:active {
523
- color: #0073aa;
524
- border-color: #0073aa;
525
- }
526
-
527
- .pp-capability-menus .check-all-menu-link,
528
- .pp-capability-menus .check-all-menu-link:active {
529
- color: #555;
530
- }
531
-
532
- .pp-capability-menus .menu-item-link.restricted,
533
- .pp-capability-menus .menu-item-link.restricted:active {
534
- color: crimson;
535
- }
536
-
537
- .pp-capability-menus .menu-item-link.disabled,
538
- .pp-capability-menus .menu-item-link.disabled:active {
539
- color: #555;
540
- }
541
-
542
- .pp-capability-menus .menu-item-link + .dashicons {
543
- display: none;
544
- margin-top: 1px;
545
- margin-bottom: -1px;
546
- line-height: inherit;
547
- }
548
-
549
- .pp-capability-menus .menu-item-link:hover + .dashicons,
550
- .pp-capability-menus .menu-item-link:focus + .dashicons {
551
- display: inline-block;
552
- }
553
-
554
- .pp-capability-menus-wrapper .button-primary {
555
- margin-bottom: 25px !important;
556
- }
557
-
558
-
559
- .pp-capability-menus-wrapper .tooltip {
560
- position: relative;
561
- display: inline-block;
562
- border-bottom: 1px dotted black;
563
- }
564
-
565
- .pp-capability-menus-wrapper .tooltip .tooltiptext {
566
- visibility: hidden;
567
- width: 120px;
568
- background-color: black;
569
- color: #fff;
570
- text-align: center;
571
- padding: 5px 0;
572
- border-radius: 6px;
573
-
574
- position: absolute;
575
- z-index: 1;
576
- }
577
-
578
- .pp-capability-menus-wrapper .tooltip:hover .tooltiptext {
579
- visibility: visible;
580
- }
581
-
582
- .capabilities_page_pp-capabilities-admin-menus input.ppc-admin-menu-submit,
583
- .capabilities_page_pp-capabilities-nav-menus input.ppc-nav-menu-submit {
584
- margin-bottom: 10px !important;
585
- }
586
-
587
- .pp-capability-menus-wrapper .features-section-header {
588
- padding-left: 10px !important;
589
- }
590
-
591
-
592
- body.capabilities_page_pp-capabilities-admin-features .pp-capability-menus-select .restrict-column {
593
- width: 70px !important;
594
- }
595
-
596
- .pp-column-right.capabilities-sidebar .button.button-primary {
597
- color: #2271b1;
598
- border-color: #2271b1;
599
- background: #f6f7f7;
600
- }
601
-
602
- /* Roles screen */
603
-
604
- .roles-capabilities-title {
605
- font-weight: bold !important;
606
- padding-left: 0 !important;
607
- }
608
- .pp-role-edit-wrap #publishing-action {
609
- text-align: unset !important;
610
- float: unset !important;
611
- }
612
-
613
- .pp-roles-delete-botton {
614
- color: red !important;
615
- border-color: red !important;
616
- }
617
-
618
- .ppc-roles-section {
619
- min-height: 370px;
620
- }
621
-
622
- #poststuff .ppc-roles-section.postbox .inside {
623
- margin-left: 0 !important;
624
- margin-top: 0 !important;
625
- padding-left: 0 !important;
626
- }
627
-
628
- .ppc-roles-section input[type=text],
629
- .ppc-roles-section input[type=number],
630
- .ppc-roles-section select {
631
- width: 300px;
632
- }
633
-
634
- .ppc-roles-section #poststuff {
635
- min-height: 600px;
636
- }
637
-
638
- ul.ppc-roles-tab {
639
- margin: 0;
640
- width: 20%;
641
- float: left;
642
- line-height: 1em;
643
- padding: 0 0 10px;
644
- position: relative;
645
- background-color: #fafafa;
646
- border-right: 1px solid #eee;
647
- box-sizing: border-box;
648
- min-height: 363px;
649
- }
650
- .ppc-roles-tab-content {
651
- float: left;
652
- width: 80%;
653
- min-height: 275px;
654
- box-sizing: border-box;
655
- padding-left: 10px;
656
- }
657
-
658
-
659
- ul.ppc-roles-tab li {
660
- margin: 0;
661
- padding: 0;
662
- display: block;
663
- position: relative;
664
- }
665
- ul.ppc-roles-tab li a {
666
- margin: 0;
667
- padding: 10px;
668
- display: block;
669
- box-shadow: none;
670
- text-decoration: none;
671
- line-height: 20px!important;
672
- border-bottom: 1px solid #eee;
673
- }
674
-
675
- ul.ppc-roles-tab li a span {
676
- margin-right: .618em;
677
- }
678
-
679
- ul.ppc-roles-tab li a span.dashicons {
680
- margin-left: 0;
681
- font-size: 15px;
682
- }
683
- ul.ppc-roles-tab li.active a {
684
- color: #555;
685
- position: relative;
686
- background-color: #eee;
687
- }
688
-
689
- .ppc-roles-sidebar ul.pp-roles-capabilities li {
690
- margin-bottom: 0;
691
- }
692
-
693
- .ppc-roles-sidebar ul.pp-roles-capabilities li::before {
694
- font-family: Dashicons;
695
- font-weight: 400;
696
- text-transform: none;
697
- line-height: 1;
698
- -webkit-font-smoothing: antialiased;
699
- content: "\f12a";
700
- font-variant: normal;
701
- text-decoration: none;
702
- color: green;
703
- }
704
- .roles-capabilities-load-more,
705
- .roles-capabilities-load-less {
706
- cursor: pointer;
707
- color: #2271b1;
708
- text-decoration: underline;
709
- }
710
-
711
- .ppc-roles-section .red-warning {
712
- color: red;
713
- font-weight: bold;
714
- }
715
-
716
- /* Filters */
717
- .ppc-filter-wrapper {
718
- float: right;
719
- margin-bottom: 15px;
720
- display: flex;
721
- }
722
-
723
- .ppc-filter-wrapper .button {
724
- margin-left: 5px;
725
- }
726
-
727
- .ppc-filter-no-results {
728
- margin-top: 20px;
729
- }
730
-
731
- /* ====================================================== Main Screen */
732
-
733
- #ppc-capabilities-wrapper {
734
- display: grid;
735
- grid-template-columns: 1fr 4fr;
736
- min-height: 400px;
737
- }
738
-
739
- /*
740
- #ppc-capabilities-wrapper .ppc-capabilities-tabs {
741
-
742
- }
743
- */
744
-
745
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul {
746
- padding: 0;
747
- margin: 0;
748
- display: block;
749
- }
750
-
751
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li {
752
- margin: 0;
753
- padding: 15px 12px;
754
- background: #f0f0f1;
755
- cursor: pointer;
756
- border-bottom: 1px solid #ccc;
757
- border-right: 1px solid #ccc;
758
- font-size: 1.1em;
759
- line-height: 1.3em;
760
- }
761
-
762
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li:last-child {
763
- margin-bottom: 20px;
764
- }
765
-
766
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li.ppc-capabilities-tab-active {
767
- background: #fff;
768
- border-right-color: #fff;
769
- }
770
-
771
- #ppc-capabilities-wrapper .ppc-capabilities-content > div {
772
- padding: 20px;
773
- }
774
-
775
- #ppc-capabilities-wrapper .ppc-capabilities-content > div > h3 {
776
- margin-top: 0;
777
- display: inline-block;
778
- }
779
-
780
- #publishpress_caps_form table#akmin td .pp-sidebar-box p:not(:last-of-type) {
781
- margin: 15px 0;
782
- padding: 0;
783
- }
784
-
785
- @media (max-width: 1199px) {
786
-
787
- #ppc-capabilities-wrapper {
788
- display: block;
789
- }
790
-
791
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li,
792
- #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li.ppc-capabilities-tab-active {
793
- border-right: none;
794
- }
795
-
796
- #publishpress_caps_form #akmin td.content,
797
- #publishpress_caps_form #akmin td.sidebar {
798
- display: block;
799
- padding: 0;
800
- }
801
-
802
- #publishpress_caps_form #akmin td.content {
803
- margin-bottom: 40px;
804
- }
805
- }
806
-
807
- @media (max-width: 1184px) {
808
-
809
- /* Filters */
810
- .ppc-filter-wrapper {
811
- float: none;
812
- margin-bottom: 25px;
813
- }
814
- }
815
-
816
- @media (max-width: 782px) {
817
-
818
- table.cme-checklist.form-table tr td {
819
- padding: 15px 10px;
820
- }
821
-
822
- table .cme-typecaps th:first-of-type {
823
- width: 110px;
824
- }
825
-
826
- .pp-capability-menus {
827
- background: linear-gradient(90deg, #fafafa 0%, #fafafa 48px, #fff 48px, #fff 100%);
828
- }
829
-
830
- #pp-capability-menu-wrapper table td,
831
- #pp-capability-menu-wrapper table th {
832
- line-height: 24px;
833
- }
834
-
835
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Settings for admin dashboard.
3
+ * Based on the styles for Maintenance Mode plugin by Michael Wöhrer
4
+ *
5
+ * @version $Rev: 198515 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage CapsMan
12
+ *
13
+
14
+ Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ version 2 as published by the Free Software Foundation.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+
29
+
30
+ /* ====================================================== SIDEBAR ICONS */
31
+
32
+ a.cap_type {
33
+ text-decoration: none;
34
+ }
35
+
36
+ a.cap_type:hover {
37
+ text-decoration: underline;
38
+ }
39
+
40
+ ul.cme-listhoriz li {
41
+ text-align: center;
42
+ padding-right: 1em;
43
+ }
44
+
45
+ ul.cme-listhoriz li table{
46
+ text-align: center;
47
+ }
48
+
49
+
50
+ ul.cme-listhoriz {
51
+ width: 100%;
52
+ clear: both;
53
+ float: left;
54
+ margin: 0;
55
+ padding: 0;
56
+ }
57
+
58
+ ul.cme-listhoriz li {
59
+ list-style: none;
60
+ float: left;
61
+ margin: 0;
62
+ }
63
+
64
+
65
+ div.cme-listhoriz h3 {
66
+ margin: 0.2em;
67
+ }
68
+
69
+ div.cme-cap-type-tables {
70
+ border: 1px solid black;
71
+ }
72
+
73
+ /*
74
+ table.cme-typecaps {
75
+
76
+ }
77
+ */
78
+
79
+ table .cme-typecaps td:first-of-type {
80
+ text-align: left;
81
+ }
82
+
83
+ table .cme-typecaps td {
84
+ text-align: center;
85
+ height: 2em;
86
+ }
87
+
88
+ table .cme-typecaps th:first-of-type {
89
+ width: 160px;
90
+ }
91
+
92
+ table .cme-typecaps th {
93
+ cursor: pointer;
94
+ text-align: center;
95
+ }
96
+
97
+ table.cme-typecaps span.cap-x {
98
+ display: none;
99
+ cursor: pointer;
100
+ }
101
+
102
+ table.cme-checklist span.cap-x {
103
+ cursor: pointer;
104
+ }
105
+
106
+ table.cme-checklist tr td input[type="checkbox"] {
107
+ margin-right: 10px !important;
108
+ }
109
+
110
+ h3.cme-cap-section {
111
+ margin-top:0;
112
+ }
113
+
114
+ a.neg-cap, a.cap-on, a.type-on, a.neg-type-caps, a.cme-neg-all {
115
+ text-decoration: none;
116
+ }
117
+
118
+ span.cap-x, a.cme-neg-all {
119
+ color: red;
120
+ font-size: 1.5em;
121
+ padding-left: 1px;
122
+ padding-right: 1px;
123
+ vertical-align: middle;
124
+ }
125
+
126
+ a.cme-switch-all {
127
+ color: black;
128
+ font-size: 1.5em;
129
+ padding-right: 1px;
130
+ padding-right: 1px;
131
+ vertical-align: middle;
132
+ text-decoration: line-through !important;
133
+ }
134
+
135
+ td.cap-yes span {
136
+ color:green;font-weight:bold;
137
+ }
138
+
139
+ td.cap-no {
140
+ color:#777;
141
+ }
142
+
143
+ td.cap-neg label span {
144
+ color: red;
145
+ }
146
+
147
+ td.cap-neg input {
148
+ display:none;
149
+ }
150
+
151
+ td.cap-no span.cap-x, td.cap-yes span.cap-x {
152
+ display:none;
153
+ }
154
+
155
+ td.cap-neg span.cap-x {
156
+ display:inline;
157
+ }
158
+
159
+ td.cap-neg a.neg-cap {
160
+ display:none;
161
+ }
162
+
163
+ td.cap-metagroup label span {
164
+ color: #080 !important;
165
+ }
166
+
167
+ td.cap-locked a.neg-cap {
168
+ display: none !important;
169
+ }
170
+
171
+ tr.cme-bulk-select td {
172
+ padding-top: 8px;
173
+ padding-bottom: 8px;
174
+ color: black;
175
+ -webkit-user-select: none;
176
+ -moz-user-select: none;
177
+ -ms-user-select: none;
178
+ user-select: none;
179
+ }
180
+
181
+ tr.cme-bulk-select span {
182
+ vertical-align: bottom;
183
+ }
184
+
185
+ a.type-off, a.neg-cap, a.cme-neg-all, a.neg-type-caps {
186
+ color: #800;
187
+ }
188
+
189
+ a.type-on, a.cap-on, a.cme-switch-all {
190
+ color: black;
191
+ }
192
+
193
+ input.cme-check-all, a.cme-neg-all {
194
+ margin-right: 10px;
195
+ padding-right: 10px;
196
+ }
197
+
198
+ #akmin input.button {
199
+ margin-top: 5px;
200
+ }
201
+
202
+ #akmin input.button-primary {
203
+ margin: 0;
204
+ }
205
+
206
+ #akmin td.sidebar {
207
+ width: 300px;
208
+ }
209
+
210
+ #akmin .cme-backup-tool a {
211
+ padding-left:0;
212
+ }
213
+
214
+ #akmin input.regular-text {
215
+ width: 200px;
216
+ }
217
+
218
+ #akmin input.tight-text {
219
+ width: 125px;
220
+ }
221
+
222
+ .cme-subtext {
223
+ color: #686868;
224
+ font-style: italic;
225
+ margin-top:5px;
226
+ }
227
+
228
+ td.cm-has-via-pp {
229
+ background-color: #84fb84;
230
+ }
231
+
232
+ div.pressshack-admin-wrapper footer {
233
+ padding-right: 5px;
234
+ }
235
+
236
+ #akmin div.publishpress-headline {
237
+ line-height:25px;
238
+ }
239
+
240
+ #akmin div.publishpress-filters {
241
+ margin-bottom: 20px; margin-top: 10px;
242
+ }
243
+
244
+ #akmin span.publishpress-thanks{
245
+ margin-left:5px;
246
+ color:#655997;
247
+ white-space:nowrap;
248
+ }
249
+
250
+ #akmin span.publishpress-thanks,#akmin span.publishpress-thanks a,#akmin span.publishpress-thanks a:visited {
251
+ color:#655997;
252
+ font-weight:bold;
253
+ }
254
+
255
+ table#akmin td li.publishpress-contact{
256
+ text-align:center;
257
+ }
258
+
259
+ table#akmin td li.publishpress-contact a{
260
+ padding:5px 0 5px 0;
261
+ }
262
+
263
+ #pp_features {
264
+ display:none;
265
+ border:1px solid #eee;
266
+ padding:5px;
267
+ text-align:center;
268
+ min-width:600px;
269
+ }
270
+
271
+ #pp_features div.pp-logo {
272
+ text-align: center;
273
+ }
274
+
275
+ #pp_features div.features-wrap {
276
+ margin-left: auto;
277
+ margin-right: auto;
278
+ text-align: center;
279
+ width: 600px;
280
+ }
281
+
282
+ #pp_features ul.pp-features {
283
+ list-style: none;
284
+ padding-top:10px;
285
+ text-align:left;
286
+ margin-left: auto;
287
+ }
288
+
289
+ #pp_features ul.pp-features li:before {
290
+ content: "\2713\0020";
291
+ }
292
+
293
+ #pp_features ul.pp-features li {
294
+ padding-bottom: 5px;
295
+ }
296
+
297
+ #pp_features img.cme-play {
298
+ margin-bottom: -3px;
299
+ margin-left: 5px;
300
+ }
301
+
302
+ div.publishpress-caps-manage span.manage-members {
303
+ margin-left:5px;
304
+ font-weight:normal;
305
+ color: #777;
306
+ }
307
+
308
+ div.publishpress-caps-manage span.manage-members a {
309
+ color: #777;
310
+ }
311
+
312
+ div.publishpress-caps-manage span.manage-members a:hover {
313
+ text-decoration: underline;
314
+ color:#655997;
315
+ }
316
+
317
+ div.publishpress-headline .cme-subtext a {
318
+ font-weight: bold;
319
+ }
320
+
321
+ div.publishpress-headline .cme-subtext a:hover {
322
+ text-decoration: underline;
323
+ }
324
+
325
+ div.publishpress-caps-backup th {
326
+ text-align:right;
327
+ padding-top:28px;
328
+ width: 140px;
329
+ }
330
+
331
+ div.publishpress-caps-backup p.description {max-width:620px !important;}
332
+
333
+ div.publishpress-caps-backup #cme_select_restore_div {height:250px;}
334
+ div.publishpress-caps-backup #cme_select_restore {
335
+ list-style:none;
336
+ max-height:250px;
337
+ margin:0;
338
+ overflow:auto;
339
+ padding:0;
340
+ background-color: #eee;
341
+ padding: 5px;
342
+ text-indent:10px;
343
+ }
344
+ div.publishpress-caps-backup #cme_select_restore li {
345
+ padding: 7px 15px 7px 7px;
346
+ background-color: #f4f4f4;
347
+ margin: 0;
348
+ line-height:25px;
349
+ }
350
+
351
+ div.publishpress-caps-backup #cme_select_restore li label {
352
+ font-size: 13px;
353
+ }
354
+
355
+ div.publishpress-caps-backup #cme_select_restore li:nth-child(even){
356
+ background-color:white;
357
+ }
358
+
359
+ div.cme-selected-backup-caption {
360
+ padding-left: 5px;
361
+ }
362
+
363
+ div.pp-caps-backup-button {
364
+ margin-top: 10px;
365
+ }
366
+
367
+ div.cme-restore-button {
368
+ margin-top: 25px;
369
+ padding-left: 5px;
370
+ }
371
+
372
+ div.publishpress-caps-backup td.cme-backup-info{
373
+ padding:0;
374
+ }
375
+
376
+ div.cme-show-backup {
377
+ padding-left:20px;
378
+ }
379
+
380
+ div.publishpress-caps-backup td.cme-backup-info li {
381
+ display:none;
382
+ }
383
+
384
+ div.publishpress-caps-backup td.cme-backup-info li.cme-change {
385
+ display: list-item;
386
+ }
387
+
388
+ div.publishpress-caps-backup td.cme-backup-info .cme-plus {
389
+ font-weight: bold;
390
+ color: green;
391
+ }
392
+
393
+ .cme-backup-info ul.pp-restore-caps {
394
+ display: inline-block;
395
+ }
396
+
397
+ ul.pp-restore-caps li {
398
+ margin-left: 20px;
399
+ }
400
+
401
+ span.pp-restore-caps-no-change {
402
+ font-style: italic;
403
+ padding-left : 20px;
404
+ }
405
+
406
+ div.publishpress-caps-backup td.cme-backup-info .cme-minus {
407
+ font-weight: bold;
408
+ color: #a00;
409
+ text-decoration: line-through;
410
+ }
411
+
412
+ div.publishpress-caps-backup td.cme-backup-info .cme-negate {
413
+ font-weight: bold;
414
+ background-color: #a00;
415
+ color: white;
416
+ text-decoration: line-through;
417
+ }
418
+
419
+ .cme-backup-info ul.toplevel_page_pp-capabilities {
420
+ display: inline-block;
421
+ padding-left:30px;
422
+ }
423
+
424
+ .restrict-column input[type=checkbox]:checked:focus {
425
+ border-color: crimson;
426
+ box-shadow: 0 0 0 1px crimson;
427
+ }
428
+
429
+ .restrict-column input[type=checkbox]:checked::before {
430
+ content: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiIHZpZXdCb3g9IjAgMCAyMCAyMCIgc3R5bGU9Ii1tcy10cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7IHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7Ij48cGF0aCBkPSJNMTQuOTUgNi40NkwxMS40MSAxMGwzLjU0IDMuNTRsLTEuNDEgMS40MUwxMCAxMS40MmwtMy41MyAzLjUzbC0xLjQyLTEuNDJMOC41OCAxMEw1LjA1IDYuNDdsMS40Mi0xLjQyTDEwIDguNThsMy41NC0zLjUzeiIgZmlsbD0iI2RjMTQzYyIvPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0icmdiYSgwLCAwLCAwLCAwKSIgLz48L3N2Zz4=");
431
+ }
432
+
433
+ #ppcb-tab-reset p {
434
+ text-align:center;
435
+ }
436
+
437
+ .publishpress-caps-backup span.pp-caps-warning {
438
+ color:red;
439
+ }
440
+
441
+ table#akmin tr td input[type=checkbox] {
442
+ margin: 0;
443
+ }
444
+
445
+
446
+ .pp-capability-menus {
447
+ width: 100%;
448
+ overflow: hidden;
449
+ background: #fff;
450
+ background: linear-gradient(90deg, #fafafa 0%, #fafafa 20%, #fff 20%, #fff 100%);
451
+ }
452
+
453
+ .pp-capability-menus .pp-capability-menus-wrap {
454
+ float: left;
455
+ width: 100%;
456
+ margin-left: -1px;
457
+ margin-right: 20px;
458
+ }
459
+
460
+
461
+ #pp-capability-menu-wrapper table {
462
+ border-right: none;
463
+ border-top: none;
464
+ border-bottom: none;
465
+ }
466
+
467
+ #pp-capability-menu-wrapper table td,
468
+ #pp-capability-menu-wrapper table th {
469
+ padding: 10px;
470
+ padding-bottom: 10px;
471
+ font-size: 13px;
472
+ line-height: 20px;
473
+ }
474
+
475
+ #pp-capability-menu-wrapper table td h4.ppc-menu-row-section {
476
+ margin-bottom: 0;
477
+ }
478
+
479
+ #pp-capability-menu-wrapper table td {
480
+ padding: 9px;
481
+ }
482
+
483
+ #pp-capability-menu-wrapper tbody tr:last-of-type td {
484
+ border-bottom: none;
485
+ }
486
+
487
+ #pp-capability-menu-wrapper tfoot th {
488
+ border-color: #eee;
489
+ }
490
+
491
+
492
+ table#akmin .pp-capability-menus-select .restrict-column {
493
+ min-width: 90px;
494
+ text-align: center;
495
+ display: table-cell !important;
496
+ clear: none !important;
497
+ }
498
+
499
+ .pp-capability-menus .menu-item-link {
500
+ display: inline;
501
+ color: #0073aa;
502
+ margin: -4px;
503
+ line-height: inherit;
504
+ padding: 4px 8px;
505
+ border: 1px solid transparent;
506
+ background: transparent;
507
+ border-radius: 0;
508
+ outline: none;
509
+ -webkit-transition: all 0.25s ease-out;
510
+ -moz-transition: all 0.25s ease-out;
511
+ -o-transition: all 0.25s ease-out;
512
+ transition: all 0.25s ease-out;
513
+ }
514
+
515
+ .pp-capability-menus .menu-item-link:hover,
516
+ .pp-capability-menus .menu-item-link:focus {
517
+ border-color: #eee;
518
+ background: #fafafa;
519
+ cursor: pointer;
520
+ }
521
+
522
+ .pp-capability-menus .menu-item-link:active {
523
+ color: #0073aa;
524
+ border-color: #0073aa;
525
+ }
526
+
527
+ .pp-capability-menus .check-all-menu-link,
528
+ .pp-capability-menus .check-all-menu-link:active {
529
+ color: #555;
530
+ }
531
+
532
+ .pp-capability-menus .menu-item-link.restricted,
533
+ .pp-capability-menus .menu-item-link.restricted:active {
534
+ color: crimson;
535
+ }
536
+
537
+ .pp-capability-menus .menu-item-link.disabled,
538
+ .pp-capability-menus .menu-item-link.disabled:active {
539
+ color: #555;
540
+ }
541
+
542
+ .pp-capability-menus .menu-item-link + .dashicons {
543
+ display: none;
544
+ margin-top: 1px;
545
+ margin-bottom: -1px;
546
+ line-height: inherit;
547
+ }
548
+
549
+ .pp-capability-menus .menu-item-link:hover + .dashicons,
550
+ .pp-capability-menus .menu-item-link:focus + .dashicons {
551
+ display: inline-block;
552
+ }
553
+
554
+ .pp-capability-menus-wrapper .button-primary {
555
+ margin-bottom: 25px !important;
556
+ }
557
+
558
+
559
+ .pp-capability-menus-wrapper .tooltip {
560
+ position: relative;
561
+ display: inline-block;
562
+ border-bottom: 1px dotted black;
563
+ }
564
+
565
+ .pp-capability-menus-wrapper .tooltip .tooltiptext {
566
+ visibility: hidden;
567
+ width: 120px;
568
+ background-color: black;
569
+ color: #fff;
570
+ text-align: center;
571
+ padding: 5px 0;
572
+ border-radius: 6px;
573
+
574
+ position: absolute;
575
+ z-index: 1;
576
+ }
577
+
578
+ .pp-capability-menus-wrapper .tooltip:hover .tooltiptext {
579
+ visibility: visible;
580
+ }
581
+
582
+ .capabilities_page_pp-capabilities-admin-menus input.ppc-admin-menu-submit,
583
+ .capabilities_page_pp-capabilities-nav-menus input.ppc-nav-menu-submit {
584
+ margin-bottom: 10px !important;
585
+ }
586
+
587
+ .pp-capability-menus-wrapper .features-section-header {
588
+ padding-left: 10px !important;
589
+ }
590
+
591
+
592
+ body.capabilities_page_pp-capabilities-admin-features .pp-capability-menus-select .restrict-column {
593
+ width: 70px !important;
594
+ }
595
+
596
+ .pp-column-right.capabilities-sidebar .button.button-primary {
597
+ color: #2271b1;
598
+ border-color: #2271b1;
599
+ background: #f6f7f7;
600
+ }
601
+
602
+ /* Roles screen */
603
+
604
+ .roles-capabilities-title {
605
+ font-weight: bold !important;
606
+ padding-left: 0 !important;
607
+ }
608
+ .pp-role-edit-wrap #publishing-action {
609
+ text-align: unset !important;
610
+ float: unset !important;
611
+ }
612
+
613
+ .pp-roles-delete-botton {
614
+ color: red !important;
615
+ border-color: red !important;
616
+ }
617
+
618
+ .ppc-roles-section {
619
+ min-height: 370px;
620
+ }
621
+
622
+ #poststuff .ppc-roles-section.postbox .inside {
623
+ margin-left: 0 !important;
624
+ margin-top: 0 !important;
625
+ padding-left: 0 !important;
626
+ }
627
+
628
+ .ppc-roles-section input[type=text],
629
+ .ppc-roles-section input[type=number],
630
+ .ppc-roles-section select {
631
+ width: 300px;
632
+ }
633
+
634
+ .ppc-roles-section #poststuff {
635
+ min-height: 600px;
636
+ }
637
+
638
+ ul.ppc-roles-tab {
639
+ margin: 0;
640
+ width: 20%;
641
+ float: left;
642
+ line-height: 1em;
643
+ padding: 0 0 10px;
644
+ position: relative;
645
+ background-color: #fafafa;
646
+ border-right: 1px solid #eee;
647
+ box-sizing: border-box;
648
+ min-height: 363px;
649
+ }
650
+ .ppc-roles-tab-content {
651
+ float: left;
652
+ width: 80%;
653
+ min-height: 275px;
654
+ box-sizing: border-box;
655
+ padding-left: 10px;
656
+ }
657
+
658
+
659
+ ul.ppc-roles-tab li {
660
+ margin: 0;
661
+ padding: 0;
662
+ display: block;
663
+ position: relative;
664
+ }
665
+ ul.ppc-roles-tab li a {
666
+ margin: 0;
667
+ padding: 10px;
668
+ display: block;
669
+ box-shadow: none;
670
+ text-decoration: none;
671
+ line-height: 20px!important;
672
+ border-bottom: 1px solid #eee;
673
+ }
674
+
675
+ ul.ppc-roles-tab li a span {
676
+ margin-right: .618em;
677
+ }
678
+
679
+ ul.ppc-roles-tab li a span.dashicons {
680
+ margin-left: 0;
681
+ font-size: 15px;
682
+ }
683
+ ul.ppc-roles-tab li.active a {
684
+ color: #555;
685
+ position: relative;
686
+ background-color: #eee;
687
+ }
688
+
689
+ .ppc-roles-sidebar ul.pp-roles-capabilities li {
690
+ margin-bottom: 0;
691
+ }
692
+
693
+ .ppc-roles-sidebar ul.pp-roles-capabilities li::before {
694
+ font-family: Dashicons;
695
+ font-weight: 400;
696
+ text-transform: none;
697
+ line-height: 1;
698
+ -webkit-font-smoothing: antialiased;
699
+ content: "\f12a";
700
+ font-variant: normal;
701
+ text-decoration: none;
702
+ color: green;
703
+ }
704
+ .roles-capabilities-load-more,
705
+ .roles-capabilities-load-less {
706
+ cursor: pointer;
707
+ color: #2271b1;
708
+ text-decoration: underline;
709
+ }
710
+
711
+ .ppc-roles-section .red-warning {
712
+ color: red;
713
+ font-weight: bold;
714
+ }
715
+
716
+ /* Filters */
717
+ .ppc-filter-wrapper {
718
+ float: right;
719
+ margin-bottom: 15px;
720
+ display: flex;
721
+ }
722
+
723
+ .ppc-filter-wrapper .button {
724
+ margin-left: 5px;
725
+ }
726
+
727
+ .ppc-filter-no-results {
728
+ margin-top: 20px;
729
+ }
730
+
731
+ /* ====================================================== Main Screen */
732
+
733
+ #ppc-capabilities-wrapper {
734
+ display: grid;
735
+ grid-template-columns: 1fr 4fr;
736
+ min-height: 400px;
737
+ }
738
+
739
+ /*
740
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs {
741
+
742
+ }
743
+ */
744
+
745
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul {
746
+ padding: 0;
747
+ margin: 0;
748
+ display: block;
749
+ }
750
+
751
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li {
752
+ margin: 0;
753
+ padding: 15px 12px;
754
+ background: #f0f0f1;
755
+ cursor: pointer;
756
+ border-bottom: 1px solid #ccc;
757
+ border-right: 1px solid #ccc;
758
+ font-size: 1.1em;
759
+ line-height: 1.3em;
760
+ }
761
+
762
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li:last-child {
763
+ margin-bottom: 20px;
764
+ }
765
+
766
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li.ppc-capabilities-tab-active {
767
+ background: #fff;
768
+ border-right-color: #fff;
769
+ }
770
+
771
+ #ppc-capabilities-wrapper .ppc-capabilities-content > div {
772
+ padding: 20px;
773
+ }
774
+
775
+ #ppc-capabilities-wrapper .ppc-capabilities-content > div > h3 {
776
+ margin-top: 0;
777
+ display: inline-block;
778
+ }
779
+
780
+ #publishpress_caps_form table#akmin td .pp-sidebar-box p:not(:last-of-type) {
781
+ margin: 15px 0;
782
+ padding: 0;
783
+ }
784
+
785
+ .pp-capabilities-feature-count {
786
+ display: inline-block;
787
+ vertical-align: top;
788
+ box-sizing: border-box;
789
+ margin: 1px 0 -1px 2px;
790
+ padding: 0 7px;
791
+ min-height: 17px;
792
+ border-radius: 9px;
793
+ background-color: #999;
794
+ color: #fff;
795
+ font-size: 11px;
796
+ line-height: 1.6;
797
+ text-align: center;
798
+ z-index: 26;
799
+ float: right;
800
+ }
801
+
802
+ @media (max-width: 1199px) {
803
+
804
+ #ppc-capabilities-wrapper {
805
+ display: block;
806
+ }
807
+
808
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li,
809
+ #ppc-capabilities-wrapper .ppc-capabilities-tabs > ul > li.ppc-capabilities-tab-active {
810
+ border-right: none;
811
+ }
812
+
813
+ #publishpress_caps_form #akmin td.content,
814
+ #publishpress_caps_form #akmin td.sidebar {
815
+ display: block;
816
+ padding: 0;
817
+ }
818
+
819
+ #publishpress_caps_form #akmin td.content {
820
+ margin-bottom: 40px;
821
+ }
822
+ }
823
+
824
+ @media (max-width: 1184px) {
825
+
826
+ /* Filters */
827
+ .ppc-filter-wrapper {
828
+ float: none;
829
+ margin-bottom: 25px;
830
+ }
831
+ }
832
+
833
+ @media (max-width: 782px) {
834
+
835
+ table.cme-checklist.form-table tr td {
836
+ padding: 15px 10px;
837
+ }
838
+
839
+ table .cme-typecaps th:first-of-type {
840
+ width: 110px;
841
+ }
842
+
843
+ .pp-capability-menus {
844
+ background: linear-gradient(90deg, #fafafa 0%, #fafafa 48px, #fff 48px, #fff 100%);
845
+ }
846
+
847
+ #pp-capability-menu-wrapper table td,
848
+ #pp-capability-menu-wrapper table th {
849
+ line-height: 24px;
850
+ }
851
+
852
+ }
common/js/admin.dev.js CHANGED
@@ -1,236 +1,236 @@
1
- jQuery(document).ready( function($) {
2
- $('a.neg-cap').attr('title',cmeAdmin.negationCaption);
3
- $('a.neg-type-caps').attr('title',cmeAdmin.typeCapsNegationCaption);
4
- $('td.cap-unreg').attr('title',cmeAdmin.typeCapUnregistered);
5
- $('a.normal-cap').attr('title',cmeAdmin.switchableCaption);
6
- $('span.cap-x').attr('title',cmeAdmin.capNegated);
7
- $('table.cme-checklist input[class!="cme-check-all"]').not(':disabled').attr('title',cmeAdmin.chkCaption);
8
-
9
- $('table.cme-checklist a.neg-cap').click( function(e) {
10
- $(this).closest('td').removeClass('cap-yes').removeClass('cap-no').addClass('cap-neg');
11
-
12
- var cap_name_attr = $(this).parent().find('input[type="checkbox"]').attr('name');
13
- $(this).after('<input type="hidden" class="cme-negation-input" name="'+cap_name_attr+'" value="" />');
14
-
15
- $('input[name="' + cap_name_attr + '"]').closest('td').removeClass('cap-yes').removeClass('cap-no').addClass('cap-neg');
16
-
17
- return false;
18
- });
19
-
20
- //$('table.cme-typecaps span.cap-x,table.cme-checklist span.cap-x,table.cme-checklist td.cap-neg span').live( 'click', function(e) {
21
- $(document).on( 'click', 'table.cme-typecaps span.cap-x,table.cme-checklist span.cap-x,table.cme-checklist td.cap-neg span', function(e) {
22
- $(this).closest('td').removeClass('cap-neg').removeClass('cap-yes').addClass('cap-no');
23
- $(this).parent().find('input[type="checkbox"]').prop('checked',false);
24
- $(this).parent().find('input.cme-negation-input').remove();
25
-
26
- // Also apply for any other checkboxes with the same name
27
- var cap_name_attr = $(this).next('input[type="checkbox"]').attr('name');
28
-
29
- if (!cap_name_attr) {
30
- cap_name_attr = $(this).next('label').find('input[type="checkbox"]').attr('name');
31
- }
32
-
33
- $('input[name="' + cap_name_attr + '"]').parent().closest('td').removeClass('cap-neg').removeClass('cap-yes').addClass('cap-no');
34
- $('input[name="' + cap_name_attr + '"]').prop('checked',false).parent().find('input.cme-negation-input').remove();
35
-
36
- return false;
37
- });
38
-
39
- $("#publishpress_caps_form").bind("keypress", function(e) {
40
- if (e.keyCode == 13) {
41
- $(document.activeElement).parent().find('input[type="submit"]').first().click();
42
- return false;
43
- }
44
- });
45
-
46
- $('input.cme-check-all').click( function(e) {
47
- $(this).closest('table').find('input[type="checkbox"][disabled!="disabled"]:visible').prop('checked', $(this).is(":checked") );
48
- });
49
-
50
- $('a.cme-neg-all').click( function(e) {
51
- $(this).closest('table').find('a.neg-cap:visible').click();
52
- return false;
53
- });
54
-
55
- $('a.cme-switch-all').click( function(e) {
56
- $(this).closest('table').find('td.cap-neg span').click();
57
- return false;
58
- });
59
-
60
- $('table.cme-typecaps a.neg-type-caps').click( function(e) {
61
- $(this).closest('tr').find('td[class!="cap-neg"]').filter('td[class!="cap-unreg"]').each( function() {
62
- $(this).addClass('cap-neg');
63
-
64
- var cap_name_attr = $(this).find('input[type="checkbox"]').attr('name');
65
- $(this).append('<input type="hidden" class="cme-negation-input" name="'+cap_name_attr+'" value="" />');
66
-
67
- $('input[name="' + cap_name_attr + '"]').parent().next('a.neg-cap:visible').click();
68
- });
69
-
70
- return false;
71
- });
72
-
73
- //http://stackoverflow.com/users/803925/nbrooks
74
- $('table.cme-typecaps th').click(function(){
75
- var columnNo = $(this).index();
76
-
77
- var check_val = ! $(this).prop('checked_all');
78
-
79
- if ( $(this).hasClass('term-cap') )
80
- var class_sel = '[class*="term-cap"]';
81
- else
82
- var class_sel = '[class*="post-cap"]';
83
-
84
- var chks = $(this).closest("table")
85
- .find("tr td" + class_sel + ":nth-child(" + (columnNo+1) + ') input[type="checkbox"]:visible');
86
-
87
- $(chks).each(function(i,e) {
88
- $('input[name="' + $(this).attr('name') + '"]').prop('checked', check_val);
89
- });
90
-
91
- $(this).prop('checked_all',check_val);
92
- });
93
-
94
- $('a.cme-fix-read-cap').click(function(){
95
- $('input[name="caps[read]"]').prop('checked', true);
96
- $('input[name="SaveRole"]').trigger('click');
97
- return false;
98
- });
99
-
100
- /* Filter Edit, Delete and Read capabilities */
101
-
102
- // Fill the <select> extracting the values and labels from the tables
103
- $('.ppc-filter-select').each(function(){
104
- var filter = $(this)
105
- var options = new Array();
106
- $(this).parent().siblings('table').find('tbody').find('tr').each(function(){
107
- options.push({
108
- value : $(this).attr('class'),
109
- text : $(this).find('.cap_type').text()
110
- });
111
- });
112
- options.forEach(function(option, index){
113
- filter.append($('<option>', {
114
- value: option.value,
115
- text: option.text
116
- }));
117
- });
118
- });
119
-
120
- // Reset select filters on load
121
- $('.ppc-filter-select').prop('selectedIndex', 0);
122
-
123
- $('.ppc-filter-select-reset').click(function(){
124
- $(this).prev('.ppc-filter-select').prop('selectedIndex', 0);
125
- $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
126
- });
127
- $('.ppc-filter-select').change(function(){
128
- if($(this).val()){
129
- $(this).parent().siblings('table').find('tr').hide();
130
- $(this).parent().siblings('table').find('thead tr:first-child').show(); // Show the table heading
131
- $(this).parent().siblings('table').find('tr.' + $(this).val()).show(); // Show only the filtered row
132
- } else {
133
- $(this).parent().siblings('table').find('tr').show(); // No value selected; show all the table rows
134
- }
135
- });
136
-
137
- /* Filter WordPress core, WooCommerce, Additional capabilities */
138
-
139
- // Reset text filters on load
140
- $('.ppc-filter-text').val('');
141
-
142
- $('.ppc-filter-text-reset').click(function(){
143
- $(this).prev('.ppc-filter-text').val('');
144
- $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
145
- $(this).parent().siblings('.ppc-filter-no-results').hide(); // Hide "no results" message
146
- });
147
- $('.ppc-filter-text').keyup(function(){
148
- $(this).parent().siblings('table').find('tr').hide();
149
- $(this).parent().siblings('table').find('tr[class*="' + $(this).val() + '"]').show(); // Show only the filtered row
150
- $(this).parent().siblings('table').find('tr.cme-bulk-select').hide(); // Hide bulk row
151
- if($(this).val().length === 0){
152
- $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
153
- }
154
- // Show / Hide the no-results message
155
- if($(this).parent().siblings('table').find('tr:visible').length === 0) {
156
- $(this).parent().siblings('.ppc-filter-no-results').show(); // Show "no results" message
157
- } else {
158
- $(this).parent().siblings('.ppc-filter-no-results').hide(); // Hide "no results" message
159
- }
160
- });
161
-
162
- /**
163
- * Roles tab toggle
164
- */
165
- $(document).on('click', '.ppc-roles-tab li', function (event) {
166
- event.preventDefault();
167
-
168
- var clicked_tab = $(this).attr('data-tab');
169
-
170
- //remove active class from all tabs
171
- $('.ppc-roles-tab li').removeClass('active');
172
- //add active class to current tab
173
- $(this).addClass('active');
174
-
175
- //hide all tabs contents
176
- $('.pp-roles-tab-tr').hide();
177
- //show this current tab contents
178
- $('.pp-roles-' + clicked_tab + '-tab').show();
179
- });
180
-
181
- /**
182
- * Roles capabilities load more button
183
- */
184
- $(document).on('click', '.roles-capabilities-load-more', function (event) {
185
- event.preventDefault();
186
-
187
- $('.roles-capabilities-load-more').hide();
188
-
189
- $('.roles-capabilities-load-less').show();
190
-
191
- $('ul.pp-roles-capabilities li').show();
192
- });
193
-
194
- /**
195
- * Roles capabilities load less button
196
- */
197
- $(document).on('click', '.roles-capabilities-load-less', function (event) {
198
- event.preventDefault();
199
-
200
- $('.roles-capabilities-load-less').hide();
201
-
202
- $('.roles-capabilities-load-more').show();
203
-
204
- $('ul.pp-roles-capabilities li').hide();
205
-
206
- $('ul.pp-roles-capabilities').children().slice(0, 6).show();
207
-
208
- window.scrollTo({ top: 0, behavior: 'smooth' });
209
- });
210
-
211
- /**
212
- * Capabilities role slug validation
213
- */
214
- $('.ppc-roles-tab-content input[name="role_slug"]').on('keyup', function (e) {
215
- is_role_slug_exist();
216
- });
217
-
218
- if ($('#pp-role-slug-exists').length > 0) {
219
- is_role_slug_exist();
220
- }
221
-
222
- function is_role_slug_exist() {
223
- if ($('.ppc-roles-tab-content input[name="role_slug"]').attr('readonly') !== 'readonly') {
224
- var value = $('.ppc-roles-tab-content input[name="role_slug"]').val();
225
- var slugexists = $('#pp-role-slug-exists')
226
- var all_roles = $('.ppc-roles-all-roles').val();
227
- var role_array = all_roles.split(',');
228
- if (role_array.includes(value)) {
229
- slugexists.show();
230
- } else {
231
- slugexists.hide();
232
- }
233
- }
234
- }
235
-
236
- });
1
+ jQuery(document).ready( function($) {
2
+ $('a.neg-cap').attr('title',cmeAdmin.negationCaption);
3
+ $('a.neg-type-caps').attr('title',cmeAdmin.typeCapsNegationCaption);
4
+ $('td.cap-unreg').attr('title',cmeAdmin.typeCapUnregistered);
5
+ $('a.normal-cap').attr('title',cmeAdmin.switchableCaption);
6
+ $('span.cap-x').attr('title',cmeAdmin.capNegated);
7
+ $('table.cme-checklist input[class!="cme-check-all"]').not(':disabled').attr('title',cmeAdmin.chkCaption);
8
+
9
+ $('table.cme-checklist a.neg-cap').click( function(e) {
10
+ $(this).closest('td').removeClass('cap-yes').removeClass('cap-no').addClass('cap-neg');
11
+
12
+ var cap_name_attr = $(this).parent().find('input[type="checkbox"]').attr('name');
13
+ $(this).after('<input type="hidden" class="cme-negation-input" name="'+cap_name_attr+'" value="" />');
14
+
15
+ $('input[name="' + cap_name_attr + '"]').closest('td').removeClass('cap-yes').removeClass('cap-no').addClass('cap-neg');
16
+
17
+ return false;
18
+ });
19
+
20
+ //$('table.cme-typecaps span.cap-x,table.cme-checklist span.cap-x,table.cme-checklist td.cap-neg span').live( 'click', function(e) {
21
+ $(document).on( 'click', 'table.cme-typecaps span.cap-x,table.cme-checklist span.cap-x,table.cme-checklist td.cap-neg span', function(e) {
22
+ $(this).closest('td').removeClass('cap-neg').removeClass('cap-yes').addClass('cap-no');
23
+ $(this).parent().find('input[type="checkbox"]').prop('checked',false);
24
+ $(this).parent().find('input.cme-negation-input').remove();
25
+
26
+ // Also apply for any other checkboxes with the same name
27
+ var cap_name_attr = $(this).next('input[type="checkbox"]').attr('name');
28
+
29
+ if (!cap_name_attr) {
30
+ cap_name_attr = $(this).next('label').find('input[type="checkbox"]').attr('name');
31
+ }
32
+
33
+ $('input[name="' + cap_name_attr + '"]').parent().closest('td').removeClass('cap-neg').removeClass('cap-yes').addClass('cap-no');
34
+ $('input[name="' + cap_name_attr + '"]').prop('checked',false).parent().find('input.cme-negation-input').remove();
35
+
36
+ return false;
37
+ });
38
+
39
+ $("#publishpress_caps_form").bind("keypress", function(e) {
40
+ if (e.keyCode == 13) {
41
+ $(document.activeElement).parent().find('input[type="submit"]').first().click();
42
+ return false;
43
+ }
44
+ });
45
+
46
+ $('input.cme-check-all').click( function(e) {
47
+ $(this).closest('table').find('input[type="checkbox"][disabled!="disabled"]:visible').prop('checked', $(this).is(":checked") );
48
+ });
49
+
50
+ $('a.cme-neg-all').click( function(e) {
51
+ $(this).closest('table').find('a.neg-cap:visible').click();
52
+ return false;
53
+ });
54
+
55
+ $('a.cme-switch-all').click( function(e) {
56
+ $(this).closest('table').find('td.cap-neg span').click();
57
+ return false;
58
+ });
59
+
60
+ $('table.cme-typecaps a.neg-type-caps').click( function(e) {
61
+ $(this).closest('tr').find('td[class!="cap-neg"]').filter('td[class!="cap-unreg"]').each( function() {
62
+ $(this).addClass('cap-neg');
63
+
64
+ var cap_name_attr = $(this).find('input[type="checkbox"]').attr('name');
65
+ $(this).append('<input type="hidden" class="cme-negation-input" name="'+cap_name_attr+'" value="" />');
66
+
67
+ $('input[name="' + cap_name_attr + '"]').parent().next('a.neg-cap:visible').click();
68
+ });
69
+
70
+ return false;
71
+ });
72
+
73
+ //http://stackoverflow.com/users/803925/nbrooks
74
+ $('table.cme-typecaps th').click(function(){
75
+ var columnNo = $(this).index();
76
+
77
+ var check_val = ! $(this).prop('checked_all');
78
+
79
+ if ( $(this).hasClass('term-cap') )
80
+ var class_sel = '[class*="term-cap"]';
81
+ else
82
+ var class_sel = '[class*="post-cap"]';
83
+
84
+ var chks = $(this).closest("table")
85
+ .find("tr td" + class_sel + ":nth-child(" + (columnNo+1) + ') input[type="checkbox"]:visible');
86
+
87
+ $(chks).each(function(i,e) {
88
+ $('input[name="' + $(this).attr('name') + '"]').prop('checked', check_val);
89
+ });
90
+
91
+ $(this).prop('checked_all',check_val);
92
+ });
93
+
94
+ $('a.cme-fix-read-cap').click(function(){
95
+ $('input[name="caps[read]"]').prop('checked', true);
96
+ $('input[name="SaveRole"]').trigger('click');
97
+ return false;
98
+ });
99
+
100
+ /* Filter Edit, Delete and Read capabilities */
101
+
102
+ // Fill the <select> extracting the values and labels from the tables
103
+ $('.ppc-filter-select').each(function(){
104
+ var filter = $(this)
105
+ var options = new Array();
106
+ $(this).parent().siblings('table').find('tbody').find('tr').each(function(){
107
+ options.push({
108
+ value : $(this).attr('class'),
109
+ text : $(this).find('.cap_type').text()
110
+ });
111
+ });
112
+ options.forEach(function(option, index){
113
+ filter.append($('<option>', {
114
+ value: option.value,
115
+ text: option.text
116
+ }));
117
+ });
118
+ });
119
+
120
+ // Reset select filters on load
121
+ $('.ppc-filter-select').prop('selectedIndex', 0);
122
+
123
+ $('.ppc-filter-select-reset').click(function(){
124
+ $(this).prev('.ppc-filter-select').prop('selectedIndex', 0);
125
+ $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
126
+ });
127
+ $('.ppc-filter-select').change(function(){
128
+ if($(this).val()){
129
+ $(this).parent().siblings('table').find('tr').hide();
130
+ $(this).parent().siblings('table').find('thead tr:first-child').show(); // Show the table heading
131
+ $(this).parent().siblings('table').find('tr.' + $(this).val()).show(); // Show only the filtered row
132
+ } else {
133
+ $(this).parent().siblings('table').find('tr').show(); // No value selected; show all the table rows
134
+ }
135
+ });
136
+
137
+ /* Filter WordPress core, WooCommerce, Additional capabilities */
138
+
139
+ // Reset text filters on load
140
+ $('.ppc-filter-text').val('');
141
+
142
+ $('.ppc-filter-text-reset').click(function(){
143
+ $(this).prev('.ppc-filter-text').val('');
144
+ $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
145
+ $(this).parent().siblings('.ppc-filter-no-results').hide(); // Hide "no results" message
146
+ });
147
+ $('.ppc-filter-text').keyup(function(){
148
+ $(this).parent().siblings('table').find('tr').hide();
149
+ $(this).parent().siblings('table').find('tr[class*="' + $(this).val() + '"]').show(); // Show only the filtered row
150
+ $(this).parent().siblings('table').find('tr.cme-bulk-select').hide(); // Hide bulk row
151
+ if($(this).val().length === 0){
152
+ $(this).parent().siblings('table').find('tr').show(); // Show all the table rows
153
+ }
154
+ // Show / Hide the no-results message
155
+ if($(this).parent().siblings('table').find('tr:visible').length === 0) {
156
+ $(this).parent().siblings('.ppc-filter-no-results').show(); // Show "no results" message
157
+ } else {
158
+ $(this).parent().siblings('.ppc-filter-no-results').hide(); // Hide "no results" message
159
+ }
160
+ });
161
+
162
+ /**
163
+ * Roles tab toggle
164
+ */
165
+ $(document).on('click', '.ppc-roles-tab li', function (event) {
166
+ event.preventDefault();
167
+
168
+ var clicked_tab = $(this).attr('data-tab');
169
+
170
+ //remove active class from all tabs
171
+ $('.ppc-roles-tab li').removeClass('active');
172
+ //add active class to current tab
173
+ $(this).addClass('active');
174
+
175
+ //hide all tabs contents
176
+ $('.pp-roles-tab-tr').hide();
177
+ //show this current tab contents
178
+ $('.pp-roles-' + clicked_tab + '-tab').show();
179
+ });
180
+
181
+ /**
182
+ * Roles capabilities load more button
183
+ */
184
+ $(document).on('click', '.roles-capabilities-load-more', function (event) {
185
+ event.preventDefault();
186
+
187
+ $('.roles-capabilities-load-more').hide();
188
+
189
+ $('.roles-capabilities-load-less').show();
190
+
191
+ $('ul.pp-roles-capabilities li').show();
192
+ });
193
+
194
+ /**
195
+ * Roles capabilities load less button
196
+ */
197
+ $(document).on('click', '.roles-capabilities-load-less', function (event) {
198
+ event.preventDefault();
199
+
200
+ $('.roles-capabilities-load-less').hide();
201
+
202
+ $('.roles-capabilities-load-more').show();
203
+
204
+ $('ul.pp-roles-capabilities li').hide();
205
+
206
+ $('ul.pp-roles-capabilities').children().slice(0, 6).show();
207
+
208
+ window.scrollTo({ top: 0, behavior: 'smooth' });
209
+ });
210
+
211
+ /**
212
+ * Capabilities role slug validation
213
+ */
214
+ $('.ppc-roles-tab-content input[name="role_slug"]').on('keyup', function (e) {
215
+ is_role_slug_exist();
216
+ });
217
+
218
+ if ($('#pp-role-slug-exists').length > 0) {
219
+ is_role_slug_exist();
220
+ }
221
+
222
+ function is_role_slug_exist() {
223
+ if ($('.ppc-roles-tab-content input[name="role_slug"]').attr('readonly') !== 'readonly') {
224
+ var value = $('.ppc-roles-tab-content input[name="role_slug"]').val();
225
+ var slugexists = $('#pp-role-slug-exists')
226
+ var all_roles = $('.ppc-roles-all-roles').val();
227
+ var role_array = all_roles.split(',');
228
+ if (role_array.includes(value)) {
229
+ slugexists.show();
230
+ } else {
231
+ slugexists.hide();
232
+ }
233
+ }
234
+ }
235
+
236
+ });
common/js/profile.js CHANGED
@@ -1,34 +1,34 @@
1
- jQuery(function ($) {
2
- // Check if the Role field is available. If not, abort.
3
- if (!$('.user-role-wrap select#role, #createuser select#role').length) {
4
- return;
5
- }
6
-
7
- var $field = $('.user-role-wrap select#role, #createuser select#role'),
8
- $newField = $field.clone();
9
-
10
- $newField.attr('name', 'pp_roles[]');
11
- $newField.attr('id', 'pp_roles');
12
- $field.after($newField);
13
- $field.hide();
14
-
15
- // Convert the roles field into multiselect
16
- $newField.prop('multiple', true);
17
-
18
- // $newField.attr('name', 'role[]');
19
-
20
- // Select additional roles
21
- $newField.find('option').each(function (i, option) {
22
- $option = $(option);
23
-
24
- $.each(ppCapabilitiesProfileData.selected_roles, function (i, role) {
25
- if ($option.val() === role) {
26
- $option.prop('selected', true);
27
- }
28
- });
29
- });
30
-
31
- $newField.chosen({
32
- 'width': '25em'
33
- });
34
- });
1
+ jQuery(function ($) {
2
+ // Check if the Role field is available. If not, abort.
3
+ if (!$('.user-role-wrap select#role, #createuser select#role').length) {
4
+ return;
5
+ }
6
+
7
+ var $field = $('.user-role-wrap select#role, #createuser select#role'),
8
+ $newField = $field.clone();
9
+
10
+ $newField.attr('name', 'pp_roles[]');
11
+ $newField.attr('id', 'pp_roles');
12
+ $field.after($newField);
13
+ $field.hide();
14
+
15
+ // Convert the roles field into multiselect
16
+ $newField.prop('multiple', true);
17
+
18
+ // $newField.attr('name', 'role[]');
19
+
20
+ // Select additional roles
21
+ $newField.find('option').each(function (i, option) {
22
+ $option = $(option);
23
+
24
+ $.each(ppCapabilitiesProfileData.selected_roles, function (i, role) {
25
+ if ($option.val() === role) {
26
+ $option.prop('selected', true);
27
+ }
28
+ });
29
+ });
30
+
31
+ $newField.chosen({
32
+ 'width': '25em'
33
+ });
34
+ });
composer.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "name": "publishpress/publishpress-capabilities",
3
- "type": "wordpress-plugin",
4
- "description": "",
5
- "license": "GPL-2",
6
- "authors": [
7
- {
8
- "name": "PublishPress",
9
- "email": "help@publishpress.com"
10
- }
11
- ],
12
- "config": {
13
- "preferred-install": "dist"
14
- },
15
- "minimum-stability": "stable",
16
- "require": {
17
- "php": ">=5.6.20",
18
- "psr/container": "1.0.0",
19
- "pimple/pimple": "3.2.3.*",
20
- "publishpress/wordpress-reviews": "^1.1",
21
- "publishpress/wordpress-version-notices": "^1",
22
- "publishpress/wordpress-banners": "^1.2"
23
- }
24
- }
1
+ {
2
+ "name": "publishpress/publishpress-capabilities",
3
+ "type": "wordpress-plugin",
4
+ "description": "",
5
+ "license": "GPL-2",
6
+ "authors": [
7
+ {
8
+ "name": "PublishPress",
9
+ "email": "help@publishpress.com"
10
+ }
11
+ ],
12
+ "config": {
13
+ "preferred-install": "dist"
14
+ },
15
+ "minimum-stability": "stable",
16
+ "require": {
17
+ "php": ">=5.6.20",
18
+ "psr/container": "1.0.0",
19
+ "pimple/pimple": "3.2.3.*",
20
+ "publishpress/wordpress-reviews": "^1.1",
21
+ "publishpress/wordpress-version-notices": "^1",
22
+ "publishpress/wordpress-banners": "^1.2"
23
+ }
24
+ }
composer.lock CHANGED
@@ -279,5 +279,5 @@
279
  "php": ">=5.6.20"
280
  },
281
  "platform-dev": [],
282
- "plugin-api-version": "2.2.0"
283
  }
279
  "php": ">=5.6.20"
280
  },
281
  "platform-dev": [],
282
+ "plugin-api-version": "2.3.0"
283
  }
framework/lib/users.php CHANGED
@@ -1,109 +1,109 @@
1
- <?php
2
- /**
3
- * Users, Roles and Capabilities related functions.
4
- *
5
- * @version $Rev: 203758 $
6
- * @author Jordi Canals
7
- * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
8
- * @license GNU General Public License version 2
9
- * @link http://alkivia.org
10
- * @package Alkivia
11
- * @subpackage Framework
12
- *
13
-
14
- Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
-
16
- This program is free software; you can redistribute it and/or
17
- modify it under the terms of the GNU General Public License
18
- version 2 as published by the Free Software Foundation.
19
-
20
- This program is distributed in the hope that it will be useful,
21
- but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- GNU General Public License for more details.
24
-
25
- You should have received a copy of the GNU General Public License
26
- along with this program. If not, see <http://www.gnu.org/licenses/>.
27
- */
28
-
29
- /**
30
- * Returns all valid roles.
31
- * The returned list can be translated or not.
32
- *
33
- * @uses apply_filters() Calls the 'alkivia_roles_translate' hook on translated roles array.
34
- * @since 0.5
35
- *
36
- * @param boolean $translate If the returned roles have to be translated or not.
37
- * @return array All defined roles. If translated, the key is the role name and value is the translated role.
38
- */
39
- function ak_get_roles( $translate = false ) {
40
- $wp_roles_obj = wp_roles();
41
-
42
- $roles = $wp_roles_obj->get_names();
43
- if ( $translate ) {
44
- foreach ($roles as $k => $r) {
45
- $roles[$k] = _x($r, 'User role');
46
- }
47
- asort($roles);
48
- return apply_filters('alkivia_roles_translate', $roles);
49
- } else {
50
- $roles = array_keys($roles);
51
- asort($roles);
52
- return $roles;
53
- }
54
- }
55
-
56
- /**
57
- * Generates the caps names from user level.
58
- *
59
- * @since 0.5
60
- *
61
- * @param int $level Level to convert to caps
62
- * @return array Generated caps
63
- */
64
- function ak_level2caps( $level ) {
65
- $caps = array();
66
- $level = min(10, intval($level));
67
-
68
- for ( $i = $level; $i >= 0; $i--) {
69
- $caps["level_{$i}"] = true;
70
- }
71
-
72
- return $caps;
73
- }
74
-
75
- /**
76
- * Finds the proper level from a capabilities list.
77
- *
78
- * @since 0.5
79
- *
80
- * @uses _ak_level_reduce()
81
- * @param array $caps List of capabilities.
82
- * @return int Level found, if no level found, will return 0.
83
- */
84
- function ak_caps2level( $caps ) {
85
- if (!is_array($caps)) {
86
- return 0;
87
- }
88
-
89
- $level = array_reduce( array_keys( $caps ), '_ak_caps2level_CB', 0);
90
- return $level;
91
- }
92
-
93
- /**
94
- * Callback function to find the level from caps.
95
- * Taken from WordPress 2.7.1
96
- *
97
- * @since 0.5
98
- * @access private
99
- *
100
- * @return int level Level found.
101
- */
102
- function _ak_caps2level_CB( $max, $item ) {
103
- if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
104
- $level = intval( $matches[1] );
105
- return max( $max, $level );
106
- } else {
107
- return $max;
108
- }
109
- }
1
+ <?php
2
+ /**
3
+ * Users, Roles and Capabilities related functions.
4
+ *
5
+ * @version $Rev: 203758 $
6
+ * @author Jordi Canals
7
+ * @copyright Copyright (C) 2008, 2009, 2010 Jordi Canals
8
+ * @license GNU General Public License version 2
9
+ * @link http://alkivia.org
10
+ * @package Alkivia
11
+ * @subpackage Framework
12
+ *
13
+
14
+ Copyright 2008, 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ version 2 as published by the Free Software Foundation.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License
26
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+ */
28
+
29
+ /**
30
+ * Returns all valid roles.
31
+ * The returned list can be translated or not.
32
+ *
33
+ * @uses apply_filters() Calls the 'alkivia_roles_translate' hook on translated roles array.
34
+ * @since 0.5
35
+ *
36
+ * @param boolean $translate If the returned roles have to be translated or not.
37
+ * @return array All defined roles. If translated, the key is the role name and value is the translated role.
38
+ */
39
+ function ak_get_roles( $translate = false ) {
40
+ $wp_roles_obj = wp_roles();
41
+
42
+ $roles = $wp_roles_obj->get_names();
43
+ if ( $translate ) {
44
+ foreach ($roles as $k => $r) {
45
+ $roles[$k] = _x($r, 'User role');
46
+ }
47
+ asort($roles);
48
+ return apply_filters('alkivia_roles_translate', $roles);
49
+ } else {
50
+ $roles = array_keys($roles);
51
+ asort($roles);
52
+ return $roles;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Generates the caps names from user level.
58
+ *
59
+ * @since 0.5
60
+ *
61
+ * @param int $level Level to convert to caps
62
+ * @return array Generated caps
63
+ */
64
+ function ak_level2caps( $level ) {
65
+ $caps = array();
66
+ $level = min(10, intval($level));
67
+
68
+ for ( $i = $level; $i >= 0; $i--) {
69
+ $caps["level_{$i}"] = true;
70
+ }
71
+
72
+ return $caps;
73
+ }
74
+
75
+ /**
76
+ * Finds the proper level from a capabilities list.
77
+ *
78
+ * @since 0.5
79
+ *
80
+ * @uses _ak_level_reduce()
81
+ * @param array $caps List of capabilities.
82
+ * @return int Level found, if no level found, will return 0.
83
+ */
84
+ function ak_caps2level( $caps ) {
85
+ if (!is_array($caps)) {
86
+ return 0;
87
+ }
88
+
89
+ $level = array_reduce( array_keys( $caps ), '_ak_caps2level_CB', 0);
90
+ return $level;
91
+ }
92
+
93
+ /**
94
+ * Callback function to find the level from caps.
95
+ * Taken from WordPress 2.7.1
96
+ *
97
+ * @since 0.5
98
+ * @access private
99
+ *
100
+ * @return int level Level found.
101
+ */
102
+ function _ak_caps2level_CB( $max, $item ) {
103
+ if ( preg_match( '/^level_(10|[0-9])$/i', $item, $matches ) ) {
104
+ $level = intval( $matches[1] );
105
+ return max( $max, $level );
106
+ } else {
107
+ return $max;
108
+ }
109
+ }
framework/styles/admin.css CHANGED
@@ -1,134 +1,134 @@
1
- /**
2
- * Alkivia Framework.
3
- * Styles for admin dashboard.
4
- * Based on the styles for Maintenance Mode plugin by Michael Wöhrer
5
- *
6
- * @version $Rev: 198515 $
7
- * @author Jordi Canals
8
- * @copyright Copyright (C) 2009, 2010 Jordi Canals
9
- * @license GNU General Public License version 2
10
- * @link http://alkivia.org
11
- * @package Alkivia
12
- * @subpackage Framework
13
- *
14
-
15
- Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
-
17
- This program is free software; you can redistribute it and/or
18
- modify it under the terms of the GNU General Public License
19
- version 2 as published by the Free Software Foundation.
20
-
21
- This program is distributed in the hope that it will be useful,
22
- but WITHOUT ANY WARRANTY; without even the implied warranty of
23
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
- GNU General Public License for more details.
25
-
26
- You should have received a copy of the GNU General Public License
27
- along with this program. If not, see <http://www.gnu.org/licenses/>.
28
- */
29
-
30
- /* =========================================================== SETTINGS */
31
-
32
- table#akmin {
33
- width: 100%;
34
- border: 0 none;
35
- padding: 0;
36
- margin: 0;
37
- }
38
-
39
- table#akmin fieldset {
40
- border: 0 none;
41
- padding: 0;
42
- margin: 0;
43
- }
44
-
45
- table#akmin td {
46
- vertical-align: top;
47
- }
48
-
49
- table#akmin td dl {
50
- padding: 0;
51
- margin: 10px 0 20px 0;
52
- background-color: white;
53
- border: 1px solid #dfdfdf;
54
- }
55
-
56
- table#akmin td dl {
57
- -moz-border-radius: 5px;
58
- -khtml-border-radius: 5px;
59
- -webkit-border-radius: 5px;
60
- border-radius: 5px;
61
- }
62
-
63
- table#akmin dl dt {
64
- font-size: 13px;
65
- font-weight: bold;
66
- margin: 0;
67
- padding: 4px 10px 4px 10px;
68
- background: #dfdfdf;
69
- }
70
-
71
- table#akmin p:not(.pp-recommendations-heading) {
72
- padding: 5px 0 5px 0;
73
- margin: 0;
74
- }
75
-
76
- table#akmin ul {
77
- list-style: none;
78
- }
79
-
80
- table#akmin ul.ul-disc {
81
- list-style: disc outside;
82
- }
83
-
84
- /* ====================================================== ADMIN CONTENT */
85
-
86
- table#akmin td.content {
87
- padding: 0 8px 0 0;
88
- }
89
-
90
- table#akmin td.content dd {
91
- margin: 0;
92
- padding: 10px;
93
- }
94
-
95
- select.ppc-admin-menu-role {
96
- margin-left: 0;
97
- }
98
-
99
- /* ====================================================== ADMIN SIDEBAR */
100
-
101
- table#akmin td.sidebar {
102
- width: 250px;
103
- padding: 0 0 0 8px;
104
- }
105
-
106
- table#akmin td.sidebar ul, table#akmin td.sidebar ul li {
107
- list-style: none;
108
- padding: 0;
109
- margin: 0;
110
- }
111
-
112
- table#akmin td.sidebar a {
113
- text-decoration: none;
114
- background-position: 0px 60%;
115
- background-repeat: no-repeat;
116
- padding: 4px 0px 4px 22px;
117
- border: 0 none;
118
- display: block;
119
- }
120
-
121
- table#akmin td.sidebar .cme-backup-tool a {
122
- padding-left: 0;
123
- }
124
-
125
- table#akmin td.sidebar ul li {
126
- margin: 0;
127
- border-bottom: 1px dotted gray;
128
- }
129
-
130
- table#akmin td.sidebar dd,
131
- table#akmin td .pp-column-right dd {
132
- margin: 0;
133
- padding: 5px 10px 5px 10px;
134
- }
1
+ /**
2
+ * Alkivia Framework.
3
+ * Styles for admin dashboard.
4
+ * Based on the styles for Maintenance Mode plugin by Michael Wöhrer
5
+ *
6
+ * @version $Rev: 198515 $
7
+ * @author Jordi Canals
8
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals
9
+ * @license GNU General Public License version 2
10
+ * @link http://alkivia.org
11
+ * @package Alkivia
12
+ * @subpackage Framework
13
+ *
14
+
15
+ Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ version 2 as published by the Free Software Foundation.
20
+
21
+ This program is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU General Public License for more details.
25
+
26
+ You should have received a copy of the GNU General Public License
27
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ */
29
+
30
+ /* =========================================================== SETTINGS */
31
+
32
+ table#akmin {
33
+ width: 100%;
34
+ border: 0 none;
35
+ padding: 0;
36
+ margin: 0;
37
+ }
38
+
39
+ table#akmin fieldset {
40
+ border: 0 none;
41
+ padding: 0;
42
+ margin: 0;
43
+ }
44
+
45
+ table#akmin td {
46
+ vertical-align: top;
47
+ }
48
+
49
+ table#akmin td dl {
50
+ padding: 0;
51
+ margin: 10px 0 20px 0;
52
+ background-color: white;
53
+ border: 1px solid #dfdfdf;
54
+ }
55
+
56
+ table#akmin td dl {
57
+ -moz-border-radius: 5px;
58
+ -khtml-border-radius: 5px;
59
+ -webkit-border-radius: 5px;
60
+ border-radius: 5px;
61
+ }
62
+
63
+ table#akmin dl dt {
64
+ font-size: 13px;
65
+ font-weight: bold;
66
+ margin: 0;
67
+ padding: 4px 10px 4px 10px;
68
+ background: #dfdfdf;
69
+ }
70
+
71
+ table#akmin p:not(.pp-recommendations-heading) {
72
+ padding: 5px 0 5px 0;
73
+ margin: 0;
74
+ }
75
+
76
+ table#akmin ul {
77
+ list-style: none;
78
+ }
79
+
80
+ table#akmin ul.ul-disc {
81
+ list-style: disc outside;
82
+ }
83
+
84
+ /* ====================================================== ADMIN CONTENT */
85
+
86
+ table#akmin td.content {
87
+ padding: 0 8px 0 0;
88
+ }
89
+
90
+ table#akmin td.content dd {
91
+ margin: 0;
92
+ padding: 10px;
93
+ }
94
+
95
+ select.ppc-admin-menu-role {
96
+ margin-left: 0;
97
+ }
98
+
99
+ /* ====================================================== ADMIN SIDEBAR */
100
+
101
+ table#akmin td.sidebar {
102
+ width: 250px;
103
+ padding: 0 0 0 8px;
104
+ }
105
+
106
+ table#akmin td.sidebar ul, table#akmin td.sidebar ul li {
107
+ list-style: none;
108
+ padding: 0;
109
+ margin: 0;
110
+ }
111
+
112
+ table#akmin td.sidebar a {
113
+ text-decoration: none;
114
+ background-position: 0px 60%;
115
+ background-repeat: no-repeat;
116
+ padding: 4px 0px 4px 22px;
117
+ border: 0 none;
118
+ display: block;
119
+ }
120
+
121
+ table#akmin td.sidebar .cme-backup-tool a {
122
+ padding-left: 0;
123
+ }
124
+
125
+ table#akmin td.sidebar ul li {
126
+ margin: 0;
127
+ border-bottom: 1px dotted gray;
128
+ }
129
+
130
+ table#akmin td.sidebar dd,
131
+ table#akmin td .pp-column-right dd {
132
+ margin: 0;
133
+ padding: 5px 10px 5px 10px;
134
+ }
includes-core/CoreAdmin.php CHANGED
@@ -1,85 +1,85 @@
1
- <?php
2
- namespace PublishPress\Capabilities;
3
-
4
- class CoreAdmin {
5
- function __construct() {
6
- add_action('admin_print_scripts', [$this, 'setUpgradeMenuLink'], 50);
7
-
8
- if (is_admin()) {
9
- $autoloadPath = PUBLISHPRESS_CAPS_ABSPATH . '/vendor/autoload.php';
10
- if (file_exists($autoloadPath)) {
11
- require_once $autoloadPath;
12
- }
13
-
14
- require_once PUBLISHPRESS_CAPS_ABSPATH . '/vendor/publishpress/wordpress-version-notices/includes.php';
15
-
16
- add_filter(\PPVersionNotices\Module\TopNotice\Module::SETTINGS_FILTER, function ($settings) {
17
- $settings['capabilities'] = [
18
- 'message' => 'You\'re using PublishPress Capabilities Free. The Pro version has more features and support. %sUpgrade to Pro%s',
19
- 'link' => 'https://publishpress.com/links/capabilities-banner',
20
- 'screens' => [
21
- ['base' => 'toplevel_page_pp-capabilities'],
22
- ['base' => 'capabilities_page_pp-capabilities-roles'],
23
- ['base' => 'capabilities_page_pp-capabilities-editor-features'],
24
- ['base' => 'capabilities_page_pp-capabilities-admin-features'],
25
- ['base' => 'capabilities_page_pp-capabilities-backup'],
26
- ['base' => 'capabilities_page_pp-capabilities-settings'],
27
- ]
28
- ];
29
-
30
- return $settings;
31
- });
32
- }
33
-
34
- add_action('pp-capabilities-admin-submenus', [$this, 'actCapabilitiesSubmenus']);
35
-
36
- //Editor feature metaboxes promo
37
- add_action('pp_capabilities_features_gutenberg_after_table_tr', [$this, 'metaboxesPromo']);
38
- add_action('pp_capabilities_features_classic_after_table_tr', [$this, 'metaboxesPromo']);
39
-
40
- //Admin features promo
41
- add_action('pp_capabilities_admin_features_after_table_tr', [$this, 'customItemsPromo']);
42
- }
43
-
44
- function setUpgradeMenuLink() {
45
- $url = 'https://publishpress.com/links/capabilities-menu';
46
- ?>
47
- <style type="text/css">
48
- #toplevel_page_pp-capabilities ul li:last-of-type a {font-weight: bold !important; color: #FEB123 !important;}
49
- </style>
50
-
51
- <script type="text/javascript">
52
- jQuery(document).ready(function($) {
53
- $('#toplevel_page_pp-capabilities ul li:last a').attr('href', '<?php echo esc_url_raw($url);?>').attr('target', '_blank').css('font-weight', 'bold').css('color', '#FEB123');
54
- });
55
- </script>
56
- <?php
57
- }
58
-
59
- function actCapabilitiesSubmenus() {
60
- $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
61
-
62
- add_submenu_page('pp-capabilities', esc_html__('Admin Menus', 'capsman-enhanced'), esc_html__('Admin Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-menus', [$this, 'AdminMenusPromo']);
63
- add_submenu_page('pp-capabilities', esc_html__('Nav Menus', 'capsman-enhanced'), esc_html__('Nav Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-nav-menus', [$this, 'NavMenusPromo']);
64
- }
65
-
66
- function AdminMenusPromo() {
67
- wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
68
- include (dirname(__FILE__) . '/admin-menus-promo.php');
69
- }
70
-
71
- function NavMenusPromo() {
72
- wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
73
- include (dirname(__FILE__) . '/nav-menus-promo.php');
74
- }
75
-
76
- function metaboxesPromo(){
77
- wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
78
- include (dirname(__FILE__) . '/editor-features-promo.php');
79
- }
80
-
81
- function customItemsPromo(){
82
- wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
83
- include (dirname(__FILE__) . '/admin-features-promo.php');
84
- }
85
  }
1
+ <?php
2
+ namespace PublishPress\Capabilities;
3
+
4
+ class CoreAdmin {
5
+ function __construct() {
6
+ add_action('admin_print_scripts', [$this, 'setUpgradeMenuLink'], 50);
7
+
8
+ if (is_admin()) {
9
+ $autoloadPath = PUBLISHPRESS_CAPS_ABSPATH . '/vendor/autoload.php';
10
+ if (file_exists($autoloadPath)) {
11
+ require_once $autoloadPath;
12
+ }
13
+
14
+ require_once PUBLISHPRESS_CAPS_ABSPATH . '/vendor/publishpress/wordpress-version-notices/includes.php';
15
+
16
+ add_filter(\PPVersionNotices\Module\TopNotice\Module::SETTINGS_FILTER, function ($settings) {
17
+ $settings['capabilities'] = [
18
+ 'message' => 'You\'re using PublishPress Capabilities Free. The Pro version has more features and support. %sUpgrade to Pro%s',
19
+ 'link' => 'https://publishpress.com/links/capabilities-banner',
20
+ 'screens' => [
21
+ ['base' => 'toplevel_page_pp-capabilities-roles'],
22
+ ['base' => 'capabilities_page_pp-capabilities'],
23
+ ['base' => 'capabilities_page_pp-capabilities-editor-features'],
24
+ ['base' => 'capabilities_page_pp-capabilities-admin-features'],
25
+ ['base' => 'capabilities_page_pp-capabilities-backup'],
26
+ ['base' => 'capabilities_page_pp-capabilities-settings'],
27
+ ]
28
+ ];
29
+
30
+ return $settings;
31
+ });
32
+ }
33
+
34
+ add_action('pp-capabilities-admin-submenus', [$this, 'actCapabilitiesSubmenus']);
35
+
36
+ //Editor feature metaboxes promo
37
+ add_action('pp_capabilities_features_gutenberg_after_table_tr', [$this, 'metaboxesPromo']);
38
+ add_action('pp_capabilities_features_classic_after_table_tr', [$this, 'metaboxesPromo']);
39
+
40
+ //Admin features promo
41
+ add_action('pp_capabilities_admin_features_after_table_tr', [$this, 'customItemsPromo']);
42
+ }
43
+
44
+ function setUpgradeMenuLink() {
45
+ $url = 'https://publishpress.com/links/capabilities-menu';
46
+ ?>
47
+ <style type="text/css">
48
+ #toplevel_page_pp-capabilities-roles ul li:last-of-type a {font-weight: bold !important; color: #FEB123 !important;}
49
+ </style>
50
+
51
+ <script type="text/javascript">
52
+ jQuery(document).ready(function($) {
53
+ $('#toplevel_page_pp-capabilities-roles ul li:last a').attr('href', '<?php echo esc_url_raw($url);?>').attr('target', '_blank').css('font-weight', 'bold').css('color', '#FEB123');
54
+ });
55
+ </script>
56
+ <?php
57
+ }
58
+
59
+ function actCapabilitiesSubmenus() {
60
+ $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
61
+
62
+ add_submenu_page('pp-capabilities-roles', esc_html__('Admin Menus', 'capsman-enhanced'), esc_html__('Admin Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-menus', [$this, 'AdminMenusPromo']);
63
+ add_submenu_page('pp-capabilities-roles', esc_html__('Nav Menus', 'capsman-enhanced'), esc_html__('Nav Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-nav-menus', [$this, 'NavMenusPromo']);
64
+ }
65
+
66
+ function AdminMenusPromo() {
67
+ wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
68
+ include (dirname(__FILE__) . '/admin-menus-promo.php');
69
+ }
70
+
71
+ function NavMenusPromo() {
72
+ wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
73
+ include (dirname(__FILE__) . '/nav-menus-promo.php');
74
+ }
75
+
76
+ function metaboxesPromo(){
77
+ wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
78
+ include (dirname(__FILE__) . '/editor-features-promo.php');
79
+ }
80
+
81
+ function customItemsPromo(){
82
+ wp_enqueue_style('pp-capabilities-admin-core', plugin_dir_url(CME_FILE) . 'includes-core/admin-core.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
83
+ include (dirname(__FILE__) . '/admin-features-promo.php');
84
+ }
85
  }
includes-core/admin-core.css CHANGED
@@ -1,185 +1,185 @@
1
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img,
2
- div.pp-capability-menus-wrapper-promo input.ppc-admin-menu-submit,
3
- div.pp-capability-menus-wrapper-promo select.ppc-admin-menu-role,
4
- div.pp-capability-menus-wrapper-promo input.ppc-nav-menu-submit,
5
- div.pp-capability-menus-wrapper-promo select.ppc-nav-menu-role {
6
- filter: blur(2px);
7
- }
8
-
9
- #pp-capability-menu-wrapper {
10
- border: inherit;
11
- }
12
-
13
- #pp-capability-menu-wrapper div.pp-capability-menus-promo {
14
- height: 600px;
15
- overflow: hidden;
16
- }
17
-
18
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner {
19
- position: relative;
20
- width: 100%;
21
- height: 100%;
22
- }
23
-
24
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img {
25
- position: absolute;
26
- width: 100%;
27
- }
28
-
29
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-mobile {
30
- display: none !important;
31
- }
32
-
33
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-desktop {
34
- display: block !important;
35
- }
36
-
37
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content {
38
- position: absolute;
39
- top: calc(50% - 100px);
40
- left: calc(50% - 225px);
41
- text-align: center;
42
- background: #655897;
43
- padding: 20px 20px 35px;
44
- border-radius: 6px;
45
- width: 450px;
46
- box-sizing: border-box;
47
- box-shadow: 0 0 25px #ccc;
48
- }
49
-
50
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-gradient {
51
- position: absolute;
52
- bottom: 0;
53
- width: 100%;
54
- height: 200px;
55
- background-image: linear-gradient(to bottom, rgba(255,255,255,0), #f1f1f1);
56
- }
57
-
58
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content p {
59
- line-height: 1.4em;
60
- font-size: 16px;
61
- margin-bottom: 20px;
62
- margin-top: 0;
63
- color: #fff;
64
- padding: 0;
65
- }
66
-
67
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content p:last-of-type {
68
- margin-bottom: 0;
69
- }
70
-
71
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a {
72
- font-size: 17px;
73
- background: #FCB223;
74
- color: #000;
75
- font-weight: normal;
76
- text-decoration: none;
77
- padding: 9px 12px;
78
- -webkit-border-radius: 4px;
79
- -moz-border-radius: 4px;
80
- border-radius: 4px;
81
- box-sizing: border-box;
82
- border: 1px solid #fca871;
83
- break-inside: avoid;
84
- white-space: nowrap;
85
- }
86
-
87
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:hover,
88
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:focus,
89
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:active {
90
- background: #fcca46;
91
- color: #000;
92
- }
93
-
94
- #pp-capability-menu-wrapper div.pp-capability-menus-promo-nav {
95
- height: 370px;
96
- }
97
-
98
- tr.pp-promo-blur {
99
- filter: blur(1.5px);
100
- }
101
-
102
- .pp-promo-overlay-row input[type=checkbox], input[type=radio] {
103
- cursor: not-allowed !important;
104
- }
105
-
106
- .pp-promo-overlay-row .ppc-custom-features-delete {
107
- color: red;
108
- }
109
-
110
- .pp-promo-overlay-row .pp-promo-upgrade-notice {
111
- position: absolute;
112
- margin-top: -100px;
113
- left: calc(50% - 225px);
114
- text-align: center;
115
- background: #655897;
116
- padding: 20px 20px 35px;
117
- border-radius: 6px;
118
- width: 450px;
119
- box-sizing: border-box;
120
- box-shadow: 0 0 25px #ccc;
121
- z-index: 999;
122
- }
123
-
124
- .pp-promo-overlay-row .pp-promo-upgrade-notice p {
125
- line-height: 1.4em;
126
- font-size: 16px;
127
- margin-bottom: 20px !important;
128
- margin-top: 0 !important;
129
- color: #fff;
130
- padding: 0;
131
- }
132
-
133
- .pp-promo-overlay-row .pp-promo-upgrade-notice p:last-of-type {
134
- margin-bottom: 0 !important;
135
- }
136
-
137
- .pp-promo-overlay-row .pp-promo-upgrade-notice a {
138
- font-size: 17px;
139
- background: #FCB223;
140
- color: #000;
141
- font-weight: normal;
142
- text-decoration: none;
143
- padding: 9px 12px;
144
- -webkit-border-radius: 4px;
145
- -moz-border-radius: 4px;
146
- border-radius: 4px;
147
- box-sizing: border-box;
148
- border: 1px solid #fca871;
149
- break-inside: avoid;
150
- white-space: nowrap;
151
- }
152
-
153
- @media (max-width: 979px) {
154
-
155
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-mobile {
156
- display: block !important;
157
- }
158
-
159
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-desktop {
160
- display: none !important;
161
- }
162
- }
163
-
164
- @media (max-width: 768px) {
165
-
166
- #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content {
167
- top: calc(50% - 100px);
168
- left: calc(50% - 150px);
169
- padding: 20px 20px 35px;
170
- width: 300px;
171
- }
172
-
173
- .pp-promo-overlay-row .pp-promo-upgrade-notice {
174
- left: 0;
175
- padding: 20px 20px 35px;
176
- width: fit-content;
177
- margin-left: 10px;
178
- margin-right: 10px;
179
- }
180
- }
181
-
182
- div.publishpress-wp-reviews-notice a.publishpress-dismiss {
183
- vertical-align: top !important;
184
- margin-bottom: 0 !important;
185
  }
1
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img,
2
+ div.pp-capability-menus-wrapper-promo input.ppc-admin-menu-submit,
3
+ div.pp-capability-menus-wrapper-promo select.ppc-admin-menu-role,
4
+ div.pp-capability-menus-wrapper-promo input.ppc-nav-menu-submit,
5
+ div.pp-capability-menus-wrapper-promo select.ppc-nav-menu-role {
6
+ filter: blur(2px);
7
+ }
8
+
9
+ #pp-capability-menu-wrapper {
10
+ border: inherit;
11
+ }
12
+
13
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo {
14
+ height: 600px;
15
+ overflow: hidden;
16
+ }
17
+
18
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner {
19
+ position: relative;
20
+ width: 100%;
21
+ height: 100%;
22
+ }
23
+
24
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img {
25
+ position: absolute;
26
+ width: 100%;
27
+ }
28
+
29
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-mobile {
30
+ display: none !important;
31
+ }
32
+
33
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-desktop {
34
+ display: block !important;
35
+ }
36
+
37
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content {
38
+ position: absolute;
39
+ top: calc(50% - 100px);
40
+ left: calc(50% - 225px);
41
+ text-align: center;
42
+ background: #655897;
43
+ padding: 20px 20px 35px;
44
+ border-radius: 6px;
45
+ width: 450px;
46
+ box-sizing: border-box;
47
+ box-shadow: 0 0 25px #ccc;
48
+ }
49
+
50
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-gradient {
51
+ position: absolute;
52
+ bottom: 0;
53
+ width: 100%;
54
+ height: 200px;
55
+ background-image: linear-gradient(to bottom, rgba(255,255,255,0), #f1f1f1);
56
+ }
57
+
58
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content p {
59
+ line-height: 1.4em;
60
+ font-size: 16px;
61
+ margin-bottom: 20px;
62
+ margin-top: 0;
63
+ color: #fff;
64
+ padding: 0;
65
+ }
66
+
67
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content p:last-of-type {
68
+ margin-bottom: 0;
69
+ }
70
+
71
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a {
72
+ font-size: 17px;
73
+ background: #FCB223;
74
+ color: #000;
75
+ font-weight: normal;
76
+ text-decoration: none;
77
+ padding: 9px 12px;
78
+ -webkit-border-radius: 4px;
79
+ -moz-border-radius: 4px;
80
+ border-radius: 4px;
81
+ box-sizing: border-box;
82
+ border: 1px solid #fca871;
83
+ break-inside: avoid;
84
+ white-space: nowrap;
85
+ }
86
+
87
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:hover,
88
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:focus,
89
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content a:active {
90
+ background: #fcca46;
91
+ color: #000;
92
+ }
93
+
94
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo-nav {
95
+ height: 370px;
96
+ }
97
+
98
+ tr.pp-promo-blur {
99
+ filter: blur(1.5px);
100
+ }
101
+
102
+ .pp-promo-overlay-row input[type=checkbox], input[type=radio] {
103
+ cursor: not-allowed !important;
104
+ }
105
+
106
+ .pp-promo-overlay-row .ppc-custom-features-delete {
107
+ color: red;
108
+ }
109
+
110
+ .pp-promo-overlay-row .pp-promo-upgrade-notice {
111
+ position: absolute;
112
+ margin-top: -100px;
113
+ left: calc(50% - 225px);
114
+ text-align: center;
115
+ background: #655897;
116
+ padding: 20px 20px 35px;
117
+ border-radius: 6px;
118
+ width: 450px;
119
+ box-sizing: border-box;
120
+ box-shadow: 0 0 25px #ccc;
121
+ z-index: 999;
122
+ }
123
+
124
+ .pp-promo-overlay-row .pp-promo-upgrade-notice p {
125
+ line-height: 1.4em;
126
+ font-size: 16px;
127
+ margin-bottom: 20px !important;
128
+ margin-top: 0 !important;
129
+ color: #fff;
130
+ padding: 0;
131
+ }
132
+
133
+ .pp-promo-overlay-row .pp-promo-upgrade-notice p:last-of-type {
134
+ margin-bottom: 0 !important;
135
+ }
136
+
137
+ .pp-promo-overlay-row .pp-promo-upgrade-notice a {
138
+ font-size: 17px;
139
+ background: #FCB223;
140
+ color: #000;
141
+ font-weight: normal;
142
+ text-decoration: none;
143
+ padding: 9px 12px;
144
+ -webkit-border-radius: 4px;
145
+ -moz-border-radius: 4px;
146
+ border-radius: 4px;
147
+ box-sizing: border-box;
148
+ border: 1px solid #fca871;
149
+ break-inside: avoid;
150
+ white-space: nowrap;
151
+ }
152
+
153
+ @media (max-width: 979px) {
154
+
155
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-mobile {
156
+ display: block !important;
157
+ }
158
+
159
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner img.pp-capability-desktop {
160
+ display: none !important;
161
+ }
162
+ }
163
+
164
+ @media (max-width: 768px) {
165
+
166
+ #pp-capability-menu-wrapper div.pp-capability-menus-promo .pp-capability-menus-promo-inner .pp-capability-menus-promo-content {
167
+ top: calc(50% - 100px);
168
+ left: calc(50% - 150px);
169
+ padding: 20px 20px 35px;
170
+ width: 300px;
171
+ }
172
+
173
+ .pp-promo-overlay-row .pp-promo-upgrade-notice {
174
+ left: 0;
175
+ padding: 20px 20px 35px;
176
+ width: fit-content;
177
+ margin-left: 10px;
178
+ margin-right: 10px;
179
+ }
180
+ }
181
+
182
+ div.publishpress-wp-reviews-notice a.publishpress-dismiss {
183
+ vertical-align: top !important;
184
+ margin-bottom: 0 !important;
185
  }
includes-core/admin-features-promo.php CHANGED
@@ -1,136 +1,136 @@
1
- <?php
2
- /**
3
- * Capability Manager Admin Features Promo.
4
- *
5
- * Copyright 2020, PublishPress <help@publishpress.com>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
- */
19
-
20
- ?>
21
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
22
- <td class="features-section-header" colspan="2">
23
- <strong><i class="dashicons dashicons-hidden"></i> Hide Css Element</strong>
24
- </td>
25
- </tr>
26
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
27
- <td class="restrict-column ppc-menu-checkbox">
28
- <input type="checkbox">
29
- </td>
30
- <td class="menu-column ppc-menu-item">
31
- <label>
32
- <span class="menu-item-link">
33
- <strong> — Welcome panel <small
34
- class="entry">(#welcome-panel)</small> &nbsp; <span
35
- class="ppc-custom-features-css-delete red-pointer"
36
- data-id="16188f4b317b0b"><small>(Delete)</small></span></strong></span>
37
- </label>
38
- </td>
39
- </tr>
40
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
41
- <td class="restrict-column ppc-menu-checkbox">
42
- <input type="checkbox">
43
- </td>
44
- <td class="menu-column ppc-menu-item">
45
- <label>
46
- <span class="menu-item-link restricted">
47
- <strong>
48
- — Woocomerce and site health <small
49
- class="entry">(#wc_admin_dashboard_setup, #dashboard_site_health)</small> &nbsp; <span
50
- class="ppc-custom-features-css-delete red-pointer"
51
- data-id="16188f4dfe6150"><small>(Delete)</small></span></strong></span>
52
- </label>
53
- </td>
54
- </tr>
55
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
56
- <td class="restrict-column ppc-menu-checkbox">
57
- <input type="checkbox">
58
- </td>
59
- <td class="menu-column ppc-menu-item">
60
- <label>
61
- <span class="menu-item-link">
62
- <strong>
63
- — Others <small
64
- class="entry">(#dashboard_activity, #dashboard_right_now,#dashboard_primary)</small> &nbsp; <span
65
- class="ppc-custom-features-css-delete red-pointer"
66
- data-id="16188f50c5b7b7"><small>(Delete)</small></span> </strong></span>
67
- </label>
68
- </td>
69
- </tr>
70
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row">
71
- <td colspan="2">
72
- <div class="pp-promo-upgrade-notice">
73
- <p>
74
- <?php esc_html_e('You can block pages by URL or hide Admin elements by entering a CSS class or ID. This feature is available in PublishPress Capabilities Pro.',
75
- 'capsman-enhanced'); ?>
76
- </p>
77
- <p>
78
- <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
79
- <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
80
- </a>
81
- </p>
82
- </div>
83
- </td>
84
- </tr>
85
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
86
- <td class="features-section-header" colspan="2">
87
- <strong><i class="dashicons dashicons-admin-links"></i> Blocked by URL </strong>
88
- </td>
89
- </tr>
90
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
91
- <td class="restrict-column ppc-menu-checkbox">
92
- <input type="checkbox">
93
- </td>
94
- <td class="menu-column ppc-menu-item">
95
- <label>
96
- <span class="menu-item-link">
97
- <strong>
98
- — Plugin add <small
99
- class="entry">(/wp-admin/plugin-install.php)</small> &nbsp; <span
100
- class="ppc-custom-features-url-delete red-pointer"
101
- data-id="16183aea9b16aa"><small>(Delete)</small></span> </strong></span>
102
- </label>
103
- </td>
104
- </tr>
105
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
106
- <td class="restrict-column ppc-menu-checkbox">
107
- <input type="checkbox">
108
- </td>
109
- <td class="menu-column ppc-menu-item">
110
- <label>
111
- <span class="menu-item-link restricted">
112
- <strong>
113
- — Some settings pages <small
114
- class="entry">(/wp-admin/options-general.php, /wp-admin/options-writing.php, /wp-admin/options-reading.php)</small> &nbsp; <span
115
- class="ppc-custom-features-url-delete red-pointer"
116
- data-id="16183aedcbab7b"><small>(Delete)</small></span> </strong></span>
117
- </label>
118
- </td>
119
- </tr>
120
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
121
- <td class="restrict-column ppc-menu-checkbox">
122
- <input type="checkbox">
123
- </td>
124
- <td class="menu-column ppc-menu-item">
125
- <label>
126
- <span class="menu-item-link">
127
- <strong>
128
- — TaxoPress Taxonomy Add <small
129
- class="entry">(/wp-admin/admin.php?page=st_taxonomies&amp;add=taxonomy)</small> &nbsp; <span
130
- class="ppc-custom-features-url-delete red-pointer"
131
- data-id="16183aefacc9bc"><small>(Delete)</small></span></strong></span>
132
- </label>
133
- </td>
134
- </tr>
135
-
136
- <?php
1
+ <?php
2
+ /**
3
+ * Capability Manager Admin Features Promo.
4
+ *
5
+ * Copyright 2020, PublishPress <help@publishpress.com>
6
+ *
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License
9
+ * version 2 as published by the Free Software Foundation.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ ?>
21
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
22
+ <td class="features-section-header" colspan="2">
23
+ <strong><i class="dashicons dashicons-hidden"></i> Hide Css Element</strong>
24
+ </td>
25
+ </tr>
26
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
27
+ <td class="restrict-column ppc-menu-checkbox">
28
+ <input type="checkbox">
29
+ </td>
30
+ <td class="menu-column ppc-menu-item">
31
+ <label>
32
+ <span class="menu-item-link">
33
+ <strong> — Welcome panel <small
34
+ class="entry">(#welcome-panel)</small> &nbsp; <span
35
+ class="ppc-custom-features-css-delete red-pointer"
36
+ data-id="16188f4b317b0b"><small>(Delete)</small></span></strong></span>
37
+ </label>
38
+ </td>
39
+ </tr>
40
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
41
+ <td class="restrict-column ppc-menu-checkbox">
42
+ <input type="checkbox">
43
+ </td>
44
+ <td class="menu-column ppc-menu-item">
45
+ <label>
46
+ <span class="menu-item-link restricted">
47
+ <strong>
48
+ — Woocomerce and site health <small
49
+ class="entry">(#wc_admin_dashboard_setup, #dashboard_site_health)</small> &nbsp; <span
50
+ class="ppc-custom-features-css-delete red-pointer"
51
+ data-id="16188f4dfe6150"><small>(Delete)</small></span></strong></span>
52
+ </label>
53
+ </td>
54
+ </tr>
55
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur hidecsselement">
56
+ <td class="restrict-column ppc-menu-checkbox">
57
+ <input type="checkbox">
58
+ </td>
59
+ <td class="menu-column ppc-menu-item">
60
+ <label>
61
+ <span class="menu-item-link">
62
+ <strong>
63
+ — Others <small
64
+ class="entry">(#dashboard_activity, #dashboard_right_now,#dashboard_primary)</small> &nbsp; <span
65
+ class="ppc-custom-features-css-delete red-pointer"
66
+ data-id="16188f50c5b7b7"><small>(Delete)</small></span> </strong></span>
67
+ </label>
68
+ </td>
69
+ </tr>
70
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row">
71
+ <td colspan="2">
72
+ <div class="pp-promo-upgrade-notice">
73
+ <p>
74
+ <?php esc_html_e('You can block pages by URL or hide Admin elements by entering a CSS class or ID. This feature is available in PublishPress Capabilities Pro.',
75
+ 'capsman-enhanced'); ?>
76
+ </p>
77
+ <p>
78
+ <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
79
+ <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
80
+ </a>
81
+ </p>
82
+ </div>
83
+ </td>
84
+ </tr>
85
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
86
+ <td class="features-section-header" colspan="2">
87
+ <strong><i class="dashicons dashicons-admin-links"></i> Blocked by URL </strong>
88
+ </td>
89
+ </tr>
90
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
91
+ <td class="restrict-column ppc-menu-checkbox">
92
+ <input type="checkbox">
93
+ </td>
94
+ <td class="menu-column ppc-menu-item">
95
+ <label>
96
+ <span class="menu-item-link">
97
+ <strong>
98
+ — Plugin add <small
99
+ class="entry">(/wp-admin/plugin-install.php)</small> &nbsp; <span
100
+ class="ppc-custom-features-url-delete red-pointer"
101
+ data-id="16183aea9b16aa"><small>(Delete)</small></span> </strong></span>
102
+ </label>
103
+ </td>
104
+ </tr>
105
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
106
+ <td class="restrict-column ppc-menu-checkbox">
107
+ <input type="checkbox">
108
+ </td>
109
+ <td class="menu-column ppc-menu-item">
110
+ <label>
111
+ <span class="menu-item-link restricted">
112
+ <strong>
113
+ — Some settings pages <small
114
+ class="entry">(/wp-admin/options-general.php, /wp-admin/options-writing.php, /wp-admin/options-reading.php)</small> &nbsp; <span
115
+ class="ppc-custom-features-url-delete red-pointer"
116
+ data-id="16183aedcbab7b"><small>(Delete)</small></span> </strong></span>
117
+ </label>
118
+ </td>
119
+ </tr>
120
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur blockedbyurl">
121
+ <td class="restrict-column ppc-menu-checkbox">
122
+ <input type="checkbox">
123
+ </td>
124
+ <td class="menu-column ppc-menu-item">
125
+ <label>
126
+ <span class="menu-item-link">
127
+ <strong>
128
+ — TaxoPress Taxonomy Add <small
129
+ class="entry">(/wp-admin/admin.php?page=st_taxonomies&amp;add=taxonomy)</small> &nbsp; <span
130
+ class="ppc-custom-features-url-delete red-pointer"
131
+ data-id="16183aefacc9bc"><small>(Delete)</small></span></strong></span>
132
+ </label>
133
+ </td>
134
+ </tr>
135
+
136
+ <?php
includes-core/admin-menus-promo.php CHANGED
@@ -1,157 +1,157 @@
1
- <?php
2
- /**
3
- * Capability Manager Admin Menu Permissions.
4
- * Hide and block selected Admin Menus per-role.
5
- *
6
- * Copyright 2020, PublishPress <help@publishpress.com>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * version 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
- global $capsman, $menu, $submenu;
22
- $capsman->generateNames();
23
- $roles = $capsman->roles;
24
- $default_role = $capsman->current;
25
- ?>
26
-
27
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper-promo">
28
- <div id="icon-capsman-admin" class="icon32"></div>
29
- <h2><?php esc_html_e('Admin Menu Restrictions', 'capsman-enhanced'); ?></h2>
30
-
31
- <form method="post" id="ppc-admin-menu-form" action="admin.php?page=pp-capabilities-admin-menus">
32
- <fieldset>
33
- <table id="akmin">
34
- <tr>
35
- <td class="content">
36
- <div class="publishpress-filters">
37
- <select name="ppc-admin-menu-role" class="ppc-admin-menu-role">
38
- <?php
39
- foreach ($roles as $role_name => $name) :
40
- $name = translate_user_role($name);
41
- ?>
42
- <option value="<?php echo esc_attr($role_name);?>" <?php selected($default_role, $role_name);?>><?php echo esc_html($name);?></option>
43
- <?php
44
- endforeach;
45
- ?>
46
- </select> &nbsp;
47
- <input type="submit" name="admin-menu-submit"
48
- value="<?php esc_attr_e('Save Changes', 'capsman-enhanced') ?>"
49
- class="button-primary ppc-admin-menu-submit" style="float:right" />
50
- </div>
51
- <div id="pp-capability-menu-wrapper" class="postbox" style="box-shadow: none;">
52
- <div class="pp-capability-menus-promo">
53
- <div class="pp-capability-menus-promo-inner">
54
- <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-admin-menus-desktop.jpg');?>" class="pp-capability-desktop" />
55
- <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-admin-menus-mobile.jpg');?>" class="pp-capability-mobile" />
56
- <div class="pp-capability-menus-promo-content">
57
- <p>
58
- <?php esc_html_e('You can restrict access to admin menu screens. This feature is available in PublishPress Capabilities Pro', 'capsman-enhanced'); ?>
59
- </p>
60
- <p>
61
- <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
62
- <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
63
- </a>
64
- </p>
65
- </div>
66
- <div class="pp-capability-menus-promo-gradient"></div>
67
- </div>
68
- </div>
69
- </div>
70
- </td>
71
- </tr>
72
- </table>
73
-
74
- </fieldset>
75
-
76
- </form>
77
-
78
- <script type="text/javascript">
79
- /* <![CDATA[ */
80
- jQuery(document).ready(function ($) {
81
-
82
- // -------------------------------------------------------------
83
- // reload page for instant reflection if user is updating own role
84
- // -------------------------------------------------------------
85
- <?php if((int)$ppc_admin_menu_reload === 1){ ?>
86
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=' . $default_role . '')); ?>';
87
- <?php } ?>
88
-
89
- // -------------------------------------------------------------
90
- // Set form action attribute to include role
91
- // -------------------------------------------------------------
92
- $('#ppc-admin-menu-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=' . $default_role . '')); ?>');
93
-
94
- // -------------------------------------------------------------
95
- // Instant restricted item class
96
- // -------------------------------------------------------------
97
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function () {
98
-
99
- if ($(this).is(':checked')) {
100
- //add class if value is checked
101
- $(this).parent().parent().find('.menu-item-link').addClass('restricted');
102
-
103
- //toggle all checkbox
104
- if ($(this).hasClass('check-all-menu-item')) {
105
- $("input[type='checkbox'][name='pp_cababilities_disabled_menu[]']").prop('checked', true);
106
- $("input[type='checkbox'][name='pp_cababilities_disabled_child_menu[]']").prop('checked', true);
107
- $('.menu-item-link').addClass('restricted');
108
- } else {
109
- $('.check-all-menu-link').removeClass('restricted');
110
- $('.check-all-menu-item').prop('checked', false);
111
- }
112
-
113
- } else {
114
- //unchecked value
115
- $(this).parent().parent().find('.menu-item-link').removeClass('restricted');
116
-
117
- //toggle all checkbox
118
- if ($(this).hasClass('check-all-menu-item')) {
119
- $("input[type='checkbox'][name='pp_cababilities_disabled_menu[]']").prop('checked', false);
120
- $("input[type='checkbox'][name='pp_cababilities_disabled_child_menu[]']").prop('checked', false);
121
- $('.menu-item-link').removeClass('restricted');
122
- } else {
123
- $('.check-all-menu-link').removeClass('restricted');
124
- $('.check-all-menu-item').prop('checked', false);
125
- }
126
-
127
- }
128
-
129
- });
130
-
131
- // -------------------------------------------------------------
132
- // Load selected roles menu
133
- // -------------------------------------------------------------
134
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-admin-menu-role', function () {
135
-
136
- //disable select
137
- $('.pp-capability-menus-wrapper .ppc-admin-menu-role').attr('disabled', true);
138
-
139
- //hide button
140
- $('.pp-capability-menus-wrapper .ppc-admin-menu-submit').hide();
141
-
142
- //show loading
143
- $('#pp-capability-menu-wrapper').html('<img src="<?php echo esc_url_raw($capsman->mod_url . '/images/loader-black.gif'); ?>" alt="loading...">');
144
-
145
- //go to url
146
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=')); ?>' + $(this).val() + '';
147
- });
148
- });
149
- /* ]]> */
150
- </script>
151
-
152
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
153
- cme_publishpressFooter();
154
- }
155
- ?>
156
- </div>
157
- <?php
1
+ <?php
2
+ /**
3
+ * Capability Manager Admin Menu Permissions.
4
+ * Hide and block selected Admin Menus per-role.
5
+ *
6
+ * Copyright 2020, PublishPress <help@publishpress.com>
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * version 2 as published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+ global $capsman, $menu, $submenu;
22
+ $capsman->generateNames();
23
+ $roles = $capsman->roles;
24
+ $default_role = $capsman->current;
25
+ ?>
26
+
27
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper-promo">
28
+ <div id="icon-capsman-admin" class="icon32"></div>
29
+ <h2><?php esc_html_e('Admin Menu Restrictions', 'capsman-enhanced'); ?></h2>
30
+
31
+ <form method="post" id="ppc-admin-menu-form" action="admin.php?page=pp-capabilities-admin-menus">
32
+ <fieldset>
33
+ <table id="akmin">
34
+ <tr>
35
+ <td class="content">
36
+ <div class="publishpress-filters">
37
+ <select name="ppc-admin-menu-role" class="ppc-admin-menu-role">
38
+ <?php
39
+ foreach ($roles as $role_name => $name) :
40
+ $name = translate_user_role($name);
41
+ ?>
42
+ <option value="<?php echo esc_attr($role_name);?>" <?php selected($default_role, $role_name);?>><?php echo esc_html($name);?></option>
43
+ <?php
44
+ endforeach;
45
+ ?>
46
+ </select> &nbsp;
47
+ <input type="submit" name="admin-menu-submit"
48
+ value="<?php esc_attr_e('Save Changes', 'capsman-enhanced') ?>"
49
+ class="button-primary ppc-admin-menu-submit" style="float:right" />
50
+ </div>
51
+ <div id="pp-capability-menu-wrapper" class="postbox" style="box-shadow: none;">
52
+ <div class="pp-capability-menus-promo">
53
+ <div class="pp-capability-menus-promo-inner">
54
+ <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-admin-menus-desktop.jpg');?>" class="pp-capability-desktop" />
55
+ <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-admin-menus-mobile.jpg');?>" class="pp-capability-mobile" />
56
+ <div class="pp-capability-menus-promo-content">
57
+ <p>
58
+ <?php esc_html_e('You can restrict access to admin menu screens. This feature is available in PublishPress Capabilities Pro', 'capsman-enhanced'); ?>
59
+ </p>
60
+ <p>
61
+ <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
62
+ <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
63
+ </a>
64
+ </p>
65
+ </div>
66
+ <div class="pp-capability-menus-promo-gradient"></div>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </td>
71
+ </tr>
72
+ </table>
73
+
74
+ </fieldset>
75
+
76
+ </form>
77
+
78
+ <script type="text/javascript">
79
+ /* <![CDATA[ */
80
+ jQuery(document).ready(function ($) {
81
+
82
+ // -------------------------------------------------------------
83
+ // reload page for instant reflection if user is updating own role
84
+ // -------------------------------------------------------------
85
+ <?php if((int)$ppc_admin_menu_reload === 1){ ?>
86
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=' . $default_role . '')); ?>';
87
+ <?php } ?>
88
+
89
+ // -------------------------------------------------------------
90
+ // Set form action attribute to include role
91
+ // -------------------------------------------------------------
92
+ $('#ppc-admin-menu-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=' . $default_role . '')); ?>');
93
+
94
+ // -------------------------------------------------------------
95
+ // Instant restricted item class
96
+ // -------------------------------------------------------------
97
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function () {
98
+
99
+ if ($(this).is(':checked')) {
100
+ //add class if value is checked
101
+ $(this).parent().parent().find('.menu-item-link').addClass('restricted');
102
+
103
+ //toggle all checkbox
104
+ if ($(this).hasClass('check-all-menu-item')) {
105
+ $("input[type='checkbox'][name='pp_cababilities_disabled_menu[]']").prop('checked', true);
106
+ $("input[type='checkbox'][name='pp_cababilities_disabled_child_menu[]']").prop('checked', true);
107
+ $('.menu-item-link').addClass('restricted');
108
+ } else {
109
+ $('.check-all-menu-link').removeClass('restricted');
110
+ $('.check-all-menu-item').prop('checked', false);
111
+ }
112
+
113
+ } else {
114
+ //unchecked value
115
+ $(this).parent().parent().find('.menu-item-link').removeClass('restricted');
116
+
117
+ //toggle all checkbox
118
+ if ($(this).hasClass('check-all-menu-item')) {
119
+ $("input[type='checkbox'][name='pp_cababilities_disabled_menu[]']").prop('checked', false);
120
+ $("input[type='checkbox'][name='pp_cababilities_disabled_child_menu[]']").prop('checked', false);
121
+ $('.menu-item-link').removeClass('restricted');
122
+ } else {
123
+ $('.check-all-menu-link').removeClass('restricted');
124
+ $('.check-all-menu-item').prop('checked', false);
125
+ }
126
+
127
+ }
128
+
129
+ });
130
+
131
+ // -------------------------------------------------------------
132
+ // Load selected roles menu
133
+ // -------------------------------------------------------------
134
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-admin-menu-role', function () {
135
+
136
+ //disable select
137
+ $('.pp-capability-menus-wrapper .ppc-admin-menu-role').attr('disabled', true);
138
+
139
+ //hide button
140
+ $('.pp-capability-menus-wrapper .ppc-admin-menu-submit').hide();
141
+
142
+ //show loading
143
+ $('#pp-capability-menu-wrapper').html('<img src="<?php echo esc_url_raw($capsman->mod_url . '/images/loader-black.gif'); ?>" alt="loading...">');
144
+
145
+ //go to url
146
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-menus&role=')); ?>' + $(this).val() + '';
147
+ });
148
+ });
149
+ /* ]]> */
150
+ </script>
151
+
152
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
153
+ cme_publishpressFooter();
154
+ }
155
+ ?>
156
+ </div>
157
+ <?php
includes-core/editor-features-promo.php CHANGED
@@ -1,147 +1,126 @@
1
- <?php
2
- /**
3
- * Capability Manager Editor Features Promo.
4
- *
5
- * Copyright 2020, PublishPress <help@publishpress.com>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
- */
19
-
20
- ?>
21
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
22
-
23
- <td colspan="3">
24
- <h4 class="ppc-menu-row-section"><?php esc_html_e('Metaboxes', 'capsman-enhanced'); ?></h4>
25
- </td>
26
- </tr>
27
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
28
-
29
- <td class="menu-column ppc-menu-item">
30
-
31
- <span class="gutenberg menu-item-link">
32
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Checklist', 'capsman-enhanced'); ?> </strong></span>
33
- </td>
34
-
35
- <td class="restrict-column ppc-menu-checkbox">
36
- <input type="checkbox">
37
- </td>
38
- <td class="restrict-column ppc-menu-checkbox">
39
- <input type="checkbox">
40
- </td>
41
- </tr>
42
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
43
- <td class="menu-column ppc-menu-item">
44
- <span class="gutenberg menu-item-link restricted">
45
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Editorial Comments', 'capsman-enhanced'); ?></strong></span>
46
- </td>
47
-
48
- <td class="restrict-column ppc-menu-checkbox">
49
- <input type="checkbox">
50
- </td>
51
- <td class="restrict-column ppc-menu-checkbox">
52
- <input type="checkbox">
53
- </td>
54
- </tr>
55
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
56
- <td class="menu-column ppc-menu-item">
57
- <span class="gutenberg menu-item-link">
58
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Notifications', 'capsman-enhanced'); ?></strong></span>
59
- </td>
60
-
61
- <td class="restrict-column ppc-menu-checkbox">
62
- <input type="checkbox">
63
- </td>
64
- <td class="restrict-column ppc-menu-checkbox">
65
- <input type="checkbox">
66
- </td>
67
- </tr>
68
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
69
- <td class="menu-column ppc-menu-item">
70
- <span class="gutenberg menu-item-link">
71
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('TaxoPress - Settings', 'capsman-enhanced'); ?></strong></span>
72
- </td>
73
-
74
- <td class="restrict-column ppc-menu-checkbox">
75
- <input type="checkbox">
76
- </td>
77
- <td class="restrict-column ppc-menu-checkbox">
78
- <input type="checkbox">
79
- </td>
80
- </tr>
81
-
82
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row">
83
- <td colspan="3">
84
- <div class="pp-promo-upgrade-notice">
85
- <p>
86
- <?php esc_html_e('You can hide plugin metaboxes. You can also hide specific items by entering their CSS class or ID. This feature is available in PublishPress Capabilities Pro.',
87
- 'capsman-enhanced'); ?>
88
- </p>
89
- <p>
90
- <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
91
- <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
92
- </a>
93
- </p>
94
- </div>
95
- </td>
96
- </tr>
97
-
98
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
99
-
100
- <td colspan="3">
101
- <h4 class="ppc-menu-row-section"><?php esc_html_e('Custom Items', 'capsman-enhanced'); ?></h4>
102
- </td>
103
- </tr>
104
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
105
- <td class="menu-column ppc-menu-item">
106
- <span class="gutenberg menu-item-link">
107
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Custom item one', 'capsman-enhanced'); ?> <small>(.custom-plugin-item, #custom-plugin-item)</small> &nbsp; <span
108
- class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span></strong></span>
109
- </td>
110
-
111
- <td class="restrict-column ppc-menu-checkbox">
112
- <input type="checkbox">
113
- </td>
114
- <td class="restrict-column ppc-menu-checkbox">
115
- <input type="checkbox">
116
- </td>
117
- </tr>
118
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
119
- <td class="menu-column ppc-menu-item">
120
- <span class="gutenberg menu-item-link restricted">
121
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Permalink: Descriptive Caption', 'capsman-enhanced'); ?> <small>(.editor-post-link p)</small> &nbsp; <span
122
- class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span> </strong></span>
123
- </td>
124
-
125
- <td class="restrict-column ppc-menu-checkbox">
126
- <input type="checkbox">
127
- </td>
128
- <td class="restrict-column ppc-menu-checkbox">
129
- <input type="checkbox">
130
- </td>
131
- </tr>
132
- <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
133
- <td class="menu-column ppc-menu-item">
134
- <span class="gutenberg menu-item-link">
135
- <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Page Attributes: Order', 'capsman-enhanced'); ?> <small>(.editor-page-attributes__order)</small> &nbsp; <span class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span> </strong></span>
136
- </td>
137
-
138
- <td class="restrict-column ppc-menu-checkbox">
139
- <input type="checkbox">
140
- </td>
141
- <td class="restrict-column ppc-menu-checkbox">
142
- <input type="checkbox">
143
- </td>
144
- </tr>
145
-
146
-
147
- <?php
1
+ <?php
2
+ /**
3
+ * Capability Manager Editor Features Promo.
4
+ *
5
+ * Copyright 2020, PublishPress <help@publishpress.com>
6
+ *
7
+ * This program is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU General Public License
9
+ * version 2 as published by the Free Software Foundation.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+ ?>
21
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
22
+
23
+ <td colspan="2">
24
+ <h4 class="ppc-menu-row-section"><?php esc_html_e('Metaboxes', 'capsman-enhanced'); ?></h4>
25
+ </td>
26
+ </tr>
27
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
28
+
29
+ <td class="menu-column ppc-menu-item">
30
+
31
+ <span class="gutenberg menu-item-link">
32
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Checklist', 'capsman-enhanced'); ?> </strong></span>
33
+ </td>
34
+
35
+ <td class="restrict-column ppc-menu-checkbox">
36
+ <input type="checkbox">
37
+ </td>
38
+ </tr>
39
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
40
+ <td class="menu-column ppc-menu-item">
41
+ <span class="gutenberg menu-item-link restricted">
42
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Editorial Comments', 'capsman-enhanced'); ?></strong></span>
43
+ </td>
44
+
45
+ <td class="restrict-column ppc-menu-checkbox">
46
+ <input type="checkbox">
47
+ </td>
48
+ </tr>
49
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
50
+ <td class="menu-column ppc-menu-item">
51
+ <span class="gutenberg menu-item-link">
52
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Notifications', 'capsman-enhanced'); ?></strong></span>
53
+ </td>
54
+
55
+ <td class="restrict-column ppc-menu-checkbox">
56
+ <input type="checkbox">
57
+ </td>
58
+ </tr>
59
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
60
+ <td class="menu-column ppc-menu-item">
61
+ <span class="gutenberg menu-item-link">
62
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('TaxoPress - Settings', 'capsman-enhanced'); ?></strong></span>
63
+ </td>
64
+
65
+ <td class="restrict-column ppc-menu-checkbox">
66
+ <input type="checkbox">
67
+ </td>
68
+ </tr>
69
+
70
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row">
71
+ <td colspan="2">
72
+ <div class="pp-promo-upgrade-notice">
73
+ <p>
74
+ <?php esc_html_e('You can hide plugin metaboxes. You can also hide specific items by entering their CSS class or ID. This feature is available in PublishPress Capabilities Pro.',
75
+ 'capsman-enhanced'); ?>
76
+ </p>
77
+ <p>
78
+ <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
79
+ <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
80
+ </a>
81
+ </p>
82
+ </div>
83
+ </td>
84
+ </tr>
85
+
86
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
87
+
88
+ <td colspan="2">
89
+ <h4 class="ppc-menu-row-section"><?php esc_html_e('Custom Items', 'capsman-enhanced'); ?></h4>
90
+ </td>
91
+ </tr>
92
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
93
+ <td class="menu-column ppc-menu-item">
94
+ <span class="gutenberg menu-item-link">
95
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Custom item one', 'capsman-enhanced'); ?> <small>(.custom-plugin-item, #custom-plugin-item)</small> &nbsp; <span
96
+ class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span></strong></span>
97
+ </td>
98
+
99
+ <td class="restrict-column ppc-menu-checkbox">
100
+ <input type="checkbox">
101
+ </td>
102
+ </tr>
103
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
104
+ <td class="menu-column ppc-menu-item">
105
+ <span class="gutenberg menu-item-link restricted">
106
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Permalink: Descriptive Caption', 'capsman-enhanced'); ?> <small>(.editor-post-link p)</small> &nbsp; <span
107
+ class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span> </strong></span>
108
+ </td>
109
+
110
+ <td class="restrict-column ppc-menu-checkbox">
111
+ <input type="checkbox">
112
+ </td>
113
+ </tr>
114
+ <tr class="ppc-menu-row parent-menu pp-promo-overlay-row pp-promo-blur">
115
+ <td class="menu-column ppc-menu-item">
116
+ <span class="gutenberg menu-item-link">
117
+ <strong><i class="dashicons dashicons-arrow-right"></i> <?php esc_html_e('Page Attributes: Order', 'capsman-enhanced'); ?> <small>(.editor-page-attributes__order)</small> &nbsp; <span class="ppc-custom-features-delete"><small>(<?php esc_html_e('Delete', 'capsman-enhanced'); ?>)</small></span> </strong></span>
118
+ </td>
119
+
120
+ <td class="restrict-column ppc-menu-checkbox">
121
+ <input type="checkbox">
122
+ </td>
123
+ </tr>
124
+
125
+
126
+ <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes-core/nav-menus-promo.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
- /**
3
- * Capability Manager Nav Menus Permission.
4
- * Nav menus permission and visibility per roles.
5
- *
6
- * Copyright 2020, PublishPress <help@publishpress.com>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * version 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
- global $capsman, $menu, $submenu;
22
- $capsman->generateNames();
23
- $roles = $capsman->roles;
24
- $default_role = $capsman->current;
25
- ?>
26
-
27
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper-promo">
28
- <div id="icon-capsman-admin" class="icon32"></div>
29
- <h2><?php esc_html_e('Navigation Menu Restrictions', 'capsman-enhanced'); ?></h2>
30
-
31
- <form method="post" id="ppc-nav-menu-form" action="admin.php?page=pp-capabilities-nav-menus">
32
- <fieldset>
33
- <table id="akmin">
34
- <tr>
35
- <td class="content">
36
-
37
- <div class="publishpress-filters">
38
- <select name="ppc-nav-menu-role" class="ppc-nav-menu-role">
39
- <optgroup label="Roles">
40
- <?php
41
- foreach ($roles as $role_name => $name) {
42
- $name = translate_user_role($name);
43
- ?>
44
- <option value="<?php echo esc_attr($role_name); ?>" <?php selected($default_role, $role_name); ?>> <?php echo esc_html($name); ?>
45
- &nbsp;
46
- </option>
47
- <?php } ?>
48
- </optgroup>
49
-
50
- </select> &nbsp;
51
- <input type="submit" name="nav-menu-submit"
52
- value="<?php esc_attr_e('Save Changes', 'capsman-enhanced') ?>"
53
- class="button-primary ppc-nav-menu-submit" style="float:right" />
54
- </div>
55
-
56
- <div id="pp-capability-menu-wrapper" class="postbox" style="box-shadow: none;">
57
- <div class="pp-capability-menus-promo">
58
- <div class="pp-capability-menus-promo-inner">
59
- <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-nav-menus-desktop.jpg');?>" class="pp-capability-desktop" />
60
- <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-nav-menus-mobile.jpg');?>" class="pp-capability-mobile" />
61
- <div class="pp-capability-menus-promo-content">
62
- <p>
63
- <?php esc_html_e('You can restrict access to navigation menus. This feature is available in PublishPress Capabilities Pro', 'capsman-enhanced'); ?>
64
- </p>
65
- <p>
66
- <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
67
- <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
68
- </a>
69
- </p>
70
- </div>
71
- <div class="pp-capability-menus-promo-gradient"></div>
72
- </div>
73
- </div>
74
- </div>
75
- </td>
76
- </tr>
77
- </table>
78
-
79
- </fieldset>
80
-
81
- </form>
82
-
83
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
84
- cme_publishpressFooter();
85
- }
86
- ?>
87
- </div>
88
- <?php
1
+ <?php
2
+ /**
3
+ * Capability Manager Nav Menus Permission.
4
+ * Nav menus permission and visibility per roles.
5
+ *
6
+ * Copyright 2020, PublishPress <help@publishpress.com>
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * version 2 as published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+ global $capsman, $menu, $submenu;
22
+ $capsman->generateNames();
23
+ $roles = $capsman->roles;
24
+ $default_role = $capsman->current;
25
+ ?>
26
+
27
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper-promo">
28
+ <div id="icon-capsman-admin" class="icon32"></div>
29
+ <h2><?php esc_html_e('Navigation Menu Restrictions', 'capsman-enhanced'); ?></h2>
30
+
31
+ <form method="post" id="ppc-nav-menu-form" action="admin.php?page=pp-capabilities-nav-menus">
32
+ <fieldset>
33
+ <table id="akmin">
34
+ <tr>
35
+ <td class="content">
36
+
37
+ <div class="publishpress-filters">
38
+ <select name="ppc-nav-menu-role" class="ppc-nav-menu-role">
39
+ <optgroup label="Roles">
40
+ <?php
41
+ foreach ($roles as $role_name => $name) {
42
+ $name = translate_user_role($name);
43
+ ?>
44
+ <option value="<?php echo esc_attr($role_name); ?>" <?php selected($default_role, $role_name); ?>> <?php echo esc_html($name); ?>
45
+ &nbsp;
46
+ </option>
47
+ <?php } ?>
48
+ </optgroup>
49
+
50
+ </select> &nbsp;
51
+ <input type="submit" name="nav-menu-submit"
52
+ value="<?php esc_attr_e('Save Changes', 'capsman-enhanced') ?>"
53
+ class="button-primary ppc-nav-menu-submit" style="float:right" />
54
+ </div>
55
+
56
+ <div id="pp-capability-menu-wrapper" class="postbox" style="box-shadow: none;">
57
+ <div class="pp-capability-menus-promo">
58
+ <div class="pp-capability-menus-promo-inner">
59
+ <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-nav-menus-desktop.jpg');?>" class="pp-capability-desktop" />
60
+ <img src="<?php echo esc_url_raw(plugin_dir_url(CME_FILE) . 'includes-core/pp-capabilities-nav-menus-mobile.jpg');?>" class="pp-capability-mobile" />
61
+ <div class="pp-capability-menus-promo-content">
62
+ <p>
63
+ <?php esc_html_e('You can restrict access to navigation menus. This feature is available in PublishPress Capabilities Pro', 'capsman-enhanced'); ?>
64
+ </p>
65
+ <p>
66
+ <a href="https://publishpress.com/links/capabilities-banner" target="_blank">
67
+ <?php esc_html_e('Upgrade to Pro', 'capsman-enhanced'); ?>
68
+ </a>
69
+ </p>
70
+ </div>
71
+ <div class="pp-capability-menus-promo-gradient"></div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </td>
76
+ </tr>
77
+ </table>
78
+
79
+ </fieldset>
80
+
81
+ </form>
82
+
83
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
84
+ cme_publishpressFooter();
85
+ }
86
+ ?>
87
+ </div>
88
+ <?php
includes/admin-load.php CHANGED
@@ -1,330 +1,353 @@
1
- <?php
2
-
3
- /*
4
- * PublishPress Capabilities [Free]
5
- *
6
- * Admin execution controller: menu registration and other filters and actions that need to be loaded for every wp-admin URL
7
- *
8
- * This module should not include full functions related to our own plugin screens.
9
- * Instead, use these filter and action handlers to load other classes when needed.
10
- *
11
- */
12
- class PP_Capabilities_Admin_UI {
13
- function __construct() {
14
- global $pagenow;
15
-
16
- /**
17
- * The class responsible for handling notifications
18
- */
19
- require_once (dirname(CME_FILE) . '/classes/pp-capabilities-notices.php');
20
-
21
- add_action('init', [$this, 'featureRestrictionsGutenberg']);
22
-
23
- if (is_admin()) {
24
- add_action('admin_init', [$this, 'featureRestrictionsClassic']);
25
- }
26
-
27
- add_action('admin_enqueue_scripts', [$this, 'adminScripts'], 100);
28
- add_action('admin_print_scripts', [$this, 'adminPrintScripts']);
29
-
30
- add_action('profile_update', [$this, 'action_profile_update'], 10, 2);
31
-
32
- if (is_multisite()) {
33
- add_action('add_user_to_blog', [$this, 'action_profile_update'], 9);
34
- } else {
35
- add_action('user_register', [$this, 'action_profile_update'], 9);
36
- }
37
-
38
- if (is_admin() && (isset($_REQUEST['page']) && (in_array($_REQUEST['page'], ['pp-capabilities', 'pp-capabilities-backup', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-editor-features', 'pp-capabilities-nav-menus', 'pp-capabilities-settings', 'pp-capabilities-admin-features']))
39
-
40
- || (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], ['pp-roles-add-role', 'pp-roles-delete-role', 'pp-roles-hide-role', 'pp-roles-unhide-role']))
41
- || ( ! empty($_SERVER['SCRIPT_NAME']) && strpos(sanitize_text_field($_SERVER['SCRIPT_NAME']), 'p-admin/plugins.php' ) && ! empty($_REQUEST['action'] ) )
42
- || ( isset($_GET['action']) && ('reset-defaults' == $_GET['action']) && isset($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'capsman-reset-defaults') )
43
- || in_array( $pagenow, array( 'users.php', 'user-edit.php', 'profile.php', 'user-new.php' ) )
44
- ) ) {
45
- global $capsman;
46
-
47
- // Run the plugin
48
- require_once ( dirname(CME_FILE) . '/framework/lib/formating.php' );
49
- require_once ( dirname(CME_FILE) . '/framework/lib/users.php' );
50
-
51
- require_once ( dirname(CME_FILE) . '/includes/manager.php' );
52
- $capsman = new CapabilityManager();
53
- } else {
54
- add_action( 'admin_menu', [$this, 'cmeSubmenus'], 20 );
55
- }
56
-
57
- add_action('init', function() { // late execution avoids clash with autoloaders in other plugins
58
- global $pagenow;
59
-
60
- if ((($pagenow == 'admin.php') && isset($_GET['page']) && in_array($_GET['page'], ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-backup'])) // @todo: CSS for button alignment in Editor Features, Admin Features
61
- || (defined('DOING_AJAX') && DOING_AJAX && !empty($_REQUEST['action']) && (false !== strpos(sanitize_key($_REQUEST['action']), 'capability-manager-enhanced')))
62
- ) {
63
- if (!class_exists('\PublishPress\WordPressReviews\ReviewsController')) {
64
- include_once PUBLISHPRESS_CAPS_ABSPATH . '/vendor/publishpress/wordpress-reviews/ReviewsController.php';
65
- }
66
-
67
- if (class_exists('\PublishPress\WordPressReviews\ReviewsController')) {
68
- $reviews = new \PublishPress\WordPressReviews\ReviewsController(
69
- 'capability-manager-enhanced',
70
- 'PublishPress Capabilities',
71
- plugin_dir_url(CME_FILE) . 'common/img/capabilities-wp-logo.png'
72
- );
73
-
74
- add_filter('publishpress_wp_reviews_display_banner_capability-manager-enhanced', [$this, 'shouldDisplayBanner']);
75
-
76
- $reviews->init();
77
- }
78
- }
79
- });
80
-
81
-
82
- add_filter('pp_capabilities_feature_post_types', [$this, 'fltEditorFeaturesPostTypes'], 5);
83
- }
84
-
85
- public function fltEditorFeaturesPostTypes($def_post_types) {
86
- $type_args = defined('PP_CAPABILITIES_PRIVATE_TYPES') ? [] : ['public' => true];
87
- $def_post_types = array_merge($def_post_types, get_post_types($type_args));
88
-
89
- unset($def_post_types['attachment']);
90
-
91
- if ((count($def_post_types) > 14) && !defined('PP_CAPABILITIES_UNLIMITED_FEATURE_TYPES')) {
92
- $custom_types = array_diff($def_post_types, ['post', 'page']);
93
- $def_post_types = array_merge(['post', 'page'], array_slice($custom_types, 0, 12));
94
- }
95
-
96
- return $def_post_types;
97
- }
98
-
99
- public function shouldDisplayBanner() {
100
- global $pagenow;
101
-
102
- return ($pagenow == 'admin.php') && isset($_GET['page']) && in_array($_GET['page'], ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-backup']);
103
- }
104
-
105
- private function applyFeatureRestrictions($editor = 'gutenberg') {
106
- global $pagenow;
107
-
108
- if (is_multisite() && is_super_admin() && !defined('PP_CAPABILITIES_RESTRICT_SUPER_ADMIN')) {
109
- return;
110
- }
111
-
112
- // Return if not a post editor request
113
- if (!in_array($pagenow, ['post.php', 'post-new.php'])) {
114
- return;
115
- }
116
-
117
- static $def_post_types; // avoid redundant filter application
118
-
119
- if (!isset($def_post_types)) {
120
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
121
- }
122
-
123
- $post_type = pp_capabilities_get_post_type();
124
-
125
- // Return if not a supported post type
126
- if (in_array($post_type, apply_filters('pp_capabilities_unsupported_post_types', ['attachment']))) {
127
- return;
128
- }
129
-
130
- switch ($editor) {
131
- case 'gutenberg':
132
- if (_pp_capabilities_is_block_editor_active()) {
133
- require_once ( dirname(CME_FILE) . '/includes/features/restrict-editor-features.php' );
134
- PP_Capabilities_Post_Features::applyRestrictions($post_type);
135
- }
136
-
137
- break;
138
-
139
- case 'classic':
140
- if (!_pp_capabilities_is_block_editor_active()) {
141
- require_once ( dirname(CME_FILE) . '/includes/features/restrict-editor-features.php' );
142
- PP_Capabilities_Post_Features::adminInitClassic($post_type);
143
- }
144
- }
145
- }
146
-
147
- function featureRestrictionsGutenberg() {
148
- $this->applyFeatureRestrictions();
149
- }
150
-
151
- function featureRestrictionsClassic() {
152
- $this->applyFeatureRestrictions('classic');
153
- }
154
-
155
- function adminScripts() {
156
- global $publishpress;
157
-
158
- if (function_exists('get_current_screen') && (!defined('PUBLISHPRESS_VERSION') || empty($publishpress) || empty($publishpress->modules) || empty($publishpress->modules->roles))) {
159
- $screen = get_current_screen();
160
-
161
- if ('user-edit' === $screen->base || ('user' === $screen->base && 'add' === $screen->action && defined('PP_CAPABILITIES_ADD_USER_MULTI_ROLES'))) {
162
- // Check if we are on the user's profile page
163
- wp_enqueue_script(
164
- 'pp-capabilities-chosen-js',
165
- plugin_dir_url(CME_FILE) . 'common/libs/chosen-v1.8.7/chosen.jquery.js',
166
- ['jquery'],
167
- CAPSMAN_VERSION
168
- );
169
-
170
- wp_enqueue_script(
171
- 'pp-capabilities-roles-profile-js',
172
- plugin_dir_url(CME_FILE) . 'common/js/profile.js',
173
- ['jquery', 'pp-capabilities-chosen-js'],
174
- CAPSMAN_VERSION
175
- );
176
-
177
- wp_enqueue_style(
178
- 'pp-capabilities-chosen-css',
179
- plugin_dir_url(CME_FILE) . 'common/libs/chosen-v1.8.7/chosen.css',
180
- false,
181
- CAPSMAN_VERSION
182
- );
183
- wp_enqueue_style(
184
- 'pp-capabilities-roles-profile-css',
185
- plugin_dir_url(CME_FILE) . 'common/css/profile.css',
186
- ['pp-capabilities-chosen-css'],
187
- CAPSMAN_VERSION
188
- );
189
-
190
- $roles = !empty($_GET['user_id']) ? $this->getUsersRoles((int) $_GET['user_id']) : [];
191
-
192
- if (empty($roles)) {
193
- $roles = (array) get_option('default_role');
194
- }
195
-
196
- wp_localize_script(
197
- 'pp-capabilities-roles-profile-js',
198
- 'ppCapabilitiesProfileData',
199
- [
200
- 'selected_roles' => $roles
201
- ]
202
- );
203
- }
204
- }
205
- }
206
-
207
- function adminPrintScripts() {
208
- // Counteract overzealous menu icon styling in PublishPress <= 3.2.0 :)
209
- if (defined('PUBLISHPRESS_VERSION') && version_compare(constant('PUBLISHPRESS_VERSION'), '3.2.0', '<=') && defined('PP_CAPABILITIES_FIX_ADMIN_ICON')):?>
210
- <style type="text/css">
211
- #toplevel_page_pp-capabilities .dashicons-before::before, #toplevel_page_pp-capabilities .wp-has-current-submenu .dashicons-before::before {
212
- background-image: inherit !important;
213
- content: "\f112" !important;
214
- }
215
- </style>
216
- <?php endif;
217
- }
218
-
219
- /**
220
- * Returns a list of roles with name and display name to populate a select field.
221
- *
222
- * @param int $userId
223
- *
224
- * @return array
225
- */
226
- protected function getUsersRoles($userId)
227
- {
228
- if (empty($userId)) {
229
- return [];
230
- }
231
-
232
- $user = get_user_by('id', $userId);
233
-
234
- if (empty($user)) {
235
- return [];
236
- }
237
-
238
- return $user->roles;
239
- }
240
-
241
- public function action_profile_update($userId, $oldUserData = [])
242
- {
243
- // Check if we need to update the user's roles, allowing to set multiple roles.
244
- if (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'update-user_' . $userId) && isset($_POST['pp_roles']) && current_user_can('promote_users')) {
245
- // Remove the user's roles
246
- $user = get_user_by('ID', $userId);
247
-
248
- $newRoles = array_map('sanitize_key', $_POST['pp_roles']);
249
- $currentRoles = $user->roles;
250
-
251
- if (empty($newRoles) || !is_array($newRoles)) {
252
- return;
253
- }
254
-
255
- // Remove unselected roles
256
- foreach ($currentRoles as $role) {
257
- // Check if it is a bbPress rule. If so, don't remove it.
258
- $isBBPressRole = preg_match('/^bbp_/', $role);
259
-
260
- if (!in_array($role, $newRoles) && !$isBBPressRole) {
261
- $user->remove_role($role);
262
- }
263
- }
264
-
265
- // Add new roles
266
- foreach ($newRoles as $role) {
267
- if (!in_array($role, $currentRoles)) {
268
- $user->add_role($role);
269
- }
270
- }
271
- }
272
- }
273
-
274
-
275
- // perf enhancement: display submenu links without loading framework and plugin code
276
- function cmeSubmenus() {
277
- // First we check if user is administrator and can 'manage_capabilities'.
278
- if (current_user_can('administrator') && ! current_user_can('manage_capabilities')) {
279
- if ($admin = get_role('administrator')) {
280
- $admin->add_cap('manage_capabilities');
281
- }
282
- }
283
-
284
- $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
285
-
286
- $permissions_title = __('Capabilities', 'capsman-enhanced');
287
-
288
- $menu_order = 72;
289
-
290
- if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
291
- foreach ((array)get_option('active_plugins') as $plugin_file) {
292
- if ( false !== strpos($plugin_file, 'publishpress.php') ) {
293
- $menu_order = 27;
294
- }
295
- }
296
- }
297
-
298
- add_menu_page(
299
- $permissions_title,
300
- $permissions_title,
301
- $cap_name,
302
- 'pp-capabilities',
303
- 'cme_fakefunc',
304
- 'dashicons-admin-network',
305
- $menu_order
306
- );
307
-
308
- add_submenu_page('pp-capabilities', __('Roles', 'capsman-enhanced'), __('Roles', 'capsman-enhanced'), $cap_name, 'pp-capabilities-roles', 'cme_fakefunc');
309
- add_submenu_page('pp-capabilities', __('Editor Features', 'capsman-enhanced'), __('Editor Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-editor-features', 'cme_fakefunc');
310
- add_submenu_page('pp-capabilities', __('Admin Features', 'capsman-enhanced'), __('Admin Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-features', 'cme_fakefunc');
311
- add_submenu_page('pp-capabilities', __('Admin Menus', 'capsman-enhanced'), __('Admin Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-menus', 'cme_fakefunc');
312
- add_submenu_page('pp-capabilities', __('Nav Menus', 'capsman-enhanced'), __('Nav Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-nav-menus', 'cme_fakefunc');
313
- add_submenu_page('pp-capabilities', __('Backup', 'capsman-enhanced'), __('Backup', 'capsman-enhanced'), $cap_name, 'pp-capabilities-backup', 'cme_fakefunc');
314
-
315
- if (defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
316
- add_submenu_page('pp-capabilities', __('Settings', 'capsman-enhanced'), __('Settings', 'capsman-enhanced'), $cap_name, 'pp-capabilities-settings', 'cme_fakefunc');
317
- }
318
-
319
- if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
320
- add_submenu_page(
321
- 'pp-capabilities',
322
- __('Upgrade to Pro', 'capsman-enhanced'),
323
- __('Upgrade to Pro', 'capsman-enhanced'),
324
- 'manage_capabilities',
325
- 'capsman-enhanced',
326
- 'cme_fakefunc'
327
- );
328
- }
329
- }
330
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * PublishPress Capabilities [Free]
5
+ *
6
+ * Admin execution controller: menu registration and other filters and actions that need to be loaded for every wp-admin URL
7
+ *
8
+ * This module should not include full functions related to our own plugin screens.
9
+ * Instead, use these filter and action handlers to load other classes when needed.
10
+ *
11
+ */
12
+ class PP_Capabilities_Admin_UI {
13
+ function __construct() {
14
+ global $pagenow;
15
+
16
+ /**
17
+ * The class responsible for handling notifications
18
+ */
19
+ require_once (dirname(CME_FILE) . '/classes/pp-capabilities-notices.php');
20
+
21
+ add_action('init', [$this, 'featureRestrictionsGutenberg'], PHP_INT_MAX - 1);
22
+
23
+ if (is_admin()) {
24
+ add_action('admin_init', [$this, 'featureRestrictionsClassic'], PHP_INT_MAX - 1);
25
+ }
26
+
27
+ add_action('admin_enqueue_scripts', [$this, 'adminScripts'], 100);
28
+ add_action('admin_print_scripts', [$this, 'adminPrintScripts']);
29
+
30
+ add_action('profile_update', [$this, 'action_profile_update'], 10, 2);
31
+
32
+ if (is_multisite()) {
33
+ add_action('add_user_to_blog', [$this, 'action_profile_update'], 9);
34
+ } else {
35
+ add_action('user_register', [$this, 'action_profile_update'], 9);
36
+ }
37
+
38
+ if (is_admin() && (isset($_REQUEST['page']) && (in_array($_REQUEST['page'], ['pp-capabilities', 'pp-capabilities-backup', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-editor-features', 'pp-capabilities-nav-menus', 'pp-capabilities-settings', 'pp-capabilities-admin-features']))
39
+
40
+ || (!empty($_REQUEST['action']) && in_array($_REQUEST['action'], ['pp-roles-add-role', 'pp-roles-delete-role', 'pp-roles-hide-role', 'pp-roles-unhide-role']))
41
+ || ( ! empty($_SERVER['SCRIPT_NAME']) && strpos(sanitize_text_field($_SERVER['SCRIPT_NAME']), 'p-admin/plugins.php' ) && ! empty($_REQUEST['action'] ) )
42
+ || ( isset($_GET['action']) && ('reset-defaults' == $_GET['action']) && isset($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'capsman-reset-defaults') )
43
+ || in_array( $pagenow, array( 'users.php', 'user-edit.php', 'profile.php', 'user-new.php' ) )
44
+ ) ) {
45
+ global $capsman;
46
+
47
+ // Run the plugin
48
+ require_once ( dirname(CME_FILE) . '/framework/lib/formating.php' );
49
+ require_once ( dirname(CME_FILE) . '/framework/lib/users.php' );
50
+
51
+ require_once ( dirname(CME_FILE) . '/includes/manager.php' );
52
+ $capsman = new CapabilityManager();
53
+ } else {
54
+ add_action( 'admin_menu', [$this, 'cmeSubmenus'], 20 );
55
+ }
56
+
57
+ add_action('init', function() { // late execution avoids clash with autoloaders in other plugins
58
+ global $pagenow;
59
+
60
+ if ((($pagenow == 'admin.php') && isset($_GET['page']) && in_array($_GET['page'], ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-backup'])) // @todo: CSS for button alignment in Editor Features, Admin Features
61
+ || (defined('DOING_AJAX') && DOING_AJAX && !empty($_REQUEST['action']) && (false !== strpos(sanitize_key($_REQUEST['action']), 'capability-manager-enhanced')))
62
+ ) {
63
+ if (!class_exists('\PublishPress\WordPressReviews\ReviewsController')) {
64
+ include_once PUBLISHPRESS_CAPS_ABSPATH . '/vendor/publishpress/wordpress-reviews/ReviewsController.php';
65
+ }
66
+
67
+ if (class_exists('\PublishPress\WordPressReviews\ReviewsController')) {
68
+ $reviews = new \PublishPress\WordPressReviews\ReviewsController(
69
+ 'capability-manager-enhanced',
70
+ 'PublishPress Capabilities',
71
+ plugin_dir_url(CME_FILE) . 'common/img/capabilities-wp-logo.png'
72
+ );
73
+
74
+ add_filter('publishpress_wp_reviews_display_banner_capability-manager-enhanced', [$this, 'shouldDisplayBanner']);
75
+
76
+ $reviews->init();
77
+ }
78
+ }
79
+ });
80
+
81
+
82
+ add_filter('pp_capabilities_feature_post_types', [$this, 'fltEditorFeaturesPostTypes'], 5);
83
+ }
84
+
85
+ public function fltEditorFeaturesPostTypes($def_post_types) {
86
+ if((int)get_option('cme_editor_features_private_post_type') > 0 || defined('PP_CAPABILITIES_PRIVATE_TYPES')){
87
+ $private_cpt = get_post_types(['public' => true, 'show_ui' => true], 'names', 'or');
88
+ $public_cpt = get_post_types(['public' => true, 'show_ui' => true], 'names', 'or');
89
+ $def_post_types = array_unique(array_merge($def_post_types, $private_cpt, $public_cpt));
90
+ }else{
91
+ $def_post_types = array_merge($def_post_types, get_post_types(['public' => true], 'names'));
92
+ }
93
+
94
+ unset($def_post_types['attachment']);
95
+
96
+ if ((count($def_post_types) > 14) && !defined('PP_CAPABILITIES_UNLIMITED_FEATURE_TYPES')) {
97
+ $custom_types = array_diff($def_post_types, ['post', 'page']);
98
+ $def_post_types = array_merge(['post', 'page'], array_slice($custom_types, 0, 12));
99
+ }
100
+
101
+ return $def_post_types;
102
+ }
103
+
104
+ public function shouldDisplayBanner() {
105
+ global $pagenow;
106
+
107
+ return ($pagenow == 'admin.php') && isset($_GET['page']) && in_array($_GET['page'], ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-backup']);
108
+ }
109
+
110
+ private function applyFeatureRestrictions($editor = 'gutenberg') {
111
+ global $pagenow;
112
+
113
+ if (is_multisite() && is_super_admin() && !defined('PP_CAPABILITIES_RESTRICT_SUPER_ADMIN')) {
114
+ return;
115
+ }
116
+
117
+ // Return if not a post editor request
118
+ if (!in_array($pagenow, ['post.php', 'post-new.php'])) {
119
+ return;
120
+ }
121
+
122
+ static $def_post_types; // avoid redundant filter application
123
+
124
+ if (!isset($def_post_types)) {
125
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
126
+ }
127
+
128
+ $post_type = pp_capabilities_get_post_type();
129
+
130
+ // Return if not a supported post type
131
+ if (in_array($post_type, apply_filters('pp_capabilities_unsupported_post_types', ['attachment']))) {
132
+ return;
133
+ }
134
+
135
+ switch ($editor) {
136
+ case 'gutenberg':
137
+ if (_pp_capabilities_is_block_editor_active()) {
138
+ require_once ( dirname(CME_FILE) . '/includes/features/restrict-editor-features.php' );
139
+ PP_Capabilities_Post_Features::applyRestrictions($post_type);
140
+ }
141
+
142
+ break;
143
+
144
+ case 'classic':
145
+ if (!_pp_capabilities_is_block_editor_active()) {
146
+ require_once ( dirname(CME_FILE) . '/includes/features/restrict-editor-features.php' );
147
+ PP_Capabilities_Post_Features::adminInitClassic($post_type);
148
+ }
149
+ }
150
+ }
151
+
152
+ function featureRestrictionsGutenberg() {
153
+ $this->applyFeatureRestrictions();
154
+ }
155
+
156
+ function featureRestrictionsClassic() {
157
+ $this->applyFeatureRestrictions('classic');
158
+ }
159
+
160
+ function adminScripts() {
161
+ global $publishpress;
162
+
163
+ if (function_exists('get_current_screen') && (!defined('PUBLISHPRESS_VERSION') || empty($publishpress) || empty($publishpress->modules) || empty($publishpress->modules->roles))) {
164
+ $screen = get_current_screen();
165
+
166
+ if ('user-edit' === $screen->base || ('user' === $screen->base && 'add' === $screen->action && defined('PP_CAPABILITIES_ADD_USER_MULTI_ROLES'))) {
167
+ // Check if we are on the user's profile page
168
+ wp_enqueue_script(
169
+ 'pp-capabilities-chosen-js',
170
+ plugin_dir_url(CME_FILE) . 'common/libs/chosen-v1.8.7/chosen.jquery.js',
171
+ ['jquery'],
172
+ CAPSMAN_VERSION
173
+ );
174
+
175
+ wp_enqueue_script(
176
+ 'pp-capabilities-roles-profile-js',
177
+ plugin_dir_url(CME_FILE) . 'common/js/profile.js',
178
+ ['jquery', 'pp-capabilities-chosen-js'],
179
+ CAPSMAN_VERSION
180
+ );
181
+
182
+ wp_enqueue_style(
183
+ 'pp-capabilities-chosen-css',
184
+ plugin_dir_url(CME_FILE) . 'common/libs/chosen-v1.8.7/chosen.css',
185
+ false,
186
+ CAPSMAN_VERSION
187
+ );
188
+ wp_enqueue_style(
189
+ 'pp-capabilities-roles-profile-css',
190
+ plugin_dir_url(CME_FILE) . 'common/css/profile.css',
191
+ ['pp-capabilities-chosen-css'],
192
+ CAPSMAN_VERSION
193
+ );
194
+
195
+ $roles = !empty($_GET['user_id']) ? $this->getUsersRoles((int) $_GET['user_id']) : [];
196
+
197
+ if (empty($roles)) {
198
+ $roles = (array) get_option('default_role');
199
+ }
200
+
201
+ wp_localize_script(
202
+ 'pp-capabilities-roles-profile-js',
203
+ 'ppCapabilitiesProfileData',
204
+ [
205
+ 'selected_roles' => $roles
206
+ ]
207
+ );
208
+ }
209
+ }
210
+ }
211
+
212
+ function adminPrintScripts() {
213
+
214
+
215
+ /**
216
+ * Update capabilities top level slug from roles to capabilities
217
+ */
218
+ $menu_inline_script = "
219
+ jQuery(document).ready( function($) {
220
+ if (jQuery('li#toplevel_page_pp-capabilities-roles a.toplevel_page_pp-capabilities-roles').length > 0) {
221
+ var toplevel_page = jQuery('li#toplevel_page_pp-capabilities-roles a.toplevel_page_pp-capabilities-roles');
222
+ var toplevel_page_link = toplevel_page.attr('href');
223
+ if (toplevel_page_link) {
224
+ toplevel_page.attr('href', toplevel_page_link.replace('pp-capabilities-roles', 'pp-capabilities'));
225
+ }
226
+ }
227
+ });";
228
+ ppc_add_inline_script($menu_inline_script);
229
+
230
+ // Counteract overzealous menu icon styling in PublishPress <= 3.2.0 :)
231
+ if (defined('PUBLISHPRESS_VERSION') && version_compare(constant('PUBLISHPRESS_VERSION'), '3.2.0', '<=') && defined('PP_CAPABILITIES_FIX_ADMIN_ICON')):?>
232
+ <style type="text/css">
233
+ #toplevel_page_pp-capabilities-roles .dashicons-before::before, #toplevel_page_pp-capabilities-roles .wp-has-current-submenu .dashicons-before::before {
234
+ background-image: inherit !important;
235
+ content: "\f112" !important;
236
+ }
237
+ </style>
238
+ <?php endif;
239
+ }
240
+
241
+ /**
242
+ * Returns a list of roles with name and display name to populate a select field.
243
+ *
244
+ * @param int $userId
245
+ *
246
+ * @return array
247
+ */
248
+ protected function getUsersRoles($userId)
249
+ {
250
+ if (empty($userId)) {
251
+ return [];
252
+ }
253
+
254
+ $user = get_user_by('id', $userId);
255
+
256
+ if (empty($user)) {
257
+ return [];
258
+ }
259
+
260
+ return $user->roles;
261
+ }
262
+
263
+ public function action_profile_update($userId, $oldUserData = [])
264
+ {
265
+ // Check if we need to update the user's roles, allowing to set multiple roles.
266
+ if (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'update-user_' . $userId) && isset($_POST['pp_roles']) && current_user_can('promote_users')) {
267
+ // Remove the user's roles
268
+ $user = get_user_by('ID', $userId);
269
+
270
+ $newRoles = array_map('sanitize_key', $_POST['pp_roles']);
271
+ $currentRoles = $user->roles;
272
+
273
+ if (empty($newRoles) || !is_array($newRoles)) {
274
+ return;
275
+ }
276
+
277
+ // Remove unselected roles
278
+ foreach ($currentRoles as $role) {
279
+ // Check if it is a bbPress rule. If so, don't remove it.
280
+ $isBBPressRole = preg_match('/^bbp_/', $role);
281
+
282
+ if (!in_array($role, $newRoles) && !$isBBPressRole) {
283
+ $user->remove_role($role);
284
+ }
285
+ }
286
+
287
+ // Add new roles
288
+ foreach ($newRoles as $role) {
289
+ if (!in_array($role, $currentRoles)) {
290
+ $user->add_role($role);
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+
297
+ // perf enhancement: display submenu links without loading framework and plugin code
298
+ function cmeSubmenus() {
299
+ // First we check if user is administrator and can 'manage_capabilities'.
300
+ if (current_user_can('administrator') && ! current_user_can('manage_capabilities')) {
301
+ if ($admin = get_role('administrator')) {
302
+ $admin->add_cap('manage_capabilities');
303
+ }
304
+ }
305
+
306
+ $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
307
+
308
+ $permissions_title = __('Capabilities', 'capsman-enhanced');
309
+
310
+ $menu_order = 72;
311
+
312
+ if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
313
+ foreach ((array)get_option('active_plugins') as $plugin_file) {
314
+ if ( false !== strpos($plugin_file, 'publishpress.php') ) {
315
+ $menu_order = 27;
316
+ }
317
+ }
318
+ }
319
+
320
+ add_menu_page(
321
+ $permissions_title,
322
+ $permissions_title,
323
+ $cap_name,
324
+ 'pp-capabilities-roles',
325
+ 'cme_fakefunc',
326
+ 'dashicons-admin-network',
327
+ $menu_order
328
+ );
329
+
330
+ add_submenu_page('pp-capabilities-roles', __('Roles', 'capsman-enhanced'), __('Roles', 'capsman-enhanced'), $cap_name, 'pp-capabilities-roles', 'cme_fakefunc');
331
+ add_submenu_page('pp-capabilities-roles', $permissions_title, $permissions_title, $cap_name, 'pp-capabilities', 'cme_fakefunc');
332
+ add_submenu_page('pp-capabilities-roles', __('Editor Features', 'capsman-enhanced'), __('Editor Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-editor-features', 'cme_fakefunc');
333
+ add_submenu_page('pp-capabilities-roles', __('Admin Features', 'capsman-enhanced'), __('Admin Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-features', 'cme_fakefunc');
334
+ add_submenu_page('pp-capabilities-roles', __('Admin Menus', 'capsman-enhanced'), __('Admin Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-menus', 'cme_fakefunc');
335
+ add_submenu_page('pp-capabilities-roles', __('Nav Menus', 'capsman-enhanced'), __('Nav Menus', 'capsman-enhanced'), $cap_name, 'pp-capabilities-nav-menus', 'cme_fakefunc');
336
+ add_submenu_page('pp-capabilities-roles', __('Backup', 'capsman-enhanced'), __('Backup', 'capsman-enhanced'), $cap_name, 'pp-capabilities-backup', 'cme_fakefunc');
337
+
338
+ if (defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
339
+ add_submenu_page('pp-capabilities-roles', __('Settings', 'capsman-enhanced'), __('Settings', 'capsman-enhanced'), $cap_name, 'pp-capabilities-settings', 'cme_fakefunc');
340
+ }
341
+
342
+ if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
343
+ add_submenu_page(
344
+ 'pp-capabilities-roles',
345
+ __('Upgrade to Pro', 'capsman-enhanced'),
346
+ __('Upgrade to Pro', 'capsman-enhanced'),
347
+ 'manage_capabilities',
348
+ 'capsman-enhanced',
349
+ 'cme_fakefunc'
350
+ );
351
+ }
352
+ }
353
+ }
includes/admin.php CHANGED
@@ -1,1427 +1,1427 @@
1
- <?php
2
- /**
3
- * PublishPress Capabilities [Free]
4
- *
5
- * UI output for Capabilities screen.
6
- *
7
- * Provides admin pages to create and manage roles and capabilities.
8
- *
9
- * @author Jordi Canals, Kevin Behrens
10
- * @copyright Copyright (C) 2009, 2010 Jordi Canals, (C) 2020 PublishPress
11
- * @license GNU General Public License version 2
12
- * @link https://publishpress.com
13
- *
14
- * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
- * Modifications Copyright 2020, PublishPress <help@publishpress.com>
16
- *
17
- * This program is free software; you can redistribute it and/or
18
- * modify it under the terms of the GNU General Public License
19
- * version 2 as published by the Free Software Foundation.
20
- *
21
- * This program is distributed in the hope that it will be useful,
22
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
- * GNU General Public License for more details.
25
- *
26
- * You should have received a copy of the GNU General Public License
27
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
28
- **/
29
-
30
- global $capsman, $cme_cap_helper, $current_user;
31
-
32
- do_action('publishpress-caps_manager-load');
33
-
34
- $roles = $this->roles;
35
- $default = $this->current;
36
-
37
- if ( $block_read_removal = _cme_is_read_removal_blocked( $this->current ) ) {
38
- if ( $current = get_role($default) ) {
39
- if ( empty( $current->capabilities['read'] ) ) {
40
- ak_admin_error( sprintf( __( 'Warning: This role cannot access the dashboard without the read capability. %1$sClick here to fix this now%2$s.', 'capsman-enhanced' ), '<a href="javascript:void(0)" class="cme-fix-read-cap">', '</a>' ) );
41
- }
42
- }
43
- }
44
-
45
- require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
46
-
47
- require_once( dirname(__FILE__).'/pp-ui.php' );
48
- $pp_ui = new Capsman_PP_UI();
49
-
50
- if( defined('PRESSPERMIT_ACTIVE') ) {
51
- $pp_metagroup_caps = $pp_ui->get_metagroup_caps( $default );
52
- } else {
53
- $pp_metagroup_caps = array();
54
- }
55
- ?>
56
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper">
57
- <div id="icon-capsman-admin" class="icon32"></div>
58
-
59
- <h1><?php esc_html_e('Role Capabilities', 'capsman-enhanced') ?></h1>
60
-
61
- <?php
62
- pp_capabilities_roles()->notify->display();
63
- ?>
64
-
65
- <script type="text/javascript">
66
- /* <![CDATA[ */
67
- jQuery(document).ready( function($) {
68
- $('#publishpress_caps_form').attr('action', 'admin.php?page=pp-capabilities&role=' + $('select[name="role"]').val());
69
-
70
- $('select[name="role"]').change(function(){
71
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities&role=')); ?>' + $(this).val() + '';
72
- });
73
- });
74
- /* ]]> */
75
- </script>
76
-
77
- <form id="publishpress_caps_form" method="post" action="admin.php?page=<?php echo esc_attr($this->ID);?>">
78
- <?php wp_nonce_field('capsman-general-manager'); ?>
79
-
80
- <?php
81
- if (empty($_REQUEST['pp_caps_tab']) && !empty($_REQUEST['added'])) {
82
- $pp_tab = 'additional';
83
- } else {
84
- $pp_tab = (!empty($_REQUEST['pp_caps_tab'])) ? sanitize_key($_REQUEST['pp_caps_tab']) : 'edit';
85
- }
86
- ?>
87
-
88
- <input type="hidden" name="pp_caps_tab" value="<?php echo esc_attr($pp_tab);?>" />
89
-
90
- <p>
91
- <select name="role">
92
- <?php
93
- foreach ( $roles as $role_name => $name ) {
94
- $role_name = sanitize_key($role_name);
95
-
96
- if (pp_capabilities_is_editable_role($role_name)) {
97
- $name = translate_user_role($name);
98
- echo '<option value="' . esc_attr($role_name) .'"'; selected($default, $role_name); echo '> ' . esc_html($name) . ' &nbsp;</option>';
99
- }
100
- }
101
- ?>
102
- </select>
103
- </p>
104
-
105
- <fieldset>
106
- <table id="akmin"><tr><td>
107
- <div class="pp-columns-wrapper pp-enable-sidebar">
108
- <div class="pp-column-left">
109
-
110
- <div style="float:right">
111
-
112
- <?php
113
- $caption = (in_array(sanitize_key(get_locale()), ['en_EN', 'en_US'])) ? 'Save Capabilities' : __('Save Changes', 'capsman-enhanced');
114
- ?>
115
- <input type="submit" name="SaveRole" value="<?php echo esc_attr($caption);?>" class="button-primary" />
116
- </div>
117
-
118
- <?php
119
- $img_url = $capsman->mod_url . '/images/';
120
- ?>
121
- <div class="publishpress-headline" style="margin-bottom:20px;">
122
- <span class="cme-subtext">
123
- <?php
124
-
125
- if (defined('PRESSPERMIT_ACTIVE') && function_exists('presspermit')) {
126
- if ($group = presspermit()->groups()->getMetagroup('wp_role', $this->current)) {
127
- printf(
128
- // back compat with existing language string
129
- str_replace(
130
- ['&lt;strong&gt;', '&lt;/strong&gt;'],
131
- ['<strong>', '</strong>'],
132
- esc_html__('<strong>Note:</strong> Capability changes <strong>remain in the database</strong> after plugin deactivation. You can also configure this role as a %sPermission Group%s.', 'capsman-enhanced')
133
- ),
134
- '<a href="' . esc_url_raw(admin_url("admin.php?page=presspermit-edit-permissions&action=edit&agent_id={$group->ID}")) . '">',
135
- '</a>'
136
- );
137
- }
138
- } else {
139
- // unescaped for now for back compat with existing language string
140
- _e( '<strong>Note:</strong> Capability changes <strong>remain in the database</strong> after plugin deactivation.', 'capsman-enhanced' );
141
- }
142
-
143
- ?>
144
- </span>
145
- </div>
146
-
147
- <?php
148
- if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
149
- $pp_ui->show_capability_hints( $default );
150
- }
151
-
152
- if ( MULTISITE ) {
153
- global $wp_roles;
154
- global $wpdb;
155
-
156
- if ( ! empty($_REQUEST['cme_net_sync_role'] ) ) {
157
- $main_site_id = (function_exists('get_main_site_id')) ? get_main_site_id() : 1;
158
- switch_to_blog($main_site_id);
159
- wp_cache_delete( $wpdb->prefix . 'user_roles', 'options' );
160
- }
161
-
162
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
163
- }
164
- $capsman->reinstate_db_roles();
165
-
166
- $current = get_role($default);
167
-
168
- $rcaps = $current->capabilities;
169
-
170
- $is_administrator = current_user_can( 'administrator' ) || (is_multisite() && is_super_admin());
171
-
172
- $custom_types = get_post_types( array( '_builtin' => false ), 'names' );
173
- $custom_tax = get_taxonomies( array( '_builtin' => false ), 'names' );
174
-
175
- $defined = [];
176
- $defined['type'] = apply_filters('cme_filterable_post_types', get_post_types(['public' => true, 'show_ui' => true], 'object', 'or'));
177
- $defined['taxonomy'] = apply_filters('cme_filterable_taxonomies', get_taxonomies(['public' => true, 'show_ui' => true], 'object', 'or'));
178
-
179
- // bbPress' dynamic role def requires additional code to enforce stored caps
180
- $unfiltered['type'] = apply_filters('presspermit_unfiltered_post_types', ['forum','topic','reply','wp_block']);
181
- $unfiltered['type'] = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered['type'] : apply_filters('pp_unfiltered_post_types', $unfiltered['type']);
182
-
183
- $unfiltered['taxonomy'] = apply_filters('presspermit_unfiltered_post_types', ['post_status', 'topic-tag']); // avoid confusion with Edit Flow administrative taxonomy
184
- $unfiltered['taxonomy'] = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered['taxonomy'] : apply_filters('pp_unfiltered_taxonomies', $unfiltered['taxonomy']);
185
-
186
- $enabled_taxonomies = cme_get_assisted_taxonomies();
187
-
188
- $cap_properties['edit']['type'] = array( 'edit_posts' );
189
-
190
- foreach( $defined['type'] as $type_obj ) {
191
- if ( 'attachment' != $type_obj->name ) {
192
- if ( isset( $type_obj->cap->create_posts ) && ( $type_obj->cap->create_posts != $type_obj->cap->edit_posts ) ) {
193
- $cap_properties['edit']['type'][]= 'create_posts';
194
- break;
195
- }
196
- }
197
- }
198
-
199
- $cap_properties['edit']['type'][]= 'edit_others_posts';
200
- $cap_properties['edit']['type'] = array_merge( $cap_properties['edit']['type'], array( 'publish_posts', 'edit_published_posts', 'edit_private_posts' ) );
201
-
202
- $cap_properties['edit']['taxonomy'] = array( 'manage_terms' );
203
-
204
- if ( ! defined( 'OLD_PRESSPERMIT_ACTIVE' ) )
205
- $cap_properties['edit']['taxonomy'] = array_merge( $cap_properties['edit']['taxonomy'], array( 'edit_terms', 'assign_terms' ) );
206
-
207
- $cap_properties['delete']['type'] = array( 'delete_posts', 'delete_others_posts' );
208
- $cap_properties['delete']['type'] = array_merge( $cap_properties['delete']['type'], array( 'delete_published_posts', 'delete_private_posts' ) );
209
-
210
- if ( ! defined( 'OLD_PRESSPERMIT_ACTIVE' ) )
211
- $cap_properties['delete']['taxonomy'] = array( 'delete_terms' );
212
- else
213
- $cap_properties['delete']['taxonomy'] = array();
214
-
215
- $cap_properties['read']['type'] = array( 'read_private_posts' );
216
- $cap_properties['read']['taxonomy'] = array();
217
-
218
- $stati = get_post_stati( array( 'internal' => false ) );
219
-
220
- $cap_type_names = array(
221
- '' => __( '&nbsp;', 'capsman-enhanced' ),
222
- 'read' => __( 'Reading', 'capsman-enhanced' ),
223
- 'edit' => __( 'Editing', 'capsman-enhanced' ),
224
- 'delete' => __( 'Deletion', 'capsman-enhanced' )
225
- );
226
-
227
- $cap_tips = array(
228
- 'read_private' => esc_attr__( 'can read posts which are currently published with private visibility', 'capsman-enhanced' ),
229
- 'edit' => esc_attr__( 'has basic editing capability (but may need other capabilities based on post status and ownership)', 'capsman-enhanced' ),
230
- 'edit_others' => esc_attr__( 'can edit posts which were created by other users', 'capsman-enhanced' ),
231
- 'edit_published' => esc_attr__( 'can edit posts which are currently published', 'capsman-enhanced' ),
232
- 'edit_private' => esc_attr__( 'can edit posts which are currently published with private visibility', 'capsman-enhanced' ),
233
- 'publish' => esc_attr__( 'can make a post publicly visible', 'capsman-enhanced' ),
234
- 'delete' => esc_attr__( 'has basic deletion capability (but may need other capabilities based on post status and ownership)', 'capsman-enhanced' ),
235
- 'delete_others' => esc_attr__( 'can delete posts which were created by other users', 'capsman-enhanced' ),
236
- 'delete_published' => esc_attr__( 'can delete posts which are currently published', 'capsman-enhanced' ),
237
- 'delete_private' => esc_attr__( 'can delete posts which are currently published with private visibility', 'capsman-enhanced' ),
238
- );
239
-
240
- $default_caps = array( 'read_private_posts', 'edit_posts', 'edit_others_posts', 'edit_published_posts', 'edit_private_posts', 'publish_posts', 'delete_posts', 'delete_others_posts', 'delete_published_posts', 'delete_private_posts',
241
- 'read_private_pages', 'edit_pages', 'edit_others_pages', 'edit_published_pages', 'edit_private_pages', 'publish_pages', 'delete_pages', 'delete_others_pages', 'delete_published_pages', 'delete_private_pages',
242
- 'manage_categories'
243
- );
244
- $type_caps = array();
245
- $type_metacaps = array();
246
-
247
- // Role Scoper and PP1 adjust attachment access based only on user's capabilities for the parent post
248
- if ( defined('OLD_PRESSPERMIT_ACTIVE') ) {
249
- unset( $defined['type']['attachment'] );
250
- }
251
- ?>
252
-
253
- <script type="text/javascript">
254
- /* <![CDATA[ */
255
- jQuery(document).ready( function($) {
256
- // Tabs and Content display
257
- $('.ppc-capabilities-tabs > ul > li').click( function() {
258
- var $pp_tab = $(this).attr('data-content');
259
-
260
- $("[name='pp_caps_tab']").val($(this).attr('data-slug'));
261
-
262
- // Show current Content
263
- $('.ppc-capabilities-content > div').hide();
264
- $('#' + $pp_tab).show();
265
-
266
- $('#' + $pp_tab + '-taxonomy').show();
267
-
268
- // Active current Tab
269
- $('.ppc-capabilities-tabs > ul > li').removeClass('ppc-capabilities-tab-active');
270
- $(this).addClass('ppc-capabilities-tab-active');
271
- });
272
- });
273
- /* ]]> */
274
- </script>
275
-
276
- <div id="ppc-capabilities-wrapper" class="postbox">
277
- <div class="ppc-capabilities-tabs">
278
- <ul>
279
- <?php
280
- if (empty($_REQUEST['pp_caps_tab']) && !empty($_REQUEST['added'])) {
281
- $active_tab_slug = 'additional';
282
- } else {
283
- $active_tab_slug = (!empty($_REQUEST['pp_caps_tab'])) ? sanitize_key($_REQUEST['pp_caps_tab']) : 'edit';
284
- }
285
-
286
- $active_tab_id = "cme-cap-type-tables-{$active_tab_slug}";
287
-
288
- $ppc_tab_active = 'ppc-capabilities-tab-active';
289
-
290
- // caps: edit, delete, read
291
- foreach( array_keys($cap_properties) as $cap_type ) {
292
- $tab_id = "cme-cap-type-tables-$cap_type";
293
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
294
-
295
- echo '<li data-slug="'. esc_attr($cap_type) . '"' . ' data-content="cme-cap-type-tables-' . esc_attr($cap_type) . '" class="' . esc_attr($tab_active) . '">'
296
- . esc_html($cap_type_names[$cap_type]) .
297
- '</li>';
298
- }
299
-
300
- if ($extra_tabs = apply_filters('pp_capabilities_extra_post_capability_tabs', [])) {
301
- foreach($extra_tabs as $tab_slug => $tab_caption) {
302
- $tab_slug = esc_attr($tab_slug);
303
-
304
- $tab_id = "cme-cap-type-tables-{$tab_slug}";
305
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
306
-
307
- echo '<li data-slug="' . esc_attr($tab_slug) . '"' . ' data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">'
308
- . esc_html($tab_caption) .
309
- '</li>';
310
- }
311
- }
312
-
313
- // caps: other
314
- $tab_id = "cme-cap-type-tables-other";
315
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
316
- $tab_caption = esc_html__( 'WordPress Core', 'capsman-enhanced' );
317
-
318
- echo '<li data-slug="other" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">' . esc_html($tab_caption) . '</li>';
319
-
320
- // caps: plugins
321
- $plugin_caps = [];
322
- if (defined('PUBLISHPRESS_VERSION')) {
323
- $plugin_caps['PublishPress'] = apply_filters('cme_publishpress_capabilities',
324
- array(
325
- 'edit_metadata',
326
- 'edit_post_subscriptions',
327
- 'pp_manage_roles',
328
- 'pp_set_notification_channel',
329
- 'pp_view_calendar',
330
- 'pp_view_content_overview',
331
- )
332
- );
333
- }
334
-
335
- //PublishPress Capabilities Capabilities
336
- $plugin_caps['PublishPress Capabilities'] = apply_filters('cme_publishpress_capabilities_capabilities',
337
- array(
338
- 'manage_capabilities',
339
- )
340
- );
341
-
342
- if (defined('PUBLISHPRESS_MULTIPLE_AUTHORS_VERSION')) {
343
- if ($_caps = apply_filters('cme_multiple_authors_capabilities', array())) {
344
- $plugin_caps['PublishPress Authors'] = $_caps;
345
- }
346
- }
347
-
348
- if (defined('PRESSPERMIT_VERSION')) {
349
- $plugin_caps['PublishPress Permissions'] = apply_filters('cme_presspermit_capabilities',
350
- array(
351
- 'edit_own_attachments',
352
- 'list_others_unattached_files',
353
- 'pp_administer_content',
354
- 'pp_assign_roles',
355
- 'pp_associate_any_page',
356
- 'pp_create_groups',
357
- 'pp_create_network_groups',
358
- 'pp_define_moderation',
359
- 'pp_define_post_status',
360
- 'pp_define_privacy',
361
- 'pp_delete_groups',
362
- 'pp_edit_groups',
363
- 'pp_exempt_edit_circle',
364
- 'pp_exempt_read_circle',
365
- 'pp_force_quick_edit',
366
- 'pp_list_all_files',
367
- 'pp_manage_capabilities',
368
- 'pp_manage_members',
369
- 'pp_manage_network_members',
370
- 'pp_manage_settings',
371
- 'pp_moderate_any',
372
- 'pp_set_associate_exceptions',
373
- 'pp_set_edit_exceptions',
374
- 'pp_set_read_exceptions',
375
- 'pp_set_revise_exceptions',
376
- 'pp_set_term_assign_exceptions',
377
- 'pp_set_term_associate_exceptions',
378
- 'pp_set_term_manage_exceptions',
379
- 'pp_unfiltered',
380
- 'set_posts_status',
381
- )
382
- );
383
- }
384
-
385
- if (defined('WC_PLUGIN_FILE')) {
386
- $plugin_caps['WooCommerce'] = apply_filters('cme_woocommerce_capabilities',
387
- array(
388
- 'assign_product_terms',
389
- 'assign_shop_coupon_terms',
390
- 'assign_shop_discount_terms',
391
- 'assign_shop_order_terms',
392
- 'assign_shop_payment_terms',
393
- 'create_shop_orders',
394
- 'delete_others_products',
395
- 'delete_others_shop_coupons',
396
- 'delete_others_shop_discounts',
397
- 'delete_others_shop_orders',
398
- 'delete_others_shop_payments',
399
- 'delete_private_products',
400
- 'delete_private_shop_coupons',
401
- 'delete_private_shop_orders',
402
- 'delete_private_shop_discounts',
403
- 'delete_private_shop_payments',
404
- 'delete_product_terms',
405
- 'delete_products',
406
- 'delete_published_products',
407
- 'delete_published_shop_coupons',
408
- 'delete_published_shop_discounts',
409
- 'delete_published_shop_orders',
410
- 'delete_published_shop_payments',
411
- 'delete_shop_coupons',
412
- 'delete_shop_coupon_terms',
413
- 'delete_shop_discount_terms',
414
- 'delete_shop_discounts',
415
- 'delete_shop_order_terms',
416
- 'delete_shop_orders',
417
- 'delete_shop_payments',
418
- 'delete_shop_payment_terms',
419
- 'edit_others_products',
420
- 'edit_others_shop_coupons',
421
- 'edit_others_shop_discounts',
422
- 'edit_others_shop_orders',
423
- 'edit_others_shop_payments',
424
- 'edit_private_products',
425
- 'edit_private_shop_coupons',
426
- 'edit_private_shop_discounts',
427
- 'edit_private_shop_orders',
428
- 'edit_private_shop_payments',
429
- 'edit_product_terms',
430
- 'edit_products',
431
- 'edit_published_products',
432
- 'edit_published_shop_coupons',
433
- 'edit_published_shop_discounts',
434
- 'edit_published_shop_orders',
435
- 'edit_published_shop_payments',
436
- 'edit_shop_coupon_terms',
437
- 'edit_shop_coupons',
438
- 'edit_shop_discounts',
439
- 'edit_shop_discount_terms',
440
- 'edit_shop_order_terms',
441
- 'edit_shop_orders',
442
- 'edit_shop_payments',
443
- 'edit_shop_payment_terms',
444
- 'export_shop_payments',
445
- 'export_shop_reports',
446
- 'import_shop_discounts',
447
- 'import_shop_payments',
448
- 'manage_product_terms',
449
- 'manage_shop_coupon_terms',
450
- 'manage_shop_discounts',
451
- 'manage_shop_discount_terms',
452
- 'manage_shop_payment_terms',
453
- 'manage_shop_order_terms',
454
- 'manage_shop_settings',
455
- 'manage_woocommerce',
456
- 'publish_products',
457
- 'publish_shop_coupons',
458
- 'publish_shop_discounts',
459
- 'publish_shop_orders',
460
- 'publish_shop_payments',
461
- 'read_private_products',
462
- 'read_private_shop_coupons',
463
- 'read_private_shop_discounts',
464
- 'read_private_shop_payments',
465
- 'read_private_shop_orders',
466
- 'view_admin_dashboard',
467
- 'view_shop_discount_stats',
468
- 'view_shop_payment_stats',
469
- 'view_shop_reports',
470
- 'view_shop_sensitive_data',
471
- 'view_woocommerce_reports',
472
- )
473
- );
474
- }
475
- $plugin_caps = apply_filters('cme_plugin_capabilities', $plugin_caps);
476
- foreach($plugin_caps as $plugin_title => $__plugin_caps) {
477
- $plugin_title = esc_html($plugin_title);
478
-
479
- $tab_slug = str_replace(' ', '-', strtolower(sanitize_title($plugin_title)));
480
- $tab_id = 'cme-cap-type-tables-' . $tab_slug;
481
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
482
-
483
- echo '<li data-slug="' . esc_attr($tab_slug) . '" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">'
484
- . esc_html(str_replace('_', ' ', $plugin_title)) .
485
- '</li>';
486
- }
487
-
488
- $tab_id = "cme-cap-type-tables-invalid";
489
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
490
- $tab_caption = esc_html__( 'Invalid Capabilities', 'capsman-enhanced' );
491
- echo '<li id="cme_tab_invalid_caps" data-slug="invalid" data-content="cme-cap-type-tables-' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '" style="display:none;">' . esc_html($tab_caption) . '</li>';
492
-
493
- $tab_id = "cme-cap-type-tables-additional";
494
- $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
495
- $tab_caption = esc_html__( 'Additional', 'capsman-enhanced' );
496
- echo '<li data-slug="additional" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">' . esc_html($tab_caption) . '</li>';
497
- ?>
498
- </ul>
499
- </div>
500
- <div class="ppc-capabilities-content">
501
- <?php
502
- // caps: read, edit, deletion
503
- foreach( array_keys($cap_properties) as $cap_type ) {
504
-
505
- foreach( array_keys($defined) as $item_type ) {
506
- if ( ( 'delete' == $cap_type ) && ( 'taxonomy' == $item_type ) ) {
507
- if ( defined('OLD_PRESSPERMIT_ACTIVE') ) {
508
- continue;
509
- }
510
-
511
- $any_term_deletion_caps = false;
512
- foreach( array_keys($defined['taxonomy']) as $_tax ) {
513
- if ( isset( $defined['taxonomy'][$_tax]->cap->delete_terms ) && ( 'manage_categories' != $defined['taxonomy'][$_tax]->cap->delete_terms ) && ! in_array( $_tax, $unfiltered['taxonomy'] ) ) {
514
- $any_term_deletion_caps = true;
515
- break;
516
- }
517
- }
518
-
519
- if ( ! $any_term_deletion_caps )
520
- continue;
521
- }
522
-
523
- if ( ! count( $cap_properties[$cap_type][$item_type] ) )
524
- continue;
525
-
526
- $tab_id = "cme-cap-type-tables-$cap_type";
527
- $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
528
-
529
- $any_caps = false;
530
-
531
- if ($item_type == 'taxonomy') {
532
- $tab_id .= '-taxonomy';
533
-
534
- ob_start();
535
- }
536
-
537
- echo "<div id='" . esc_attr($tab_id) . "' style='display:" . esc_attr($div_display) . ";'>";
538
-
539
- $caption_pattern = ('taxonomy' == $item_type) ? esc_html__('Term %s Capabilities', 'capability-manager-enhanced') : esc_html__('Post %s Capabilities', 'capability-manager-enhanced');
540
-
541
- echo '<h3>' . sprintf($caption_pattern, esc_html($cap_type_names[$cap_type])) . '</h3>';
542
-
543
- echo '<div class="ppc-filter-wrapper">';
544
- echo '<select class="ppc-filter-select">';
545
- $filter_caption = ('taxonomy' == $item_type) ? __('Filter by taxonomy', 'capability-manager-enhanced') : __('Filter by post type', 'capability-manager-enhanced');
546
- echo '<option value="">' . esc_html($filter_caption) . '</option>';
547
- echo '</select>';
548
- echo ' <button class="button secondary-button ppc-filter-select-reset" type="button">' . esc_html__('Clear', 'capability-manager-enhanced') . '</button>';
549
- echo '</div>';
550
-
551
- echo "<table class='widefat fixed striped cme-typecaps cme-typecaps-" . esc_attr($cap_type) . "'>";
552
-
553
- echo '<thead><tr><th></th>';
554
-
555
- // label cap properties
556
- foreach( $cap_properties[$cap_type][$item_type] as $prop ) {
557
- $prop = str_replace( '_posts', '', $prop );
558
- $prop = str_replace( '_pages', '', $prop );
559
- $prop = str_replace( '_terms', '', $prop );
560
- $tip = ( isset( $cap_tips[$prop] ) ) ? $cap_tips[$prop] : '';
561
- $th_class = ( 'taxonomy' == $item_type ) ? 'term-cap' : 'post-cap';
562
- echo "<th style='text-align:center;' title='" . esc_attr($tip) . "' class='" . esc_attr($th_class) . "'>";
563
-
564
- if ( ( 'delete' != $prop ) || ( 'taxonomy' != $item_type ) || cme_get_detailed_taxonomies() ) {
565
- echo str_replace('_', '<br />', esc_html(ucwords($prop)));
566
- }
567
-
568
- echo '</th>';
569
- }
570
-
571
- echo '</tr></thead>';
572
-
573
- foreach( $defined[$item_type] as $key => $type_obj ) {
574
- if ( in_array( $key, $unfiltered[$item_type] ) )
575
- continue;
576
-
577
- $row = "<tr class='cme_type_" . esc_attr($key) . "'>";
578
-
579
- if ( $cap_type ) {
580
- if ( empty($force_distinct_ui) && empty( $cap_properties[$cap_type][$item_type] ) )
581
- continue;
582
-
583
- $type_label = (defined('CME_LEGACY_MENU_NAME_LABEL') && !empty($type_obj->labels->menu_name)) ? $type_obj->labels->menu_name : $type_obj->labels->name;
584
-
585
- $row .= "<td><a class='cap_type' href='#toggle_type_caps'>" . esc_html($type_label) . '</a>';
586
- $row .= '<a href="#" class="neg-type-caps">&nbsp;x&nbsp;</a>';
587
- $row .= '</td>';
588
-
589
- $display_row = ! empty($force_distinct_ui);
590
- $col_count = 0;
591
-
592
- foreach( $cap_properties[$cap_type][$item_type] as $prop ) {
593
- $td_classes = array();
594
- $checkbox = '';
595
- $cap_title = '';
596
-
597
- if ( ! empty($type_obj->cap->$prop) && ( in_array( $type_obj->name, array( 'post', 'page' ) )
598
- || ! in_array( $type_obj->cap->$prop, $default_caps )
599
- || ( ( 'manage_categories' == $type_obj->cap->$prop ) && ( 'manage_terms' == $prop ) && ( 'category' == $type_obj->name ) ) ) ) {
600
-
601
- // if edit_published or edit_private cap is same as edit_posts cap, don't display a checkbox for it
602
- if ( ( ! in_array( $prop, array( 'edit_published_posts', 'edit_private_posts', 'create_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->edit_posts ) )
603
- && ( ! in_array( $prop, array( 'delete_published_posts', 'delete_private_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->delete_posts ) )
604
- && ( ! in_array( $prop, array( 'edit_terms', 'delete_terms' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->manage_terms ) )
605
-
606
- && ( ! in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) )
607
- || empty($cme_cap_helper->all_taxonomy_caps[$type_obj->cap->$prop])
608
- || ( $cme_cap_helper->all_taxonomy_caps[ $type_obj->cap->$prop ] <= 1 )
609
- || $type_obj->cap->$prop == str_replace( '_terms', "_{$type_obj->name}s", $prop )
610
- || $type_obj->cap->$prop == str_replace( '_terms', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
611
- )
612
-
613
- && ( in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) )
614
- || empty($cme_cap_helper->all_type_caps[$type_obj->cap->$prop])
615
- || ( $cme_cap_helper->all_type_caps[ $type_obj->cap->$prop ] <= 1 )
616
- || $type_obj->cap->$prop == 'upload_files' && 'create_posts' == $prop && 'attachment' == $type_obj->name
617
- || $type_obj->cap->$prop == str_replace( '_posts', "_{$type_obj->name}s", $prop )
618
- || $type_obj->cap->$prop == str_replace( '_pages', "_{$type_obj->name}s", $prop )
619
- || $type_obj->cap->$prop == str_replace( '_posts', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
620
- || $type_obj->cap->$prop == str_replace( '_pages', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
621
- )
622
- ) {
623
- // only present these term caps up top if we are ensuring that they get enforced separately from manage_terms
624
- if ( in_array( $prop, array( 'edit_terms', 'delete_terms', 'assign_terms' ) ) && ( ! in_array( $type_obj->name, cme_get_detailed_taxonomies() ) || defined( 'OLD_PRESSPERMIT_ACTIVE' ) ) ) {
625
- continue;
626
- }
627
-
628
- $cap_name = sanitize_key($type_obj->cap->$prop);
629
-
630
- if ( 'taxonomy' == $item_type )
631
- $td_classes []= "term-cap";
632
- else
633
- $td_classes []= "post-cap";
634
-
635
- if ( ! empty($pp_metagroup_caps[$cap_name]) )
636
- $td_classes []='cm-has-via-pp';
637
-
638
- if ( $is_administrator || current_user_can($cap_name) ) {
639
- if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
640
- $cap_title = sprintf(__( '%s: assigned by Permission Group', 'capsman-enhanced' ), esc_attr($cap_name) );
641
- } else {
642
- $cap_title = esc_attr($cap_name);
643
- }
644
-
645
- $checkbox = '<input type="checkbox" title="' . esc_attr($cap_title) . '" name="caps[' . esc_attr($cap_name) . ']" autocomplete="off" value="1" ' . checked(1, ! empty($rcaps[$cap_name]), false ) . ' />';
646
-
647
- $type_caps [$cap_name] = true;
648
- $display_row = true;
649
- $any_caps = true;
650
- }
651
- } else {
652
- $cap_title = sprintf( __( 'shared capability: %s', 'capsman-enhanced' ), esc_attr( $type_obj->cap->$prop ) );
653
- }
654
-
655
- if ( isset($rcaps[$cap_name]) && empty($rcaps[$cap_name]) ) {
656
- $td_classes []= "cap-neg";
657
- }
658
- } else {
659
- $td_classes []= "cap-unreg";
660
- }
661
-
662
- $td_class = ( $td_classes ) ? implode(' ', $td_classes) : '';
663
-
664
- $row .= '<td class="' . esc_attr($td_class) . '" title="' . esc_attr($cap_title) . '"' . "><span class='cap-x'>X</span>$checkbox";
665
-
666
- if ( false !== strpos( $td_class, 'cap-neg' ) )
667
- $row .= '<input type="hidden" class="cme-negation-input" name="caps[' . esc_attr($cap_name) . ']" value="" />';
668
-
669
- $row .= "</td>";
670
-
671
- $col_count++;
672
- }
673
-
674
- if ('taxonomy' == $item_type) {
675
- for ($i = $col_count; $i < 3; $i++) {
676
- $row .= "<td></td>";
677
- }
678
- }
679
-
680
- if (!empty($type_obj->map_meta_cap) && !defined('PP_CAPABILITIES_NO_INVALID_SECTION')) {
681
- if ('type' == $item_type) {
682
- $type_metacaps[$type_obj->cap->read_post] = true;
683
- $type_metacaps[$type_obj->cap->edit_post] = isset($type_obj->cap->edit_posts) && ($type_obj->cap->edit_post != $type_obj->cap->edit_posts);
684
- $type_metacaps[$type_obj->cap->delete_post] = isset($type_obj->cap->delete_posts) && ($type_obj->cap->delete_post != $type_obj->cap->delete_posts);
685
-
686
- } elseif ('taxonomy' == $item_type && !empty($type_obj->cap->edit_term) && !empty($type_obj->cap->delete_term)) {
687
- $type_metacaps[$type_obj->cap->edit_term] = true;
688
- $type_metacaps[$type_obj->cap->delete_term] = true;
689
- }
690
- }
691
- }
692
-
693
- if ( $display_row ) {
694
- $row .= '</tr>';
695
-
696
- // Escaped piecemeal upstream; cannot be late-escaped until upstream UI output logic is reworked
697
- echo $row;
698
- }
699
- }
700
-
701
- echo '</table>';
702
- echo '</div>';
703
-
704
- if ($item_type == 'taxonomy') {
705
- if ($any_caps) {
706
- ob_flush();
707
- } else {
708
- ob_clean();
709
- }
710
- }
711
-
712
- } // end foreach item type
713
- }
714
-
715
- if (empty($caps_manager_postcaps_section)) {
716
- $caps_manager_postcaps_section = '';
717
- }
718
-
719
- do_action('publishpress-caps_manager_postcaps_section', compact('current', 'rcaps', 'pp_metagroup_caps', 'is_administrator', 'default_caps', 'custom_types', 'defined', 'unfiltered', 'pp_metagroup_caps','caps_manager_postcaps_section', 'active_tab_id'));
720
-
721
- $type_caps = apply_filters('publishpress_caps_manager_typecaps', $type_caps);
722
-
723
- // clicking on post type name toggles corresponding checkbox selections
724
- // caps: other
725
-
726
- $tab_id = "cme-cap-type-tables-other";
727
- $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
728
- ?>
729
- <div id="<?php echo esc_attr($tab_id);?>" style="display:<?php echo esc_attr($div_display);?>">
730
- <?php
731
-
732
- echo '<h3>' . esc_html__( 'WordPress Core Capabilities', 'capsman-enhanced' ) . '</h3>';
733
-
734
- echo '<div class="ppc-filter-wrapper">';
735
- echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capability-manager-enhanced') . '">';
736
- echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capability-manager-enhanced') . '</button>';
737
- echo '</div>';
738
- echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
739
-
740
- echo '<table class="widefat fixed striped form-table cme-checklist">';
741
-
742
- $centinel_ = true;
743
- $checks_per_row = get_option( 'cme_form-rows', 1 );
744
- $i = 0; $first_row = true;
745
-
746
- ?>
747
- <tr class="cme-bulk-select">
748
- <td colspan="<?php echo (int) $checks_per_row;?>">
749
- <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
750
- <span style="float:right">
751
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
752
- </span>
753
- </td>
754
- </tr>
755
-
756
- <?php
757
- $core_caps = _cme_core_caps();
758
- foreach( array_keys($core_caps) as $cap_name ) {
759
- $cap_name = sanitize_key($cap_name);
760
-
761
- if ( ! $is_administrator && ! current_user_can($cap_name) )
762
- continue;
763
-
764
- // Output first <tr>
765
- if ( $centinel_ == true ) {
766
- echo '<tr class="' . esc_attr($cap_name) . '">';
767
- $centinel_ = false;
768
- }
769
-
770
- if ( $i == $checks_per_row ) {
771
- echo '</tr><tr class="' . esc_attr($cap_name) . '">';
772
- $i = 0;
773
- }
774
-
775
- if ( ! isset( $rcaps[$cap_name] ) )
776
- $class = 'cap-no';
777
- else
778
- $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
779
-
780
- if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
781
- $class .= ' cap-metagroup';
782
- $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
783
- } else {
784
- $title_text = $cap_name;
785
- }
786
-
787
- $disabled = '';
788
- $checked = checked(1, ! empty($rcaps[$cap_name]), false );
789
- $lock_capability = false;
790
- $cap_title = $title_text;
791
-
792
- if ( 'read' == $cap_name ) {
793
- if ( ! empty( $block_read_removal ) ) {
794
- // prevent the read capability from being removed from a core role, but don't force it to be added
795
- if ( $checked || apply_filters( 'pp_caps_force_capability_storage', false, 'read', $default ) ) {
796
- if ( apply_filters( 'pp_caps_lock_capability', true, 'read', $default ) ) {
797
- $lock_capability = true;
798
- $class .= ' cap-locked';
799
- $disabled = ' disabled ';
800
- if ( 'administrator' != $this->current ) {
801
- $cap_title = __('Lockout Prevention: To remove read capability, first remove WordPress admin / editing capabilities, or add "dashboard_lockout_ok" capability', 'capsman-enhanced' );
802
- }
803
- }
804
- }
805
- }
806
- }
807
-
808
- ?>
809
- <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($cap_title);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
810
- <span>
811
- <?php
812
- echo esc_html(str_replace( '_', ' ', $cap_name));
813
- ?>
814
- </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
815
- <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
816
- <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
817
- <?php endif; ?>
818
- </td>
819
-
820
- <?php
821
-
822
- if ( $lock_capability ) {
823
- echo '<input type="hidden" name="caps[' . esc_attr($cap_name) . ']" value="1" />';
824
- }
825
-
826
- ++$i;
827
- }
828
-
829
- if ( $i == $checks_per_row ) {
830
- echo '</tr>';
831
- $i = 0;
832
- } elseif ( ! $first_row ) {
833
- // Now close a wellformed table
834
- for ( $i; $i < $checks_per_row; $i++ ){
835
- echo '<td>&nbsp;</td>';
836
- }
837
- echo '</tr>';
838
- }
839
- ?>
840
-
841
- <tr class="cme-bulk-select">
842
- <td colspan="<?php echo (int) $checks_per_row;?>">
843
- <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
844
- <span style="float:right">
845
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
846
- </span>
847
- </td>
848
- </tr>
849
-
850
- </table>
851
- </div>
852
-
853
- <?php
854
- $all_capabilities = apply_filters( 'capsman_get_capabilities', array_keys( $this->capabilities ), $this->ID );
855
- $all_capabilities = apply_filters( 'members_get_capabilities', $all_capabilities );
856
-
857
- // caps: plugins
858
- $plugin_caps = apply_filters('cme_plugin_capabilities', $plugin_caps);
859
-
860
- foreach($plugin_caps as $plugin_title => $__plugin_caps) {
861
- $plugin_title = esc_html($plugin_title);
862
-
863
- $_plugin_caps = array_fill_keys($__plugin_caps, true);
864
-
865
- $tab_id = 'cme-cap-type-tables-' . esc_attr(str_replace( ' ', '-', strtolower($plugin_title)));
866
- $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
867
-
868
- echo '<div id="' . esc_attr($tab_id) . '" style="display:' . esc_attr($div_display) . '">';
869
-
870
- echo '<h3 class="cme-cap-section">' . sprintf(esc_html__( 'Plugin Capabilities &ndash; %s', 'capsman-enhanced' ), esc_html(str_replace('_', ' ', $plugin_title))) . '</h3>';
871
-
872
- echo '<div class="ppc-filter-wrapper">';
873
- echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capability-manager-enhanced') . '">';
874
- echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capability-manager-enhanced') . '</button>';
875
- echo '</div>';
876
- echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
877
-
878
- echo '<table class="widefat fixed striped form-table cme-checklist">';
879
-
880
- $centinel_ = true;
881
- $checks_per_row = get_option( 'cme_form-rows', 1 );
882
- $i = 0; $first_row = true;
883
-
884
- ?>
885
- <tr class="cme-bulk-select">
886
- <td colspan="<?php echo (int) $checks_per_row;?>">
887
- <input type="checkbox" class="cme-check-all" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
888
- <span style="float:right">
889
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
890
- </span>
891
- </td>
892
- </tr>
893
- <?php
894
- foreach( array_keys($_plugin_caps) as $cap_name ) {
895
- $cap_name = sanitize_key($cap_name);
896
-
897
- if ( isset( $type_caps[$cap_name] ) || isset($core_caps[$cap_name]) || isset($type_metacaps[$cap_name]) ) {
898
- continue;
899
- }
900
-
901
- if ( ! $is_administrator && ! current_user_can($cap_name) )
902
- continue;
903
-
904
- // Output first <tr>
905
- if ( $centinel_ == true ) {
906
- echo '<tr class="' . esc_attr($cap_name) . '">';
907
- $centinel_ = false;
908
- }
909
-
910
- if ( $i == $checks_per_row ) {
911
- echo '</tr><tr class="' . esc_attr($cap_name) . '">';
912
- $i = 0;
913
- }
914
-
915
- if ( ! isset( $rcaps[$cap_name] ) )
916
- $class = 'cap-no';
917
- else
918
- $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
919
-
920
- if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
921
- $class .= ' cap-metagroup';
922
- $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
923
- } else {
924
- $title_text = $cap_name;
925
- }
926
-
927
- $disabled = '';
928
- $checked = checked(1, ! empty($rcaps[$cap_name]), false );
929
- $cap_title = $title_text;
930
- ?>
931
- <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($cap_title);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
932
- <span>
933
- <?php
934
- echo esc_html(str_replace( '_', ' ', $cap_name));
935
- ?>
936
- </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
937
- <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
938
- <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
939
- <?php endif; ?>
940
- </td>
941
-
942
- <?php
943
- ++$i;
944
- }
945
-
946
- if ( $i == $checks_per_row ) {
947
- echo '</tr>';
948
- $i = 0;
949
- } elseif ( ! $first_row ) {
950
- // Now close a wellformed table
951
- for ( $i; $i < $checks_per_row; $i++ ){
952
- echo '<td>&nbsp;</td>';
953
- }
954
- echo '</tr>';
955
- }
956
- ?>
957
-
958
- <tr class="cme-bulk-select">
959
- <td colspan="<?php echo (int) $checks_per_row;?>">
960
- <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
961
- <span style="float:right">
962
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
963
- </span>
964
- </td>
965
- </tr>
966
-
967
- </table>
968
- </div>
969
- <?php
970
- }
971
-
972
- // caps: invalid
973
- if (array_intersect(array_keys(array_filter($type_metacaps)), $all_capabilities) && array_intersect_key($type_metacaps, array_filter($rcaps))) {
974
- $tab_id = "cme-cap-type-tables-invalid";
975
- $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
976
-
977
- echo '<div id="' . esc_attr($tab_id) . '" style="display:' . esc_attr($div_display) . '">';
978
- echo '<h3 class="cme-cap-section">' . esc_html__( 'Invalid Capabilities', 'capsman-enhanced' ) . '</h3>';
979
- ?>
980
-
981
- <script type="text/javascript">
982
- /* <![CDATA[ */
983
- jQuery(document).ready( function($) {
984
- $('#cme_tab_invalid_caps').show();
985
- });
986
- /* ]]> */
987
- </script>
988
-
989
- <div>
990
- <span class="cme-subtext">
991
- <?php esc_html_e('The following entries have no effect. Please assign desired capabilities in the Read / Edit / Delete grid above.', 'capsman-enhanced');?>
992
- </span>
993
- </div>
994
-
995
- <table class="widefat fixed striped form-table cme-checklist">
996
- <tr>
997
- <?php
998
- $i = 0; $first_row = true;
999
-
1000
- foreach( $all_capabilities as $cap_name ) {
1001
- if ( ! isset($this->capabilities[$cap_name]) )
1002
- $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name );
1003
- }
1004
-
1005
- uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys );
1006
-
1007
- foreach ( $this->capabilities as $cap_name => $cap ) :
1008
- $cap_name = sanitize_key($cap_name);
1009
-
1010
- if (!isset($type_metacaps[$cap_name]) || empty($rcaps[$cap_name])) {
1011
- continue;
1012
- }
1013
-
1014
- if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) {
1015
- continue;
1016
- }
1017
-
1018
- if ( $i == $checks_per_row ) {
1019
- echo '</tr><tr>';
1020
- $i = 0; $first_row = false;
1021
- }
1022
-
1023
- if ( ! isset( $rcaps[$cap_name] ) )
1024
- $class = 'cap-no';
1025
- else
1026
- $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
1027
-
1028
- $title_text = $cap_name;
1029
-
1030
- $disabled = '';
1031
- $checked = checked(1, ! empty($rcaps[$cap_name]), false );
1032
- ?>
1033
- <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($title_text);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
1034
- <span>
1035
- <?php
1036
- echo esc_html(str_replace( '_', ' ', $cap ));
1037
- ?>
1038
- </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
1039
- <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
1040
- <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
1041
- <?php endif; ?>
1042
- </td>
1043
- <?php
1044
- $i++;
1045
- endforeach;
1046
-
1047
- if ( ! empty($lock_manage_caps_capability) ) {
1048
- echo '<input type="hidden" name="caps[manage_capabilities]" value="1" />';
1049
- }
1050
-
1051
- if ( $i == $checks_per_row ) {
1052
- echo '</tr><tr>';
1053
- $i = 0;
1054
- } else {
1055
- if ( ! $first_row ) {
1056
- // Now close a wellformed table
1057
- for ( $i; $i < $checks_per_row; $i++ ){
1058
- echo '<td>&nbsp;</td>';
1059
- }
1060
- echo '</tr>';
1061
- }
1062
- }
1063
- ?>
1064
-
1065
- </table>
1066
- </div>
1067
- <?php
1068
- } // endif any invalid caps
1069
-
1070
- $tab_id = "cme-cap-type-tables-additional";
1071
- $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
1072
- ?>
1073
- <div id="<?php echo esc_attr($tab_id);?>" style="display:<?php echo esc_attr($div_display);?>">
1074
- <?php
1075
- // caps: additional
1076
- echo '<h3 class="cme-cap-section">' . esc_html__( 'Additional Capabilities', 'capsman-enhanced' ) . '</h3>';
1077
-
1078
- echo '<div class="ppc-filter-wrapper">';
1079
- echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capability-manager-enhanced') . '">';
1080
- echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capability-manager-enhanced') . '</button>';
1081
- echo '</div>';
1082
- echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
1083
- ?>
1084
- <table class="widefat fixed striped form-table cme-checklist">
1085
-
1086
- <tr class="cme-bulk-select">
1087
- <td colspan="<?php echo (int) $checks_per_row;?>">
1088
- <input type="checkbox" class="cme-check-all" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
1089
- <span style="float:right">
1090
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
1091
- </span>
1092
- </td>
1093
- </tr>
1094
-
1095
- <?php
1096
- $centinel_ = true;
1097
- $i = 0; $first_row = true;
1098
-
1099
- foreach( $all_capabilities as $cap_name ) {
1100
- if ( ! isset($this->capabilities[$cap_name]) )
1101
- $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name );
1102
- }
1103
-
1104
- uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys );
1105
-
1106
- $additional_caps = apply_filters('publishpress_caps_manage_additional_caps', $this->capabilities);
1107
-
1108
- foreach ($additional_caps as $cap_name => $cap) :
1109
- $cap_name = sanitize_key($cap_name);
1110
-
1111
-
1112
- if ((isset($type_caps[$cap_name]) && !isset($type_metacaps[$cap_name]))
1113
- || isset($core_caps[$cap_name])
1114
- || (isset($type_metacaps[$cap_name]) && !empty($rcaps[$cap_name])) ) {
1115
- continue;
1116
- }
1117
-
1118
- if (!isset($type_metacaps[$cap_name]) || !empty($rcaps[$cap_name])) {
1119
- foreach(array_keys($plugin_caps) as $plugin_title) {
1120
- if ( in_array( $cap_name, $plugin_caps[$plugin_title]) ) {
1121
- continue 2;
1122
- }
1123
- }
1124
- }
1125
-
1126
- if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) {
1127
- continue;
1128
- }
1129
-
1130
- // Levels are not shown.
1131
- if ( preg_match( '/^level_(10|[0-9])$/i', $cap_name ) ) {
1132
- continue;
1133
- }
1134
-
1135
- // Output first <tr>
1136
- if ( $centinel_ == true ) {
1137
- echo '<tr class="' . esc_attr($cap_name) . '">';
1138
- $centinel_ = false;
1139
- }
1140
-
1141
- if ( $i == $checks_per_row ) {
1142
- echo '</tr><tr class="' . esc_attr($cap_name) . '">';
1143
- $i = 0; $first_row = false;
1144
- }
1145
-
1146
- if ( ! isset( $rcaps[$cap_name] ) )
1147
- $class = 'cap-no';
1148
- else
1149
- $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
1150
-
1151
- if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
1152
- $class .= ' cap-metagroup';
1153
- $title_text = sprintf( esc_html__( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
1154
- } else {
1155
- $title_text = $cap_name;
1156
- }
1157
-
1158
- $disabled = '';
1159
- $checked = checked(1, ! empty($rcaps[$cap_name]), false );
1160
-
1161
- if ( 'manage_capabilities' == $cap_name ) {
1162
- if (!current_user_can('administrator') && (!is_multisite() || !is_super_admin())) {
1163
- continue;
1164
- } elseif ( 'administrator' == $default ) {
1165
- $class .= ' cap-locked';
1166
- $lock_manage_caps_capability = true;
1167
- $disabled = ' disabled ';
1168
- }
1169
- }
1170
- ?>
1171
- <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($title_text);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . ' ' . esc_attr($disabled);?> />
1172
- <span>
1173
- <?php
1174
- echo esc_html(str_replace( '_', ' ', $cap ));
1175
- ?>
1176
- </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
1177
- <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
1178
- <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
1179
- <?php endif; ?>
1180
- </td>
1181
- <?php
1182
- $i++;
1183
- endforeach;
1184
-
1185
- if ( ! empty($lock_manage_caps_capability) ) {
1186
- echo '<input type="hidden" name="caps[manage_capabilities]" value="1" />';
1187
- }
1188
-
1189
- if ( $i == $checks_per_row ) {
1190
- echo '</tr><tr>';
1191
- $i = 0;
1192
- } else {
1193
- if ( ! $first_row ) {
1194
- // Now close a wellformed table
1195
- for ( $i; $i < $checks_per_row; $i++ ){
1196
- echo '<td>&nbsp;</td>';
1197
- }
1198
- echo '</tr>';
1199
- }
1200
- }
1201
- ?>
1202
-
1203
- <tr class="cme-bulk-select">
1204
- <td colspan="<?php echo (int) $checks_per_row;?>">
1205
- <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capability-manager-enhanced');?></span>
1206
- <span style="float:right">
1207
- &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
1208
- </span>
1209
- </td>
1210
- </tr>
1211
-
1212
- </table>
1213
- </div>
1214
- </div>
1215
- </div>
1216
-
1217
-
1218
- <script type="text/javascript">
1219
- /* <![CDATA[ */
1220
- jQuery(document).ready( function($) {
1221
- $('a[href="#pp-more"]').click( function() {
1222
- $('#pp_features').show();
1223
- return false;
1224
- });
1225
- $('a[href="#pp-hide"]').click( function() {
1226
- $('#pp_features').hide();
1227
- return false;
1228
- });
1229
- });
1230
- /* ]]> */
1231
- </script>
1232
-
1233
- <?php /* play.png icon by Pavel: http://kde-look.org/usermanager/search.php?username=InFeRnODeMoN */ ?>
1234
-
1235
- <div id="pp_features" style="display:none"><div class="pp-logo"><a href="https://publishpress.com/presspermit/"><img src="<?php echo esc_url_raw($img_url);?>pp-logo.png" alt="<?php esc_attr_e('PublishPress Permissions', 'capsman-enhanced');?>" /></a></div><div class="features-wrap"><ul class="pp-features">
1236
- <li>
1237
- <?php esc_html_e( "Automatically define type-specific capabilities for your custom post types and taxonomies", 'capsman-enhanced' );?>
1238
- <a href="https://presspermit.com/tutorial/regulate-post-type-access" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1239
-
1240
- <li>
1241
- <?php esc_html_e( "Assign standard WP roles supplementally for a specific post type", 'capsman-enhanced' );?>
1242
- <a href="https://presspermit.com/tutorial/regulate-post-type-access" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1243
-
1244
- <li>
1245
- <?php esc_html_e( "Assign custom WP roles supplementally for a specific post type <em>(Pro)</em>", 'capsman-enhanced' );?>
1246
- </li>
1247
-
1248
- <li>
1249
- <?php esc_html_e( "Customize reading permissions per-category or per-post", 'capsman-enhanced' );?>
1250
- <a href="https://presspermit.com/tutorial/category-exceptions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1251
-
1252
- <li>
1253
- <?php esc_html_e( "Customize editing permissions per-category or per-post <em>(Pro)</em>", 'capsman-enhanced' );?>
1254
- <a href="https://presspermit.com/tutorial/page-editing-exceptions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1255
-
1256
- <li>
1257
- <?php esc_html_e( "Custom Post Visibility statuses, fully implemented throughout wp-admin <em>(Pro)</em>", 'capsman-enhanced' );?>
1258
- <a href="https://presspermit.com/tutorial/custom-post-visibility" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1259
-
1260
- <li>
1261
- <?php esc_html_e( "Custom Moderation statuses for access-controlled, multi-step publishing workflow <em>(Pro)</em>", 'capsman-enhanced' );?>
1262
- <a href="https://presspermit.com/tutorial/multi-step-moderation" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1263
-
1264
- <li>
1265
- <?php esc_html_e( "Regulate permissions for Edit Flow post statuses <em>(Pro)</em>", 'capsman-enhanced' );?>
1266
- <a href="https://presspermit.com/tutorial/edit-flow-integration" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1267
-
1268
- <li>
1269
- <?php esc_html_e( "Customize the moderated editing of published content with Revisionary or Post Forking <em>(Pro)</em>", 'capsman-enhanced' );?>
1270
- <a href="https://presspermit.com/tutorial/published-content-revision" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1271
-
1272
- <li>
1273
- <?php esc_html_e( "Grant Spectator, Participant or Moderator access to specific bbPress forums <em>(Pro)</em>", 'capsman-enhanced' );?>
1274
- </li>
1275
-
1276
- <li>
1277
- <?php esc_html_e( "Grant supplemental content permissions to a BuddyPress group <em>(Pro)</em>", 'capsman-enhanced' );?>
1278
- <a href="https://presspermit.com/tutorial/buddypress-content-permissions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1279
-
1280
- <li>
1281
- <?php esc_html_e( "WPML integration to mirror permissions to translations <em>(Pro)</em>", 'capsman-enhanced' );?>
1282
- </li>
1283
-
1284
- <li>
1285
- <?php esc_html_e( "Member support forum", 'capsman-enhanced' );?>
1286
- </li>
1287
-
1288
- </ul></div>
1289
-
1290
- <?php
1291
- echo '<div>';
1292
- printf( esc_html__('%1$sgrab%2$s %3$s', 'capsman-enhanced'), '<strong>', '</strong>', '<span class="plugins update-message"><a href="' . esc_url_raw(cme_plugin_info_url('press-permit-core')) . '" class="thickbox" title="' . sprintf( esc_attr__('%s (free install)', 'capsman-enhanced'), 'Permissions Pro' ) . '">Permissions Pro</a></span>' );
1293
- echo '&nbsp;&nbsp;&bull;&nbsp;&nbsp;';
1294
- printf( esc_html__('%1$sbuy%2$s %3$s', 'capsman-enhanced'), '<strong>', '</strong>', '<a href="https://publishpress.com/presspermit/" target="_blank" title="' . sprintf( esc_attr__('%s info/purchase', 'capsman-enhanced'), 'Permissions Pro' ) . '">Permissions&nbsp;Pro</a>' );
1295
- echo '&nbsp;&nbsp;&bull;&nbsp;&nbsp;';
1296
- echo '<a href="#pp-hide">hide</a>';
1297
- echo '</div></div>';
1298
-
1299
- ///
1300
- ?>
1301
- <script type="text/javascript">
1302
- /* <![CDATA[ */
1303
- jQuery(document).ready( function($) {
1304
- $('a[href="#toggle_type_caps"]').click( function() {
1305
- var chks = $(this).closest('tr').find('input');
1306
- var set_checked = ! $(chks).first().is(':checked');
1307
-
1308
- $(chks).each(function(i,e) {
1309
- $('input[name="' + $(this).attr('name') + '"]').prop('checked', set_checked);
1310
- });
1311
-
1312
- return false;
1313
- });
1314
-
1315
- $('input[name^="caps["]').click(function() {
1316
- $('input[name="' + $(this).attr('name') + '"]').prop('checked', $(this).prop('checked'));
1317
- });
1318
- });
1319
- /* ]]> */
1320
- </script>
1321
-
1322
- <div style="display:none; float:right;">
1323
- <?php
1324
- $level = ak_caps2level($rcaps);
1325
- ?>
1326
- <span title="<?php esc_attr_e('Role level is mostly deprecated. However, it still determines eligibility for Post Author assignment and limits the application of user editing capabilities.', 'capsman-enhanced');?>">
1327
-
1328
- <?php (in_array(get_locale(), ['en_EN', 'en_US'])) ? printf('Role Level:') : esc_html_e('Level:', 'capsman-enhanced');?> <select name="level">
1329
- <?php for ( $l = $this->max_level; $l >= 0; $l-- ) {?>
1330
- <option value="<?php echo (int) $l; ?>" style="text-align:right;"<?php selected($level, $l); ?>>&nbsp;<?php echo (int) $l; ?>&nbsp;</option>
1331
- <?php }
1332
- ?>
1333
- </select>
1334
- </span>
1335
-
1336
- </div>
1337
-
1338
- <?php
1339
- $support_pp_only_roles = defined('PRESSPERMIT_ACTIVE');
1340
- cme_network_role_ui( $default );
1341
- ?>
1342
-
1343
- <p class="submit" style="padding-top:0;">
1344
- <input type="hidden" name="action" value="update" />
1345
- <input type="hidden" name="current" value="<?php echo esc_attr($default); ?>" />
1346
-
1347
- <?php
1348
- $save_caption = (in_array(sanitize_key(get_locale()), ['en_EN', 'en_US'])) ? 'Save Capabilities' : __('Save Changes', 'capsman-enhanced');
1349
- ?>
1350
- <input type="submit" name="SaveRole" value="<?php echo esc_attr($save_caption);?>" class="button-primary" /> &nbsp;
1351
- </p>
1352
-
1353
- </div><!-- .pp-column-left -->
1354
- <div class="pp-column-right capabilities-sidebar">
1355
- <?php
1356
- do_action('publishpress-caps_sidebar_top');
1357
-
1358
- $banners = new PublishPress\WordPressBanners\BannersMain;
1359
- $banners->pp_display_banner(
1360
- '',
1361
- __( 'PublishPress Capabilities is safe to use', 'capsman-enhanced' ),
1362
- array(
1363
- __( 'This plugin automatically creates a backup whenever you save changes. You can use these backups to
1364
- restore an earlier version of your roles and capabilities.', 'capsman-enhanced' )
1365
- ),
1366
- admin_url( 'admin.php?page=pp-capabilities-backup' ),
1367
- __( 'Go to the Backup feature', 'capsman-enhanced' )
1368
- );
1369
- ?>
1370
-
1371
- <dl>
1372
- <dt><?php esc_html_e('Add Capability', 'capsman-enhanced'); ?></dt>
1373
- <dd style="text-align:center;">
1374
- <p><input type="text" name="capability-name" class="regular-text" placeholder="<?php echo 'capability_name';?>" /><br />
1375
- <input type="submit" name="AddCap" value="<?php esc_attr_e('Add to role', 'capsman-enhanced') ?>" class="button" /></p>
1376
- </dd>
1377
- </dl>
1378
-
1379
- <?php
1380
- $pp_ui->pp_types_ui( $defined['type'] );
1381
- $pp_ui->pp_taxonomies_ui( $defined['taxonomy'] );
1382
-
1383
- do_action('publishpress-caps_sidebar_bottom');
1384
- ?>
1385
-
1386
- </div><!-- .pp-column-right -->
1387
- </div><!-- .pp-columns-wrapper -->
1388
- </td></tr></table> <!-- .akmin -->
1389
- </fieldset>
1390
- </form>
1391
-
1392
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
1393
- cme_publishpressFooter();
1394
- }
1395
- ?>
1396
- </div>
1397
-
1398
- <?php
1399
- function cme_network_role_ui( $default ) {
1400
- if (!is_multisite() || !is_super_admin() || !is_main_site()) {
1401
- return false;
1402
- }
1403
- ?>
1404
-
1405
- <div style="float:right;margin-left:10px;margin-right:10px">
1406
- <?php
1407
- if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) )
1408
- $autocreate_roles = array();
1409
- ?>
1410
- <div style="margin-bottom: 5px">
1411
- <label for="cme_autocreate_role" title="<?php esc_attr_e('Create this role definition in new (future) sites', 'capsman-enhanced');?>"><input type="checkbox" name="cme_autocreate_role" id="cme_autocreate_role" autocomplete="off" value="1" <?php echo checked(in_array($default, $autocreate_roles));?>> <?php esc_html_e('include in new sites', 'capsman-enhanced'); ?> </label>
1412
- </div>
1413
- <div>
1414
- <label for="cme_net_sync_role" title="<?php echo esc_attr__('Copy / update this role definition to all sites now', 'capsman-enhanced');?>"><input type="checkbox" name="cme_net_sync_role" id="cme_net_sync_role" autocomplete="off" value="1"> <?php esc_html_e('sync role to all sites now', 'capsman-enhanced'); ?> </label>
1415
- </div>
1416
- <div>
1417
- <label for="cme_net_sync_options" title="<?php echo esc_attr__('Copy option settings to all sites now', 'capsman-enhanced');?>"><input type="checkbox" name="cme_net_sync_options" id="cme_net_sync_options" autocomplete="off" value="1"> <?php esc_html_e('sync options to all sites now', 'capsman-enhanced'); ?> </label>
1418
- </div>
1419
- </div>
1420
- <?php
1421
- return true;
1422
- }
1423
-
1424
- function cme_plugin_info_url( $plugin_slug ) {
1425
- $_url = "plugin-install.php?tab=plugin-information&plugin=$plugin_slug&TB_iframe=true&width=640&height=678";
1426
- return ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
1427
- }
1
+ <?php
2
+ /**
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * UI output for Capabilities screen.
6
+ *
7
+ * Provides admin pages to create and manage roles and capabilities.
8
+ *
9
+ * @author Jordi Canals, Kevin Behrens
10
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals, (C) 2020 PublishPress
11
+ * @license GNU General Public License version 2
12
+ * @link https://publishpress.com
13
+ *
14
+ * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
15
+ * Modifications Copyright 2020, PublishPress <help@publishpress.com>
16
+ *
17
+ * This program is free software; you can redistribute it and/or
18
+ * modify it under the terms of the GNU General Public License
19
+ * version 2 as published by the Free Software Foundation.
20
+ *
21
+ * This program is distributed in the hope that it will be useful,
22
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ * GNU General Public License for more details.
25
+ *
26
+ * You should have received a copy of the GNU General Public License
27
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28
+ **/
29
+
30
+ global $capsman, $cme_cap_helper, $current_user;
31
+
32
+ do_action('publishpress-caps_manager-load');
33
+
34
+ $roles = $this->roles;
35
+ $default = $this->current;
36
+
37
+ if ( $block_read_removal = _cme_is_read_removal_blocked( $this->current ) ) {
38
+ if ( $current = get_role($default) ) {
39
+ if ( empty( $current->capabilities['read'] ) ) {
40
+ ak_admin_error( sprintf( __( 'Warning: This role cannot access the dashboard without the read capability. %1$sClick here to fix this now%2$s.', 'capsman-enhanced' ), '<a href="javascript:void(0)" class="cme-fix-read-cap">', '</a>' ) );
41
+ }
42
+ }
43
+ }
44
+
45
+ require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
46
+
47
+ require_once( dirname(__FILE__).'/pp-ui.php' );
48
+ $pp_ui = new Capsman_PP_UI();
49
+
50
+ if( defined('PRESSPERMIT_ACTIVE') ) {
51
+ $pp_metagroup_caps = $pp_ui->get_metagroup_caps( $default );
52
+ } else {
53
+ $pp_metagroup_caps = array();
54
+ }
55
+ ?>
56
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper">
57
+ <div id="icon-capsman-admin" class="icon32"></div>
58
+
59
+ <h1><?php esc_html_e('Role Capabilities', 'capsman-enhanced') ?></h1>
60
+
61
+ <?php
62
+ pp_capabilities_roles()->notify->display();
63
+ ?>
64
+
65
+ <script type="text/javascript">
66
+ /* <![CDATA[ */
67
+ jQuery(document).ready( function($) {
68
+ $('#publishpress_caps_form').attr('action', 'admin.php?page=pp-capabilities&role=' + $('select[name="role"]').val());
69
+
70
+ $('select[name="role"]').change(function(){
71
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities&role=')); ?>' + $(this).val() + '';
72
+ });
73
+ });
74
+ /* ]]> */
75
+ </script>
76
+
77
+ <form id="publishpress_caps_form" method="post" action="admin.php?page=<?php echo esc_attr($this->ID);?>">
78
+ <?php wp_nonce_field('capsman-general-manager'); ?>
79
+
80
+ <?php
81
+ if (empty($_REQUEST['pp_caps_tab']) && !empty($_REQUEST['added'])) {
82
+ $pp_tab = 'additional';
83
+ } else {
84
+ $pp_tab = (!empty($_REQUEST['pp_caps_tab'])) ? sanitize_key($_REQUEST['pp_caps_tab']) : 'edit';
85
+ }
86
+ ?>
87
+
88
+ <input type="hidden" name="pp_caps_tab" value="<?php echo esc_attr($pp_tab);?>" />
89
+
90
+ <p>
91
+ <select name="role">
92
+ <?php
93
+ foreach ( $roles as $role_name => $name ) {
94
+ $role_name = sanitize_key($role_name);
95
+
96
+ if (pp_capabilities_is_editable_role($role_name)) {
97
+ $name = translate_user_role($name);
98
+ echo '<option value="' . esc_attr($role_name) .'"'; selected($default, $role_name); echo '> ' . esc_html($name) . ' &nbsp;</option>';
99
+ }
100
+ }
101
+ ?>
102
+ </select>
103
+ </p>
104
+
105
+ <fieldset>
106
+ <table id="akmin"><tr><td>
107
+ <div class="pp-columns-wrapper pp-enable-sidebar">
108
+ <div class="pp-column-left">
109
+
110
+ <div style="float:right">
111
+
112
+ <?php
113
+ $caption = (in_array(sanitize_key(get_locale()), ['en_EN', 'en_US'])) ? 'Save Capabilities' : __('Save Changes', 'capsman-enhanced');
114
+ ?>
115
+ <input type="submit" name="SaveRole" value="<?php echo esc_attr($caption);?>" class="button-primary" />
116
+ </div>
117
+
118
+ <?php
119
+ $img_url = $capsman->mod_url . '/images/';
120
+ ?>
121
+ <div class="publishpress-headline" style="margin-bottom:20px;">
122
+ <span class="cme-subtext">
123
+ <?php
124
+
125
+ if (defined('PRESSPERMIT_ACTIVE') && function_exists('presspermit')) {
126
+ if ($group = presspermit()->groups()->getMetagroup('wp_role', $this->current)) {
127
+ printf(
128
+ // back compat with existing language string
129
+ str_replace(
130
+ ['&lt;strong&gt;', '&lt;/strong&gt;'],
131
+ ['<strong>', '</strong>'],
132
+ esc_html__('<strong>Note:</strong> Capability changes <strong>remain in the database</strong> after plugin deactivation. You can also configure this role as a %sPermission Group%s.', 'capsman-enhanced')
133
+ ),
134
+ '<a href="' . esc_url_raw(admin_url("admin.php?page=presspermit-edit-permissions&action=edit&agent_id={$group->ID}")) . '">',
135
+ '</a>'
136
+ );
137
+ }
138
+ } else {
139
+ // unescaped for now for back compat with existing language string
140
+ _e( '<strong>Note:</strong> Capability changes <strong>remain in the database</strong> after plugin deactivation.', 'capsman-enhanced' );
141
+ }
142
+
143
+ ?>
144
+ </span>
145
+ </div>
146
+
147
+ <?php
148
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
149
+ $pp_ui->show_capability_hints( $default );
150
+ }
151
+
152
+ if ( MULTISITE ) {
153
+ global $wp_roles;
154
+ global $wpdb;
155
+
156
+ if ( ! empty($_REQUEST['cme_net_sync_role'] ) ) {
157
+ $main_site_id = (function_exists('get_main_site_id')) ? get_main_site_id() : 1;
158
+ switch_to_blog($main_site_id);
159
+ wp_cache_delete( $wpdb->prefix . 'user_roles', 'options' );
160
+ }
161
+
162
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
163
+ }
164
+ $capsman->reinstate_db_roles();
165
+
166
+ $current = get_role($default);
167
+
168
+ $rcaps = $current->capabilities;
169
+
170
+ $is_administrator = current_user_can( 'administrator' ) || (is_multisite() && is_super_admin());
171
+
172
+ $custom_types = get_post_types( array( '_builtin' => false ), 'names' );
173
+ $custom_tax = get_taxonomies( array( '_builtin' => false ), 'names' );
174
+
175
+ $defined = [];
176
+ $defined['type'] = apply_filters('cme_filterable_post_types', get_post_types(['public' => true, 'show_ui' => true], 'object', 'or'));
177
+ $defined['taxonomy'] = apply_filters('cme_filterable_taxonomies', get_taxonomies(['public' => true, 'show_ui' => true], 'object', 'or'));
178
+
179
+ // bbPress' dynamic role def requires additional code to enforce stored caps
180
+ $unfiltered['type'] = apply_filters('presspermit_unfiltered_post_types', ['forum','topic','reply','wp_block']);
181
+ $unfiltered['type'] = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered['type'] : apply_filters('pp_unfiltered_post_types', $unfiltered['type']);
182
+
183
+ $unfiltered['taxonomy'] = apply_filters('presspermit_unfiltered_post_types', ['post_status', 'topic-tag']); // avoid confusion with Edit Flow administrative taxonomy
184
+ $unfiltered['taxonomy'] = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered['taxonomy'] : apply_filters('pp_unfiltered_taxonomies', $unfiltered['taxonomy']);
185
+
186
+ $enabled_taxonomies = cme_get_assisted_taxonomies();
187
+
188
+ $cap_properties['edit']['type'] = array( 'edit_posts' );
189
+
190
+ foreach( $defined['type'] as $type_obj ) {
191
+ if ( 'attachment' != $type_obj->name ) {
192
+ if ( isset( $type_obj->cap->create_posts ) && ( $type_obj->cap->create_posts != $type_obj->cap->edit_posts ) ) {
193
+ $cap_properties['edit']['type'][]= 'create_posts';
194
+ break;
195
+ }
196
+ }
197
+ }
198
+
199
+ $cap_properties['edit']['type'][]= 'edit_others_posts';
200
+ $cap_properties['edit']['type'] = array_merge( $cap_properties['edit']['type'], array( 'publish_posts', 'edit_published_posts', 'edit_private_posts' ) );
201
+
202
+ $cap_properties['edit']['taxonomy'] = array( 'manage_terms' );
203
+
204
+ if ( ! defined( 'OLD_PRESSPERMIT_ACTIVE' ) )
205
+ $cap_properties['edit']['taxonomy'] = array_merge( $cap_properties['edit']['taxonomy'], array( 'edit_terms', 'assign_terms' ) );
206
+
207
+ $cap_properties['delete']['type'] = array( 'delete_posts', 'delete_others_posts' );
208
+ $cap_properties['delete']['type'] = array_merge( $cap_properties['delete']['type'], array( 'delete_published_posts', 'delete_private_posts' ) );
209
+
210
+ if ( ! defined( 'OLD_PRESSPERMIT_ACTIVE' ) )
211
+ $cap_properties['delete']['taxonomy'] = array( 'delete_terms' );
212
+ else
213
+ $cap_properties['delete']['taxonomy'] = array();
214
+
215
+ $cap_properties['read']['type'] = array( 'read_private_posts' );
216
+ $cap_properties['read']['taxonomy'] = array();
217
+
218
+ $stati = get_post_stati( array( 'internal' => false ) );
219
+
220
+ $cap_type_names = array(
221
+ '' => __( '&nbsp;', 'capsman-enhanced' ),
222
+ 'read' => __( 'Reading', 'capsman-enhanced' ),
223
+ 'edit' => __( 'Editing', 'capsman-enhanced' ),
224
+ 'delete' => __( 'Deletion', 'capsman-enhanced' )
225
+ );
226
+
227
+ $cap_tips = array(
228
+ 'read_private' => esc_attr__( 'can read posts which are currently published with private visibility', 'capsman-enhanced' ),
229
+ 'edit' => esc_attr__( 'has basic editing capability (but may need other capabilities based on post status and ownership)', 'capsman-enhanced' ),
230
+ 'edit_others' => esc_attr__( 'can edit posts which were created by other users', 'capsman-enhanced' ),
231
+ 'edit_published' => esc_attr__( 'can edit posts which are currently published', 'capsman-enhanced' ),
232
+ 'edit_private' => esc_attr__( 'can edit posts which are currently published with private visibility', 'capsman-enhanced' ),
233
+ 'publish' => esc_attr__( 'can make a post publicly visible', 'capsman-enhanced' ),
234
+ 'delete' => esc_attr__( 'has basic deletion capability (but may need other capabilities based on post status and ownership)', 'capsman-enhanced' ),
235
+ 'delete_others' => esc_attr__( 'can delete posts which were created by other users', 'capsman-enhanced' ),
236
+ 'delete_published' => esc_attr__( 'can delete posts which are currently published', 'capsman-enhanced' ),
237
+ 'delete_private' => esc_attr__( 'can delete posts which are currently published with private visibility', 'capsman-enhanced' ),
238
+ );
239
+
240
+ $default_caps = array( 'read_private_posts', 'edit_posts', 'edit_others_posts', 'edit_published_posts', 'edit_private_posts', 'publish_posts', 'delete_posts', 'delete_others_posts', 'delete_published_posts', 'delete_private_posts',
241
+ 'read_private_pages', 'edit_pages', 'edit_others_pages', 'edit_published_pages', 'edit_private_pages', 'publish_pages', 'delete_pages', 'delete_others_pages', 'delete_published_pages', 'delete_private_pages',
242
+ 'manage_categories'
243
+ );
244
+ $type_caps = array();
245
+ $type_metacaps = array();
246
+
247
+ // Role Scoper and PP1 adjust attachment access based only on user's capabilities for the parent post
248
+ if ( defined('OLD_PRESSPERMIT_ACTIVE') ) {
249
+ unset( $defined['type']['attachment'] );
250
+ }
251
+ ?>
252
+
253
+ <script type="text/javascript">
254
+ /* <![CDATA[ */
255
+ jQuery(document).ready( function($) {
256
+ // Tabs and Content display
257
+ $('.ppc-capabilities-tabs > ul > li').click( function() {
258
+ var $pp_tab = $(this).attr('data-content');
259
+
260
+ $("[name='pp_caps_tab']").val($(this).attr('data-slug'));
261
+
262
+ // Show current Content
263
+ $('.ppc-capabilities-content > div').hide();
264
+ $('#' + $pp_tab).show();
265
+
266
+ $('#' + $pp_tab + '-taxonomy').show();
267
+
268
+ // Active current Tab
269
+ $('.ppc-capabilities-tabs > ul > li').removeClass('ppc-capabilities-tab-active');
270
+ $(this).addClass('ppc-capabilities-tab-active');
271
+ });
272
+ });
273
+ /* ]]> */
274
+ </script>
275
+
276
+ <div id="ppc-capabilities-wrapper" class="postbox">
277
+ <div class="ppc-capabilities-tabs">
278
+ <ul>
279
+ <?php
280
+ if (empty($_REQUEST['pp_caps_tab']) && !empty($_REQUEST['added'])) {
281
+ $active_tab_slug = 'additional';
282
+ } else {
283
+ $active_tab_slug = (!empty($_REQUEST['pp_caps_tab'])) ? sanitize_key($_REQUEST['pp_caps_tab']) : 'edit';
284
+ }
285
+
286
+ $active_tab_id = "cme-cap-type-tables-{$active_tab_slug}";
287
+
288
+ $ppc_tab_active = 'ppc-capabilities-tab-active';
289
+
290
+ // caps: edit, delete, read
291
+ foreach( array_keys($cap_properties) as $cap_type ) {
292
+ $tab_id = "cme-cap-type-tables-$cap_type";
293
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
294
+
295
+ echo '<li data-slug="'. esc_attr($cap_type) . '"' . ' data-content="cme-cap-type-tables-' . esc_attr($cap_type) . '" class="' . esc_attr($tab_active) . '">'
296
+ . esc_html($cap_type_names[$cap_type]) .
297
+ '</li>';
298
+ }
299
+
300
+ if ($extra_tabs = apply_filters('pp_capabilities_extra_post_capability_tabs', [])) {
301
+ foreach($extra_tabs as $tab_slug => $tab_caption) {
302
+ $tab_slug = esc_attr($tab_slug);
303
+
304
+ $tab_id = "cme-cap-type-tables-{$tab_slug}";
305
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
306
+
307
+ echo '<li data-slug="' . esc_attr($tab_slug) . '"' . ' data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">'
308
+ . esc_html($tab_caption) .
309
+ '</li>';
310
+ }
311
+ }
312
+
313
+ // caps: other
314
+ $tab_id = "cme-cap-type-tables-other";
315
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
316
+ $tab_caption = esc_html__( 'WordPress Core', 'capsman-enhanced' );
317
+
318
+ echo '<li data-slug="other" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">' . esc_html($tab_caption) . '</li>';
319
+
320
+ // caps: plugins
321
+ $plugin_caps = [];
322
+ if (defined('PUBLISHPRESS_VERSION')) {
323
+ $plugin_caps['PublishPress'] = apply_filters('cme_publishpress_capabilities',
324
+ array(
325
+ 'edit_metadata',
326
+ 'edit_post_subscriptions',
327
+ 'pp_manage_roles',
328
+ 'pp_set_notification_channel',
329
+ 'pp_view_calendar',
330
+ 'pp_view_content_overview',
331
+ )
332
+ );
333
+ }
334
+
335
+ //PublishPress Capabilities Capabilities
336
+ $plugin_caps['PublishPress Capabilities'] = apply_filters('cme_publishpress_capabilities_capabilities',
337
+ array(
338
+ 'manage_capabilities',
339
+ )
340
+ );
341
+
342
+ if (defined('PUBLISHPRESS_MULTIPLE_AUTHORS_VERSION')) {
343
+ if ($_caps = apply_filters('cme_multiple_authors_capabilities', array())) {
344
+ $plugin_caps['PublishPress Authors'] = $_caps;
345
+ }
346
+ }
347
+
348
+ if (defined('PRESSPERMIT_VERSION')) {
349
+ $plugin_caps['PublishPress Permissions'] = apply_filters('cme_presspermit_capabilities',
350
+ array(
351
+ 'edit_own_attachments',
352
+ 'list_others_unattached_files',
353
+ 'pp_administer_content',
354
+ 'pp_assign_roles',
355
+ 'pp_associate_any_page',
356
+ 'pp_create_groups',
357
+ 'pp_create_network_groups',
358
+ 'pp_define_moderation',
359
+ 'pp_define_post_status',
360
+ 'pp_define_privacy',
361
+ 'pp_delete_groups',
362
+ 'pp_edit_groups',
363
+ 'pp_exempt_edit_circle',
364
+ 'pp_exempt_read_circle',
365
+ 'pp_force_quick_edit',
366
+ 'pp_list_all_files',
367
+ 'pp_manage_capabilities',
368
+ 'pp_manage_members',
369
+ 'pp_manage_network_members',
370
+ 'pp_manage_settings',
371
+ 'pp_moderate_any',
372
+ 'pp_set_associate_exceptions',
373
+ 'pp_set_edit_exceptions',
374
+ 'pp_set_read_exceptions',
375
+ 'pp_set_revise_exceptions',
376
+ 'pp_set_term_assign_exceptions',
377
+ 'pp_set_term_associate_exceptions',
378
+ 'pp_set_term_manage_exceptions',
379
+ 'pp_unfiltered',
380
+ 'set_posts_status',
381
+ )
382
+ );
383
+ }
384
+
385
+ if (defined('WC_PLUGIN_FILE')) {
386
+ $plugin_caps['WooCommerce'] = apply_filters('cme_woocommerce_capabilities',
387
+ array(
388
+ 'assign_product_terms',
389
+ 'assign_shop_coupon_terms',
390
+ 'assign_shop_discount_terms',
391
+ 'assign_shop_order_terms',
392
+ 'assign_shop_payment_terms',
393
+ 'create_shop_orders',
394
+ 'delete_others_products',
395
+ 'delete_others_shop_coupons',
396
+ 'delete_others_shop_discounts',
397
+ 'delete_others_shop_orders',
398
+ 'delete_others_shop_payments',
399
+ 'delete_private_products',
400
+ 'delete_private_shop_coupons',
401
+ 'delete_private_shop_orders',
402
+ 'delete_private_shop_discounts',
403
+ 'delete_private_shop_payments',
404
+ 'delete_product_terms',
405
+ 'delete_products',
406
+ 'delete_published_products',
407
+ 'delete_published_shop_coupons',
408
+ 'delete_published_shop_discounts',
409
+ 'delete_published_shop_orders',
410
+ 'delete_published_shop_payments',
411
+ 'delete_shop_coupons',
412
+ 'delete_shop_coupon_terms',
413
+ 'delete_shop_discount_terms',
414
+ 'delete_shop_discounts',
415
+ 'delete_shop_order_terms',
416
+ 'delete_shop_orders',
417
+ 'delete_shop_payments',
418
+ 'delete_shop_payment_terms',
419
+ 'edit_others_products',
420
+ 'edit_others_shop_coupons',
421
+ 'edit_others_shop_discounts',
422
+ 'edit_others_shop_orders',
423
+ 'edit_others_shop_payments',
424
+ 'edit_private_products',
425
+ 'edit_private_shop_coupons',
426
+ 'edit_private_shop_discounts',
427
+ 'edit_private_shop_orders',
428
+ 'edit_private_shop_payments',
429
+ 'edit_product_terms',
430
+ 'edit_products',
431
+ 'edit_published_products',
432
+ 'edit_published_shop_coupons',
433
+ 'edit_published_shop_discounts',
434
+ 'edit_published_shop_orders',
435
+ 'edit_published_shop_payments',
436
+ 'edit_shop_coupon_terms',
437
+ 'edit_shop_coupons',
438
+ 'edit_shop_discounts',
439
+ 'edit_shop_discount_terms',
440
+ 'edit_shop_order_terms',
441
+ 'edit_shop_orders',
442
+ 'edit_shop_payments',
443
+ 'edit_shop_payment_terms',
444
+ 'export_shop_payments',
445
+ 'export_shop_reports',
446
+ 'import_shop_discounts',
447
+ 'import_shop_payments',
448
+ 'manage_product_terms',
449
+ 'manage_shop_coupon_terms',
450
+ 'manage_shop_discounts',
451
+ 'manage_shop_discount_terms',
452
+ 'manage_shop_payment_terms',
453
+ 'manage_shop_order_terms',
454
+ 'manage_shop_settings',
455
+ 'manage_woocommerce',
456
+ 'publish_products',
457
+ 'publish_shop_coupons',
458
+ 'publish_shop_discounts',
459
+ 'publish_shop_orders',
460
+ 'publish_shop_payments',
461
+ 'read_private_products',
462
+ 'read_private_shop_coupons',
463
+ 'read_private_shop_discounts',
464
+ 'read_private_shop_payments',
465
+ 'read_private_shop_orders',
466
+ 'view_admin_dashboard',
467
+ 'view_shop_discount_stats',
468
+ 'view_shop_payment_stats',
469
+ 'view_shop_reports',
470
+ 'view_shop_sensitive_data',
471
+ 'view_woocommerce_reports',
472
+ )
473
+ );
474
+ }
475
+ $plugin_caps = apply_filters('cme_plugin_capabilities', $plugin_caps);
476
+ foreach($plugin_caps as $plugin_title => $__plugin_caps) {
477
+ $plugin_title = esc_html($plugin_title);
478
+
479
+ $tab_slug = str_replace(' ', '-', strtolower(sanitize_title($plugin_title)));
480
+ $tab_id = 'cme-cap-type-tables-' . $tab_slug;
481
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
482
+
483
+ echo '<li data-slug="' . esc_attr($tab_slug) . '" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">'
484
+ . esc_html(str_replace('_', ' ', $plugin_title)) .
485
+ '</li>';
486
+ }
487
+
488
+ $tab_id = "cme-cap-type-tables-invalid";
489
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
490
+ $tab_caption = esc_html__( 'Invalid Capabilities', 'capsman-enhanced' );
491
+ echo '<li id="cme_tab_invalid_caps" data-slug="invalid" data-content="cme-cap-type-tables-' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '" style="display:none;">' . esc_html($tab_caption) . '</li>';
492
+
493
+ $tab_id = "cme-cap-type-tables-additional";
494
+ $tab_active = ($tab_id == $active_tab_id) ? $ppc_tab_active : '';
495
+ $tab_caption = esc_html__( 'Additional', 'capsman-enhanced' );
496
+ echo '<li data-slug="additional" data-content="' . esc_attr($tab_id) . '" class="' . esc_attr($tab_active) . '">' . esc_html($tab_caption) . '</li>';
497
+ ?>
498
+ </ul>
499
+ </div>
500
+ <div class="ppc-capabilities-content">
501
+ <?php
502
+ // caps: read, edit, deletion
503
+ foreach( array_keys($cap_properties) as $cap_type ) {
504
+
505
+ foreach( array_keys($defined) as $item_type ) {
506
+ if ( ( 'delete' == $cap_type ) && ( 'taxonomy' == $item_type ) ) {
507
+ if ( defined('OLD_PRESSPERMIT_ACTIVE') ) {
508
+ continue;
509
+ }
510
+
511
+ $any_term_deletion_caps = false;
512
+ foreach( array_keys($defined['taxonomy']) as $_tax ) {
513
+ if ( isset( $defined['taxonomy'][$_tax]->cap->delete_terms ) && ( 'manage_categories' != $defined['taxonomy'][$_tax]->cap->delete_terms ) && ! in_array( $_tax, $unfiltered['taxonomy'] ) ) {
514
+ $any_term_deletion_caps = true;
515
+ break;
516
+ }
517
+ }
518
+
519
+ if ( ! $any_term_deletion_caps )
520
+ continue;
521
+ }
522
+
523
+ if ( ! count( $cap_properties[$cap_type][$item_type] ) )
524
+ continue;
525
+
526
+ $tab_id = "cme-cap-type-tables-$cap_type";
527
+ $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
528
+
529
+ $any_caps = false;
530
+
531
+ if ($item_type == 'taxonomy') {
532
+ $tab_id .= '-taxonomy';
533
+
534
+ ob_start();
535
+ }
536
+
537
+ echo "<div id='" . esc_attr($tab_id) . "' style='display:" . esc_attr($div_display) . ";'>";
538
+
539
+ $caption_pattern = ('taxonomy' == $item_type) ? esc_html__('Term %s Capabilities', 'capsman-enhanced') : esc_html__('Post %s Capabilities', 'capsman-enhanced');
540
+
541
+ echo '<h3>' . sprintf($caption_pattern, esc_html($cap_type_names[$cap_type])) . '</h3>';
542
+
543
+ echo '<div class="ppc-filter-wrapper">';
544
+ echo '<select class="ppc-filter-select">';
545
+ $filter_caption = ('taxonomy' == $item_type) ? __('Filter by taxonomy', 'capsman-enhanced') : __('Filter by post type', 'capsman-enhanced');
546
+ echo '<option value="">' . esc_html($filter_caption) . '</option>';
547
+ echo '</select>';
548
+ echo ' <button class="button secondary-button ppc-filter-select-reset" type="button">' . esc_html__('Clear', 'capsman-enhanced') . '</button>';
549
+ echo '</div>';
550
+
551
+ echo "<table class='widefat fixed striped cme-typecaps cme-typecaps-" . esc_attr($cap_type) . "'>";
552
+
553
+ echo '<thead><tr><th></th>';
554
+
555
+ // label cap properties
556
+ foreach( $cap_properties[$cap_type][$item_type] as $prop ) {
557
+ $prop = str_replace( '_posts', '', $prop );
558
+ $prop = str_replace( '_pages', '', $prop );
559
+ $prop = str_replace( '_terms', '', $prop );
560
+ $tip = ( isset( $cap_tips[$prop] ) ) ? $cap_tips[$prop] : '';
561
+ $th_class = ( 'taxonomy' == $item_type ) ? 'term-cap' : 'post-cap';
562
+ echo "<th style='text-align:center;' title='" . esc_attr($tip) . "' class='" . esc_attr($th_class) . "'>";
563
+
564
+ if ( ( 'delete' != $prop ) || ( 'taxonomy' != $item_type ) || cme_get_detailed_taxonomies() ) {
565
+ echo str_replace('_', '<br />', esc_html(ucwords($prop)));
566
+ }
567
+
568
+ echo '</th>';
569
+ }
570
+
571
+ echo '</tr></thead>';
572
+
573
+ foreach( $defined[$item_type] as $key => $type_obj ) {
574
+ if ( in_array( $key, $unfiltered[$item_type] ) )
575
+ continue;
576
+
577
+ $row = "<tr class='cme_type_" . esc_attr($key) . "'>";
578
+
579
+ if ( $cap_type ) {
580
+ if ( empty($force_distinct_ui) && empty( $cap_properties[$cap_type][$item_type] ) )
581
+ continue;
582
+
583
+ $type_label = (defined('CME_LEGACY_MENU_NAME_LABEL') && !empty($type_obj->labels->menu_name)) ? $type_obj->labels->menu_name : $type_obj->labels->name;
584
+
585
+ $row .= "<td><a class='cap_type' href='#toggle_type_caps'>" . esc_html($type_label) . '</a>';
586
+ $row .= '<a href="#" class="neg-type-caps">&nbsp;x&nbsp;</a>';
587
+ $row .= '</td>';
588
+
589
+ $display_row = ! empty($force_distinct_ui);
590
+ $col_count = 0;
591
+
592
+ foreach( $cap_properties[$cap_type][$item_type] as $prop ) {
593
+ $td_classes = array();
594
+ $checkbox = '';
595
+ $cap_title = '';
596
+
597
+ if ( ! empty($type_obj->cap->$prop) && ( in_array( $type_obj->name, array( 'post', 'page' ) )
598
+ || ! in_array( $type_obj->cap->$prop, $default_caps )
599
+ || ( ( 'manage_categories' == $type_obj->cap->$prop ) && ( 'manage_terms' == $prop ) && ( 'category' == $type_obj->name ) ) ) ) {
600
+
601
+ // if edit_published or edit_private cap is same as edit_posts cap, don't display a checkbox for it
602
+ if ( ( ! in_array( $prop, array( 'edit_published_posts', 'edit_private_posts', 'create_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->edit_posts ) )
603
+ && ( ! in_array( $prop, array( 'delete_published_posts', 'delete_private_posts' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->delete_posts ) )
604
+ && ( ! in_array( $prop, array( 'edit_terms', 'delete_terms' ) ) || ( $type_obj->cap->$prop != $type_obj->cap->manage_terms ) )
605
+
606
+ && ( ! in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) )
607
+ || empty($cme_cap_helper->all_taxonomy_caps[$type_obj->cap->$prop])
608
+ || ( $cme_cap_helper->all_taxonomy_caps[ $type_obj->cap->$prop ] <= 1 )
609
+ || $type_obj->cap->$prop == str_replace( '_terms', "_{$type_obj->name}s", $prop )
610
+ || $type_obj->cap->$prop == str_replace( '_terms', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
611
+ )
612
+
613
+ && ( in_array( $prop, array( 'manage_terms', 'edit_terms', 'delete_terms', 'assign_terms' ) )
614
+ || empty($cme_cap_helper->all_type_caps[$type_obj->cap->$prop])
615
+ || ( $cme_cap_helper->all_type_caps[ $type_obj->cap->$prop ] <= 1 )
616
+ || $type_obj->cap->$prop == 'upload_files' && 'create_posts' == $prop && 'attachment' == $type_obj->name
617
+ || $type_obj->cap->$prop == str_replace( '_posts', "_{$type_obj->name}s", $prop )
618
+ || $type_obj->cap->$prop == str_replace( '_pages', "_{$type_obj->name}s", $prop )
619
+ || $type_obj->cap->$prop == str_replace( '_posts', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
620
+ || $type_obj->cap->$prop == str_replace( '_pages', "_" . _cme_get_plural($type_obj->name, $type_obj), $prop )
621
+ )
622
+ ) {
623
+ // only present these term caps up top if we are ensuring that they get enforced separately from manage_terms
624
+ if ( in_array( $prop, array( 'edit_terms', 'delete_terms', 'assign_terms' ) ) && ( ! in_array( $type_obj->name, cme_get_detailed_taxonomies() ) || defined( 'OLD_PRESSPERMIT_ACTIVE' ) ) ) {
625
+ continue;
626
+ }
627
+
628
+ $cap_name = sanitize_key($type_obj->cap->$prop);
629
+
630
+ if ( 'taxonomy' == $item_type )
631
+ $td_classes []= "term-cap";
632
+ else
633
+ $td_classes []= "post-cap";
634
+
635
+ if ( ! empty($pp_metagroup_caps[$cap_name]) )
636
+ $td_classes []='cm-has-via-pp';
637
+
638
+ if ( $is_administrator || current_user_can($cap_name) ) {
639
+ if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
640
+ $cap_title = sprintf(__( '%s: assigned by Permission Group', 'capsman-enhanced' ), esc_attr($cap_name) );
641
+ } else {
642
+ $cap_title = esc_attr($cap_name);
643
+ }
644
+
645
+ $checkbox = '<input type="checkbox" title="' . esc_attr($cap_title) . '" name="caps[' . esc_attr($cap_name) . ']" autocomplete="off" value="1" ' . checked(1, ! empty($rcaps[$cap_name]), false ) . ' />';
646
+
647
+ $type_caps [$cap_name] = true;
648
+ $display_row = true;
649
+ $any_caps = true;
650
+ }
651
+ } else {
652
+ $cap_title = sprintf( __( 'shared capability: %s', 'capsman-enhanced' ), esc_attr( $type_obj->cap->$prop ) );
653
+ }
654
+
655
+ if ( isset($rcaps[$cap_name]) && empty($rcaps[$cap_name]) ) {
656
+ $td_classes []= "cap-neg";
657
+ }
658
+ } else {
659
+ $td_classes []= "cap-unreg";
660
+ }
661
+
662
+ $td_class = ( $td_classes ) ? implode(' ', $td_classes) : '';
663
+
664
+ $row .= '<td class="' . esc_attr($td_class) . '" title="' . esc_attr($cap_title) . '"' . "><span class='cap-x'>X</span>$checkbox";
665
+
666
+ if ( false !== strpos( $td_class, 'cap-neg' ) )
667
+ $row .= '<input type="hidden" class="cme-negation-input" name="caps[' . esc_attr($cap_name) . ']" value="" />';
668
+
669
+ $row .= "</td>";
670
+
671
+ $col_count++;
672
+ }
673
+
674
+ if ('taxonomy' == $item_type) {
675
+ for ($i = $col_count; $i < 3; $i++) {
676
+ $row .= "<td></td>";
677
+ }
678
+ }
679
+
680
+ if (!empty($type_obj->map_meta_cap) && !defined('PP_CAPABILITIES_NO_INVALID_SECTION')) {
681
+ if ('type' == $item_type) {
682
+ $type_metacaps[$type_obj->cap->read_post] = true;
683
+ $type_metacaps[$type_obj->cap->edit_post] = isset($type_obj->cap->edit_posts) && ($type_obj->cap->edit_post != $type_obj->cap->edit_posts);
684
+ $type_metacaps[$type_obj->cap->delete_post] = isset($type_obj->cap->delete_posts) && ($type_obj->cap->delete_post != $type_obj->cap->delete_posts);
685
+
686
+ } elseif ('taxonomy' == $item_type && !empty($type_obj->cap->edit_term) && !empty($type_obj->cap->delete_term)) {
687
+ $type_metacaps[$type_obj->cap->edit_term] = true;
688
+ $type_metacaps[$type_obj->cap->delete_term] = true;
689
+ }
690
+ }
691
+ }
692
+
693
+ if ( $display_row ) {
694
+ $row .= '</tr>';
695
+
696
+ // Escaped piecemeal upstream; cannot be late-escaped until upstream UI output logic is reworked
697
+ echo $row;
698
+ }
699
+ }
700
+
701
+ echo '</table>';
702
+ echo '</div>';
703
+
704
+ if ($item_type == 'taxonomy') {
705
+ if ($any_caps) {
706
+ ob_flush();
707
+ } else {
708
+ ob_clean();
709
+ }
710
+ }
711
+
712
+ } // end foreach item type
713
+ }
714
+
715
+ if (empty($caps_manager_postcaps_section)) {
716
+ $caps_manager_postcaps_section = '';
717
+ }
718
+
719
+ do_action('publishpress-caps_manager_postcaps_section', compact('current', 'rcaps', 'pp_metagroup_caps', 'is_administrator', 'default_caps', 'custom_types', 'defined', 'unfiltered', 'pp_metagroup_caps','caps_manager_postcaps_section', 'active_tab_id'));
720
+
721
+ $type_caps = apply_filters('publishpress_caps_manager_typecaps', $type_caps);
722
+
723
+ // clicking on post type name toggles corresponding checkbox selections
724
+ // caps: other
725
+
726
+ $tab_id = "cme-cap-type-tables-other";
727
+ $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
728
+ ?>
729
+ <div id="<?php echo esc_attr($tab_id);?>" style="display:<?php echo esc_attr($div_display);?>">
730
+ <?php
731
+
732
+ echo '<h3>' . esc_html__( 'WordPress Core Capabilities', 'capsman-enhanced' ) . '</h3>';
733
+
734
+ echo '<div class="ppc-filter-wrapper">';
735
+ echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capsman-enhanced') . '">';
736
+ echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capsman-enhanced') . '</button>';
737
+ echo '</div>';
738
+ echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
739
+
740
+ echo '<table class="widefat fixed striped form-table cme-checklist">';
741
+
742
+ $centinel_ = true;
743
+ $checks_per_row = get_option( 'cme_form-rows', 1 );
744
+ $i = 0; $first_row = true;
745
+
746
+ ?>
747
+ <tr class="cme-bulk-select">
748
+ <td colspan="<?php echo (int) $checks_per_row;?>">
749
+ <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
750
+ <span style="float:right">
751
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
752
+ </span>
753
+ </td>
754
+ </tr>
755
+
756
+ <?php
757
+ $core_caps = _cme_core_caps();
758
+ foreach( array_keys($core_caps) as $cap_name ) {
759
+ $cap_name = sanitize_key($cap_name);
760
+
761
+ if ( ! $is_administrator && ! current_user_can($cap_name) )
762
+ continue;
763
+
764
+ // Output first <tr>
765
+ if ( $centinel_ == true ) {
766
+ echo '<tr class="' . esc_attr($cap_name) . '">';
767
+ $centinel_ = false;
768
+ }
769
+
770
+ if ( $i == $checks_per_row ) {
771
+ echo '</tr><tr class="' . esc_attr($cap_name) . '">';
772
+ $i = 0;
773
+ }
774
+
775
+ if ( ! isset( $rcaps[$cap_name] ) )
776
+ $class = 'cap-no';
777
+ else
778
+ $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
779
+
780
+ if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
781
+ $class .= ' cap-metagroup';
782
+ $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
783
+ } else {
784
+ $title_text = $cap_name;
785
+ }
786
+
787
+ $disabled = '';
788
+ $checked = checked(1, ! empty($rcaps[$cap_name]), false );
789
+ $lock_capability = false;
790
+ $cap_title = $title_text;
791
+
792
+ if ( 'read' == $cap_name ) {
793
+ if ( ! empty( $block_read_removal ) ) {
794
+ // prevent the read capability from being removed from a core role, but don't force it to be added
795
+ if ( $checked || apply_filters( 'pp_caps_force_capability_storage', false, 'read', $default ) ) {
796
+ if ( apply_filters( 'pp_caps_lock_capability', true, 'read', $default ) ) {
797
+ $lock_capability = true;
798
+ $class .= ' cap-locked';
799
+ $disabled = ' disabled ';
800
+ if ( 'administrator' != $this->current ) {
801
+ $cap_title = __('Lockout Prevention: To remove read capability, first remove WordPress admin / editing capabilities, or add "dashboard_lockout_ok" capability', 'capsman-enhanced' );
802
+ }
803
+ }
804
+ }
805
+ }
806
+ }
807
+
808
+ ?>
809
+ <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($cap_title);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
810
+ <span>
811
+ <?php
812
+ echo esc_html(str_replace( '_', ' ', $cap_name));
813
+ ?>
814
+ </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
815
+ <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
816
+ <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
817
+ <?php endif; ?>
818
+ </td>
819
+
820
+ <?php
821
+
822
+ if ( $lock_capability ) {
823
+ echo '<input type="hidden" name="caps[' . esc_attr($cap_name) . ']" value="1" />';
824
+ }
825
+
826
+ ++$i;
827
+ }
828
+
829
+ if ( $i == $checks_per_row ) {
830
+ echo '</tr>';
831
+ $i = 0;
832
+ } elseif ( ! $first_row ) {
833
+ // Now close a wellformed table
834
+ for ( $i; $i < $checks_per_row; $i++ ){
835
+ echo '<td>&nbsp;</td>';
836
+ }
837
+ echo '</tr>';
838
+ }
839
+ ?>
840
+
841
+ <tr class="cme-bulk-select">
842
+ <td colspan="<?php echo (int) $checks_per_row;?>">
843
+ <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
844
+ <span style="float:right">
845
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
846
+ </span>
847
+ </td>
848
+ </tr>
849
+
850
+ </table>
851
+ </div>
852
+
853
+ <?php
854
+ $all_capabilities = apply_filters( 'capsman_get_capabilities', array_keys( $this->capabilities ), $this->ID );
855
+ $all_capabilities = apply_filters( 'members_get_capabilities', $all_capabilities );
856
+
857
+ // caps: plugins
858
+ $plugin_caps = apply_filters('cme_plugin_capabilities', $plugin_caps);
859
+
860
+ foreach($plugin_caps as $plugin_title => $__plugin_caps) {
861
+ $plugin_title = esc_html($plugin_title);
862
+
863
+ $_plugin_caps = array_fill_keys($__plugin_caps, true);
864
+
865
+ $tab_id = 'cme-cap-type-tables-' . esc_attr(str_replace( ' ', '-', strtolower($plugin_title)));
866
+ $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
867
+
868
+ echo '<div id="' . esc_attr($tab_id) . '" style="display:' . esc_attr($div_display) . '">';
869
+
870
+ echo '<h3 class="cme-cap-section">' . sprintf(esc_html__( 'Plugin Capabilities &ndash; %s', 'capsman-enhanced' ), esc_html(str_replace('_', ' ', $plugin_title))) . '</h3>';
871
+
872
+ echo '<div class="ppc-filter-wrapper">';
873
+ echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capsman-enhanced') . '">';
874
+ echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capsman-enhanced') . '</button>';
875
+ echo '</div>';
876
+ echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
877
+
878
+ echo '<table class="widefat fixed striped form-table cme-checklist">';
879
+
880
+ $centinel_ = true;
881
+ $checks_per_row = get_option( 'cme_form-rows', 1 );
882
+ $i = 0; $first_row = true;
883
+
884
+ ?>
885
+ <tr class="cme-bulk-select">
886
+ <td colspan="<?php echo (int) $checks_per_row;?>">
887
+ <input type="checkbox" class="cme-check-all" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
888
+ <span style="float:right">
889
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
890
+ </span>
891
+ </td>
892
+ </tr>
893
+ <?php
894
+ foreach( array_keys($_plugin_caps) as $cap_name ) {
895
+ $cap_name = sanitize_key($cap_name);
896
+
897
+ if ( isset( $type_caps[$cap_name] ) || isset($core_caps[$cap_name]) || isset($type_metacaps[$cap_name]) ) {
898
+ continue;
899
+ }
900
+
901
+ if ( ! $is_administrator && ! current_user_can($cap_name) )
902
+ continue;
903
+
904
+ // Output first <tr>
905
+ if ( $centinel_ == true ) {
906
+ echo '<tr class="' . esc_attr($cap_name) . '">';
907
+ $centinel_ = false;
908
+ }
909
+
910
+ if ( $i == $checks_per_row ) {
911
+ echo '</tr><tr class="' . esc_attr($cap_name) . '">';
912
+ $i = 0;
913
+ }
914
+
915
+ if ( ! isset( $rcaps[$cap_name] ) )
916
+ $class = 'cap-no';
917
+ else
918
+ $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
919
+
920
+ if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
921
+ $class .= ' cap-metagroup';
922
+ $title_text = sprintf( __( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
923
+ } else {
924
+ $title_text = $cap_name;
925
+ }
926
+
927
+ $disabled = '';
928
+ $checked = checked(1, ! empty($rcaps[$cap_name]), false );
929
+ $cap_title = $title_text;
930
+ ?>
931
+ <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($cap_title);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
932
+ <span>
933
+ <?php
934
+ echo esc_html(str_replace( '_', ' ', $cap_name));
935
+ ?>
936
+ </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
937
+ <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
938
+ <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
939
+ <?php endif; ?>
940
+ </td>
941
+
942
+ <?php
943
+ ++$i;
944
+ }
945
+
946
+ if ( $i == $checks_per_row ) {
947
+ echo '</tr>';
948
+ $i = 0;
949
+ } elseif ( ! $first_row ) {
950
+ // Now close a wellformed table
951
+ for ( $i; $i < $checks_per_row; $i++ ){
952
+ echo '<td>&nbsp;</td>';
953
+ }
954
+ echo '</tr>';
955
+ }
956
+ ?>
957
+
958
+ <tr class="cme-bulk-select">
959
+ <td colspan="<?php echo (int) $checks_per_row;?>">
960
+ <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
961
+ <span style="float:right">
962
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
963
+ </span>
964
+ </td>
965
+ </tr>
966
+
967
+ </table>
968
+ </div>
969
+ <?php
970
+ }
971
+
972
+ // caps: invalid
973
+ if (array_intersect(array_keys(array_filter($type_metacaps)), $all_capabilities) && array_intersect_key($type_metacaps, array_filter($rcaps))) {
974
+ $tab_id = "cme-cap-type-tables-invalid";
975
+ $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
976
+
977
+ echo '<div id="' . esc_attr($tab_id) . '" style="display:' . esc_attr($div_display) . '">';
978
+ echo '<h3 class="cme-cap-section">' . esc_html__( 'Invalid Capabilities', 'capsman-enhanced' ) . '</h3>';
979
+ ?>
980
+
981
+ <script type="text/javascript">
982
+ /* <![CDATA[ */
983
+ jQuery(document).ready( function($) {
984
+ $('#cme_tab_invalid_caps').show();
985
+ });
986
+ /* ]]> */
987
+ </script>
988
+
989
+ <div>
990
+ <span class="cme-subtext">
991
+ <?php esc_html_e('The following entries have no effect. Please assign desired capabilities in the Read / Edit / Delete grid above.', 'capsman-enhanced');?>
992
+ </span>
993
+ </div>
994
+
995
+ <table class="widefat fixed striped form-table cme-checklist">
996
+ <tr>
997
+ <?php
998
+ $i = 0; $first_row = true;
999
+
1000
+ foreach( $all_capabilities as $cap_name ) {
1001
+ if ( ! isset($this->capabilities[$cap_name]) )
1002
+ $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name );
1003
+ }
1004
+
1005
+ uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys );
1006
+
1007
+ foreach ( $this->capabilities as $cap_name => $cap ) :
1008
+ $cap_name = sanitize_key($cap_name);
1009
+
1010
+ if (!isset($type_metacaps[$cap_name]) || empty($rcaps[$cap_name])) {
1011
+ continue;
1012
+ }
1013
+
1014
+ if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) {
1015
+ continue;
1016
+ }
1017
+
1018
+ if ( $i == $checks_per_row ) {
1019
+ echo '</tr><tr>';
1020
+ $i = 0; $first_row = false;
1021
+ }
1022
+
1023
+ if ( ! isset( $rcaps[$cap_name] ) )
1024
+ $class = 'cap-no';
1025
+ else
1026
+ $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
1027
+
1028
+ $title_text = $cap_name;
1029
+
1030
+ $disabled = '';
1031
+ $checked = checked(1, ! empty($rcaps[$cap_name]), false );
1032
+ ?>
1033
+ <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($title_text);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . esc_attr($disabled);?> />
1034
+ <span>
1035
+ <?php
1036
+ echo esc_html(str_replace( '_', ' ', $cap ));
1037
+ ?>
1038
+ </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
1039
+ <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
1040
+ <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
1041
+ <?php endif; ?>
1042
+ </td>
1043
+ <?php
1044
+ $i++;
1045
+ endforeach;
1046
+
1047
+ if ( ! empty($lock_manage_caps_capability) ) {
1048
+ echo '<input type="hidden" name="caps[manage_capabilities]" value="1" />';
1049
+ }
1050
+
1051
+ if ( $i == $checks_per_row ) {
1052
+ echo '</tr><tr>';
1053
+ $i = 0;
1054
+ } else {
1055
+ if ( ! $first_row ) {
1056
+ // Now close a wellformed table
1057
+ for ( $i; $i < $checks_per_row; $i++ ){
1058
+ echo '<td>&nbsp;</td>';
1059
+ }
1060
+ echo '</tr>';
1061
+ }
1062
+ }
1063
+ ?>
1064
+
1065
+ </table>
1066
+ </div>
1067
+ <?php
1068
+ } // endif any invalid caps
1069
+
1070
+ $tab_id = "cme-cap-type-tables-additional";
1071
+ $div_display = ($tab_id == $active_tab_id) ? 'block' : 'none';
1072
+ ?>
1073
+ <div id="<?php echo esc_attr($tab_id);?>" style="display:<?php echo esc_attr($div_display);?>">
1074
+ <?php
1075
+ // caps: additional
1076
+ echo '<h3 class="cme-cap-section">' . esc_html__( 'Additional Capabilities', 'capsman-enhanced' ) . '</h3>';
1077
+
1078
+ echo '<div class="ppc-filter-wrapper">';
1079
+ echo '<input type="text" class="regular-text ppc-filter-text" placeholder="' . esc_attr__('Filter by capability', 'capsman-enhanced') . '">';
1080
+ echo ' <button class="button secondary-button ppc-filter-text-reset" type="button">' . esc_html__('Clear', 'capsman-enhanced') . '</button>';
1081
+ echo '</div>';
1082
+ echo '<div class="ppc-filter-no-results" style="display:none;">' . esc_html__( 'No results found. Please try again with a different word.', 'capsman-enhanced' ) . '</div>';
1083
+ ?>
1084
+ <table class="widefat fixed striped form-table cme-checklist">
1085
+
1086
+ <tr class="cme-bulk-select">
1087
+ <td colspan="<?php echo (int) $checks_per_row;?>">
1088
+ <input type="checkbox" class="cme-check-all" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
1089
+ <span style="float:right">
1090
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
1091
+ </span>
1092
+ </td>
1093
+ </tr>
1094
+
1095
+ <?php
1096
+ $centinel_ = true;
1097
+ $i = 0; $first_row = true;
1098
+
1099
+ foreach( $all_capabilities as $cap_name ) {
1100
+ if ( ! isset($this->capabilities[$cap_name]) )
1101
+ $this->capabilities[$cap_name] = str_replace( '_', ' ', $cap_name );
1102
+ }
1103
+
1104
+ uasort( $this->capabilities, 'strnatcasecmp' ); // sort by array values, but maintain keys );
1105
+
1106
+ $additional_caps = apply_filters('publishpress_caps_manage_additional_caps', $this->capabilities);
1107
+
1108
+ foreach ($additional_caps as $cap_name => $cap) :
1109
+ $cap_name = sanitize_key($cap_name);
1110
+
1111
+
1112
+ if ((isset($type_caps[$cap_name]) && !isset($type_metacaps[$cap_name]))
1113
+ || isset($core_caps[$cap_name])
1114
+ || (isset($type_metacaps[$cap_name]) && !empty($rcaps[$cap_name])) ) {
1115
+ continue;
1116
+ }
1117
+
1118
+ if (!isset($type_metacaps[$cap_name]) || !empty($rcaps[$cap_name])) {
1119
+ foreach(array_keys($plugin_caps) as $plugin_title) {
1120
+ if ( in_array( $cap_name, $plugin_caps[$plugin_title]) ) {
1121
+ continue 2;
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ if ( ! $is_administrator && empty( $current_user->allcaps[$cap_name] ) ) {
1127
+ continue;
1128
+ }
1129
+
1130
+ // Levels are not shown.
1131
+ if ( preg_match( '/^level_(10|[0-9])$/i', $cap_name ) ) {
1132
+ continue;
1133
+ }
1134
+
1135
+ // Output first <tr>
1136
+ if ( $centinel_ == true ) {
1137
+ echo '<tr class="' . esc_attr($cap_name) . '">';
1138
+ $centinel_ = false;
1139
+ }
1140
+
1141
+ if ( $i == $checks_per_row ) {
1142
+ echo '</tr><tr class="' . esc_attr($cap_name) . '">';
1143
+ $i = 0; $first_row = false;
1144
+ }
1145
+
1146
+ if ( ! isset( $rcaps[$cap_name] ) )
1147
+ $class = 'cap-no';
1148
+ else
1149
+ $class = ( $rcaps[$cap_name] ) ? 'cap-yes' : 'cap-neg';
1150
+
1151
+ if ( ! empty($pp_metagroup_caps[$cap_name]) ) {
1152
+ $class .= ' cap-metagroup';
1153
+ $title_text = sprintf( esc_html__( '%s: assigned by Permission Group', 'capsman-enhanced' ), $cap_name );
1154
+ } else {
1155
+ $title_text = $cap_name;
1156
+ }
1157
+
1158
+ $disabled = '';
1159
+ $checked = checked(1, ! empty($rcaps[$cap_name]), false );
1160
+
1161
+ if ( 'manage_capabilities' == $cap_name ) {
1162
+ if (!current_user_can('administrator') && (!is_multisite() || !is_super_admin())) {
1163
+ continue;
1164
+ } elseif ( 'administrator' == $default ) {
1165
+ $class .= ' cap-locked';
1166
+ $lock_manage_caps_capability = true;
1167
+ $disabled = ' disabled ';
1168
+ }
1169
+ }
1170
+ ?>
1171
+ <td class="<?php echo esc_attr($class); ?>"><span class="cap-x">X</span><label title="<?php echo esc_attr($title_text);?>"><input type="checkbox" name="caps[<?php echo esc_attr($cap_name); ?>]" autocomplete="off" value="1" <?php echo esc_attr($checked) . ' ' . esc_attr($disabled);?> />
1172
+ <span>
1173
+ <?php
1174
+ echo esc_html(str_replace( '_', ' ', $cap ));
1175
+ ?>
1176
+ </span></label><a href="#" class="neg-cap">&nbsp;x&nbsp;</a>
1177
+ <?php if ( false !== strpos( $class, 'cap-neg' ) ) :?>
1178
+ <input type="hidden" class="cme-negation-input" name="caps[<?php echo esc_attr($cap_name); ?>]" value="" />
1179
+ <?php endif; ?>
1180
+ </td>
1181
+ <?php
1182
+ $i++;
1183
+ endforeach;
1184
+
1185
+ if ( ! empty($lock_manage_caps_capability) ) {
1186
+ echo '<input type="hidden" name="caps[manage_capabilities]" value="1" />';
1187
+ }
1188
+
1189
+ if ( $i == $checks_per_row ) {
1190
+ echo '</tr><tr>';
1191
+ $i = 0;
1192
+ } else {
1193
+ if ( ! $first_row ) {
1194
+ // Now close a wellformed table
1195
+ for ( $i; $i < $checks_per_row; $i++ ){
1196
+ echo '<td>&nbsp;</td>';
1197
+ }
1198
+ echo '</tr>';
1199
+ }
1200
+ }
1201
+ ?>
1202
+
1203
+ <tr class="cme-bulk-select">
1204
+ <td colspan="<?php echo (int) $checks_per_row;?>">
1205
+ <input type="checkbox" class="cme-check-all" autocomplete="off" title="<?php esc_attr_e('check / uncheck all', 'capsman-enhanced');?>"> <span><?php _e('Capability Name', 'capsman-enhanced');?></span>
1206
+ <span style="float:right">
1207
+ &nbsp;&nbsp;<a class="cme-neg-all" href="#" title="<?php esc_attr_e('negate all (storing as disabled capabilities)', 'capsman-enhanced');?>">X</a> <a class="cme-switch-all" href="#" title="<?php esc_attr_e('negate none (add/remove all capabilities normally)', 'capsman-enhanced');?>">X</a>
1208
+ </span>
1209
+ </td>
1210
+ </tr>
1211
+
1212
+ </table>
1213
+ </div>
1214
+ </div>
1215
+ </div>
1216
+
1217
+
1218
+ <script type="text/javascript">
1219
+ /* <![CDATA[ */
1220
+ jQuery(document).ready( function($) {
1221
+ $('a[href="#pp-more"]').click( function() {
1222
+ $('#pp_features').show();
1223
+ return false;
1224
+ });
1225
+ $('a[href="#pp-hide"]').click( function() {
1226
+ $('#pp_features').hide();
1227
+ return false;
1228
+ });
1229
+ });
1230
+ /* ]]> */
1231
+ </script>
1232
+
1233
+ <?php /* play.png icon by Pavel: http://kde-look.org/usermanager/search.php?username=InFeRnODeMoN */ ?>
1234
+
1235
+ <div id="pp_features" style="display:none"><div class="pp-logo"><a href="https://publishpress.com/presspermit/"><img src="<?php echo esc_url_raw($img_url);?>pp-logo.png" alt="<?php esc_attr_e('PublishPress Permissions', 'capsman-enhanced');?>" /></a></div><div class="features-wrap"><ul class="pp-features">
1236
+ <li>
1237
+ <?php esc_html_e( "Automatically define type-specific capabilities for your custom post types and taxonomies", 'capsman-enhanced' );?>
1238
+ <a href="https://presspermit.com/tutorial/regulate-post-type-access" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1239
+
1240
+ <li>
1241
+ <?php esc_html_e( "Assign standard WP roles supplementally for a specific post type", 'capsman-enhanced' );?>
1242
+ <a href="https://presspermit.com/tutorial/regulate-post-type-access" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1243
+
1244
+ <li>
1245
+ <?php esc_html_e( "Assign custom WP roles supplementally for a specific post type <em>(Pro)</em>", 'capsman-enhanced' );?>
1246
+ </li>
1247
+
1248
+ <li>
1249
+ <?php esc_html_e( "Customize reading permissions per-category or per-post", 'capsman-enhanced' );?>
1250
+ <a href="https://presspermit.com/tutorial/category-exceptions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1251
+
1252
+ <li>
1253
+ <?php esc_html_e( "Customize editing permissions per-category or per-post <em>(Pro)</em>", 'capsman-enhanced' );?>
1254
+ <a href="https://presspermit.com/tutorial/page-editing-exceptions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1255
+
1256
+ <li>
1257
+ <?php esc_html_e( "Custom Post Visibility statuses, fully implemented throughout wp-admin <em>(Pro)</em>", 'capsman-enhanced' );?>
1258
+ <a href="https://presspermit.com/tutorial/custom-post-visibility" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1259
+
1260
+ <li>
1261
+ <?php esc_html_e( "Custom Moderation statuses for access-controlled, multi-step publishing workflow <em>(Pro)</em>", 'capsman-enhanced' );?>
1262
+ <a href="https://presspermit.com/tutorial/multi-step-moderation" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1263
+
1264
+ <li>
1265
+ <?php esc_html_e( "Regulate permissions for Edit Flow post statuses <em>(Pro)</em>", 'capsman-enhanced' );?>
1266
+ <a href="https://presspermit.com/tutorial/edit-flow-integration" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1267
+
1268
+ <li>
1269
+ <?php esc_html_e( "Customize the moderated editing of published content with Revisionary or Post Forking <em>(Pro)</em>", 'capsman-enhanced' );?>
1270
+ <a href="https://presspermit.com/tutorial/published-content-revision" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1271
+
1272
+ <li>
1273
+ <?php esc_html_e( "Grant Spectator, Participant or Moderator access to specific bbPress forums <em>(Pro)</em>", 'capsman-enhanced' );?>
1274
+ </li>
1275
+
1276
+ <li>
1277
+ <?php esc_html_e( "Grant supplemental content permissions to a BuddyPress group <em>(Pro)</em>", 'capsman-enhanced' );?>
1278
+ <a href="https://presspermit.com/tutorial/buddypress-content-permissions" target="_blank"><img class="cme-play" alt="*" src="<?php echo esc_url_raw($img_url);?>play.png" /></a></li>
1279
+
1280
+ <li>
1281
+ <?php esc_html_e( "WPML integration to mirror permissions to translations <em>(Pro)</em>", 'capsman-enhanced' );?>
1282
+ </li>
1283
+
1284
+ <li>
1285
+ <?php esc_html_e( "Member support forum", 'capsman-enhanced' );?>
1286
+ </li>
1287
+
1288
+ </ul></div>
1289
+
1290
+ <?php
1291
+ echo '<div>';
1292
+ printf( esc_html__('%1$sgrab%2$s %3$s', 'capsman-enhanced'), '<strong>', '</strong>', '<span class="plugins update-message"><a href="' . esc_url_raw(cme_plugin_info_url('press-permit-core')) . '" class="thickbox" title="' . sprintf( esc_attr__('%s (free install)', 'capsman-enhanced'), 'Permissions Pro' ) . '">Permissions Pro</a></span>' );
1293
+ echo '&nbsp;&nbsp;&bull;&nbsp;&nbsp;';
1294
+ printf( esc_html__('%1$sbuy%2$s %3$s', 'capsman-enhanced'), '<strong>', '</strong>', '<a href="https://publishpress.com/presspermit/" target="_blank" title="' . sprintf( esc_attr__('%s info/purchase', 'capsman-enhanced'), 'Permissions Pro' ) . '">Permissions&nbsp;Pro</a>' );
1295
+ echo '&nbsp;&nbsp;&bull;&nbsp;&nbsp;';
1296
+ echo '<a href="#pp-hide">hide</a>';
1297
+ echo '</div></div>';
1298
+
1299
+ ///
1300
+ ?>
1301
+ <script type="text/javascript">
1302
+ /* <![CDATA[ */
1303
+ jQuery(document).ready( function($) {
1304
+ $('a[href="#toggle_type_caps"]').click( function() {
1305
+ var chks = $(this).closest('tr').find('input');
1306
+ var set_checked = ! $(chks).first().is(':checked');
1307
+
1308
+ $(chks).each(function(i,e) {
1309
+ $('input[name="' + $(this).attr('name') + '"]').prop('checked', set_checked);
1310
+ });
1311
+
1312
+ return false;
1313
+ });
1314
+
1315
+ $('input[name^="caps["]').click(function() {
1316
+ $('input[name="' + $(this).attr('name') + '"]').prop('checked', $(this).prop('checked'));
1317
+ });
1318
+ });
1319
+ /* ]]> */
1320
+ </script>
1321
+
1322
+ <div style="display:none; float:right;">
1323
+ <?php
1324
+ $level = ak_caps2level($rcaps);
1325
+ ?>
1326
+ <span title="<?php esc_attr_e('Role level is mostly deprecated. However, it still determines eligibility for Post Author assignment and limits the application of user editing capabilities.', 'capsman-enhanced');?>">
1327
+
1328
+ <?php (in_array(get_locale(), ['en_EN', 'en_US'])) ? printf('Role Level:') : esc_html_e('Level:', 'capsman-enhanced');?> <select name="level">
1329
+ <?php for ( $l = $this->max_level; $l >= 0; $l-- ) {?>
1330
+ <option value="<?php echo (int) $l; ?>" style="text-align:right;"<?php selected($level, $l); ?>>&nbsp;<?php echo (int) $l; ?>&nbsp;</option>
1331
+ <?php }
1332
+ ?>
1333
+ </select>
1334
+ </span>
1335
+
1336
+ </div>
1337
+
1338
+ <?php
1339
+ $support_pp_only_roles = defined('PRESSPERMIT_ACTIVE');
1340
+ cme_network_role_ui( $default );
1341
+ ?>
1342
+
1343
+ <p class="submit" style="padding-top:0;">
1344
+ <input type="hidden" name="action" value="update" />
1345
+ <input type="hidden" name="current" value="<?php echo esc_attr($default); ?>" />
1346
+
1347
+ <?php
1348
+ $save_caption = (in_array(sanitize_key(get_locale()), ['en_EN', 'en_US'])) ? 'Save Capabilities' : __('Save Changes', 'capsman-enhanced');
1349
+ ?>
1350
+ <input type="submit" name="SaveRole" value="<?php echo esc_attr($save_caption);?>" class="button-primary" /> &nbsp;
1351
+ </p>
1352
+
1353
+ </div><!-- .pp-column-left -->
1354
+ <div class="pp-column-right capabilities-sidebar">
1355
+ <?php
1356
+ do_action('publishpress-caps_sidebar_top');
1357
+
1358
+ $banners = new PublishPress\WordPressBanners\BannersMain;
1359
+ $banners->pp_display_banner(
1360
+ '',
1361
+ __( 'PublishPress Capabilities is safe to use', 'capsman-enhanced' ),
1362
+ array(
1363
+ __( 'This plugin automatically creates a backup whenever you save changes. You can use these backups to
1364
+ restore an earlier version of your roles and capabilities.', 'capsman-enhanced' )
1365
+ ),
1366
+ admin_url( 'admin.php?page=pp-capabilities-backup' ),
1367
+ __( 'Go to the Backup feature', 'capsman-enhanced' )
1368
+ );
1369
+ ?>
1370
+
1371
+ <dl>
1372
+ <dt><?php esc_html_e('Add Capability', 'capsman-enhanced'); ?></dt>
1373
+ <dd style="text-align:center;">
1374
+ <p><input type="text" name="capability-name" class="regular-text" placeholder="<?php echo 'capability_name';?>" /><br />
1375
+ <input type="submit" name="AddCap" value="<?php esc_attr_e('Add to role', 'capsman-enhanced') ?>" class="button" /></p>
1376
+ </dd>
1377
+ </dl>
1378
+
1379
+ <?php
1380
+ $pp_ui->pp_types_ui( $defined['type'] );
1381
+ $pp_ui->pp_taxonomies_ui( $defined['taxonomy'] );
1382
+
1383
+ do_action('publishpress-caps_sidebar_bottom');
1384
+ ?>
1385
+
1386
+ </div><!-- .pp-column-right -->
1387
+ </div><!-- .pp-columns-wrapper -->
1388
+ </td></tr></table> <!-- .akmin -->
1389
+ </fieldset>
1390
+ </form>
1391
+
1392
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
1393
+ cme_publishpressFooter();
1394
+ }
1395
+ ?>
1396
+ </div>
1397
+
1398
+ <?php
1399
+ function cme_network_role_ui( $default ) {
1400
+ if (!is_multisite() || !is_super_admin() || !is_main_site()) {
1401
+ return false;
1402
+ }
1403
+ ?>
1404
+
1405
+ <div style="float:right;margin-left:10px;margin-right:10px">
1406
+ <?php
1407
+ if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) )
1408
+ $autocreate_roles = array();
1409
+ ?>
1410
+ <div style="margin-bottom: 5px">
1411
+ <label for="cme_autocreate_role" title="<?php esc_attr_e('Create this role definition in new (future) sites', 'capsman-enhanced');?>"><input type="checkbox" name="cme_autocreate_role" id="cme_autocreate_role" autocomplete="off" value="1" <?php echo checked(in_array($default, $autocreate_roles));?>> <?php esc_html_e('include in new sites', 'capsman-enhanced'); ?> </label>
1412
+ </div>
1413
+ <div>
1414
+ <label for="cme_net_sync_role" title="<?php echo esc_attr__('Copy / update this role definition to all sites now', 'capsman-enhanced');?>"><input type="checkbox" name="cme_net_sync_role" id="cme_net_sync_role" autocomplete="off" value="1"> <?php esc_html_e('sync role to all sites now', 'capsman-enhanced'); ?> </label>
1415
+ </div>
1416
+ <div>
1417
+ <label for="cme_net_sync_options" title="<?php echo esc_attr__('Copy option settings to all sites now', 'capsman-enhanced');?>"><input type="checkbox" name="cme_net_sync_options" id="cme_net_sync_options" autocomplete="off" value="1"> <?php esc_html_e('sync options to all sites now', 'capsman-enhanced'); ?> </label>
1418
+ </div>
1419
+ </div>
1420
+ <?php
1421
+ return true;
1422
+ }
1423
+
1424
+ function cme_plugin_info_url( $plugin_slug ) {
1425
+ $_url = "plugin-install.php?tab=plugin-information&plugin=$plugin_slug&TB_iframe=true&width=640&height=678";
1426
+ return ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
1427
+ }
includes/backup-handler.php CHANGED
@@ -1,315 +1,315 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Process update operations from Backup screen
6
- *
7
- */
8
-
9
- class Capsman_BackupHandler
10
- {
11
- var $cm;
12
-
13
- function __construct( $manager_obj ) {
14
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles'))
15
- wp_die( esc_html__( 'You do not have permission to restore roles.', 'capsman-enhanced' ) );
16
-
17
- $this->cm = $manager_obj;
18
- }
19
-
20
- /**
21
- * Processes backups and restores.
22
- *
23
- * @return void
24
- */
25
- function processBackupTool ()
26
- {
27
- global $wpdb;
28
-
29
- if (isset($_POST['save_backup'])) {
30
- check_admin_referer('pp-capabilities-backup');
31
-
32
- $wp_roles = $wpdb->prefix . 'user_roles';
33
- $cm_roles = $this->cm->ID . '_backup';
34
- $cm_roles_initial = $this->cm->ID . '_backup_initial';
35
-
36
- $backup_sections = pp_capabilities_backup_sections();
37
-
38
- if ( ! get_option( $cm_roles_initial ) ) {
39
- if ( $current_backup = get_option( $cm_roles ) ) {
40
- update_option( $cm_roles_initial, $current_backup, false );
41
-
42
- if ( $initial_datestamp = get_option( $this->cm->ID . '_backup_datestamp' ) ) {
43
- update_option($this->cm->ID . '_backup_initial_datestamp', $initial_datestamp, false );
44
- }
45
- }
46
- }
47
-
48
- $active_backup = ['Roles and Capabilities'];
49
-
50
- //role backup
51
- $roles = get_option($wp_roles);
52
- update_option($cm_roles, $roles, false);
53
-
54
- //other backup
55
- foreach($backup_sections as $backup_section){
56
- $section_options = $backup_section['options'];
57
- if(is_array($section_options) && !empty($section_options)){
58
- foreach($section_options as $section_option){
59
- $active_backup[] = $backup_section['label'];
60
- $current_option = get_option($section_option);
61
- update_option($section_option.'_backup', $current_option, false);
62
- }
63
- }
64
- }
65
-
66
- $active_backup = array_unique($active_backup);
67
-
68
- //update last backup
69
- update_option($this->cm->ID . '_last_backup', implode(', ', $active_backup));
70
-
71
- //backup datestamp and response
72
- update_option($this->cm->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
73
- ak_admin_notify(__('New backup saved.', 'capsman-enhanced'));
74
-
75
- }
76
-
77
- if (isset($_POST['restore_backup']) && !empty($_POST['select_restore'])) {
78
- check_admin_referer('pp-capabilities-backup');
79
-
80
- $wp_roles = $wpdb->prefix . 'user_roles';
81
- $cm_roles = $this->cm->ID . '_backup';
82
- $cm_roles_initial = $this->cm->ID . '_backup_initial';
83
-
84
- $backup_sections = pp_capabilities_backup_sections();
85
-
86
- switch ($_POST['select_restore']) {
87
- case 'restore_initial':
88
- if ($roles = get_option($cm_roles_initial)) {
89
- update_option($wp_roles, $roles);
90
- ak_admin_notify(__('Roles and Capabilities restored from initial backup.', 'capsman-enhanced'));
91
- } else {
92
- ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
93
- }
94
- break;
95
-
96
- case 'restore':
97
- if ($roles = get_option($cm_roles)) {
98
-
99
- $restored_backup = ['Roles and Capabilities'];
100
-
101
- //restore role backup
102
- update_option($wp_roles, $roles);
103
-
104
- //restore other backup
105
- foreach($backup_sections as $backup_section){
106
- $section_options = $backup_section['options'];
107
- if(is_array($section_options) && !empty($section_options)){
108
- foreach($section_options as $section_option){
109
- $backup_option = get_option($section_option.'_backup');
110
- if ($backup_option) {
111
- $restored_backup[] = $backup_section['label'];
112
- update_option($section_option, $backup_option);
113
- }
114
- }
115
- }
116
- }
117
-
118
- $restored_backup = array_unique($restored_backup);
119
- ak_admin_notify(sprintf(__('%s restored from last backup.', 'capsman-enhanced'), implode(', ', $restored_backup)));
120
- } else {
121
- ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
122
- }
123
- break;
124
-
125
- default:
126
- if ($roles = get_option(sanitize_key($_POST['select_restore']))) {
127
- update_option($wp_roles, $roles);
128
- ak_admin_notify(__('Roles and Capabilities restored from selected auto-backup.', 'capsman-enhanced'));
129
- } else {
130
- ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
131
- }
132
- }
133
- }
134
-
135
- if (isset($_POST['import_backup'])) {
136
-
137
- check_admin_referer('pp-capabilities-backup');
138
-
139
- if (empty($_FILES['import_file']['tmp_name']) || empty($_FILES['import_file']['name'])) {
140
- ak_admin_error(__( 'Please upload a file to import', 'capsman-enhanced'));
141
- return;
142
- }
143
-
144
- if (pathinfo(sanitize_text_field($_FILES['import_file']['name']), PATHINFO_EXTENSION) !== 'json') {
145
- ak_admin_error(__( 'Please upload a valid .json file', 'capsman-enhanced'));
146
- return;
147
- }
148
-
149
- // Make sure WordPress upload support is loaded.
150
- if ( ! function_exists( 'wp_handle_upload' ) ) {
151
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
152
- }
153
-
154
- // Setup internal vars.
155
- $overrides = array( 'test_form' => false, 'test_type' => false, 'mimes' => array('json' => 'application/json') );
156
- $file = wp_handle_upload( $_FILES['import_file'], $overrides );
157
-
158
- // Make sure we have an uploaded file.
159
- if (isset($file['error'])) {
160
- ak_admin_error($file['error']);
161
- return;
162
- }
163
-
164
- if ( ! file_exists( $file['file'] ) ) {
165
- ak_admin_error(__( 'Error importing settings! Please try again.', 'capsman-enhanced'));
166
- return;
167
- }
168
-
169
- // Get the upload data.
170
- $raw = file_get_contents( $file['file'] );
171
- $data = @unserialize( $raw );
172
-
173
- // Remove the uploaded file.
174
- unlink( $file['file'] );
175
-
176
- // Data checks.
177
- if ( 'array' != gettype( $data ) ) {
178
- ak_admin_error(__( 'Error importing settings! Please check that you uploaded a valid json file.', 'capsman-enhanced'));
179
- return;
180
- }
181
-
182
- $backup_sections = pp_capabilities_backup_sections();
183
- $restored_backup = [];
184
-
185
- foreach ( $data as $option_key => $option_value ) {
186
- if($option_key === 'user_roles'){
187
- $restored_backup[] = 'Roles and Capabilities';
188
- $section_data = $this->santize_import_role($option_value);
189
- update_option($wpdb->prefix . 'user_roles', $section_data);
190
- }else{
191
- $restored_backup[] = $this->get_import_option_section($option_key, $backup_sections);
192
- $section_data = $this->santize_import_data($option_value);
193
- update_option($option_key, $section_data);
194
- }
195
- }
196
-
197
- $restored_backup = array_unique($restored_backup);
198
-
199
- ak_admin_notify(sprintf(__('%s successfully imported from uploaded data.', 'capsman-enhanced'), implode(', ', $restored_backup)));
200
-
201
- }
202
- }
203
-
204
- /**
205
- * Sanitize role data before import.
206
- *
207
- * @return array
208
- */
209
- function get_import_option_section($option_key, $backup_sections)
210
- {
211
- $option_section = '';
212
-
213
- foreach($backup_sections as $backup_section){
214
- $section_options = $backup_section['options'];
215
- if(is_array($section_options) && in_array($option_key, $section_options)){
216
- $option_section= $backup_section['label'];
217
- }
218
- }
219
-
220
- return $option_section;
221
- }
222
-
223
- /**
224
- * Sanitize role data before import.
225
- *
226
- * @return array
227
- */
228
- function santize_import_role($role){
229
-
230
- $sanitized_role = [];
231
-
232
- foreach($role as $role_key => $role_data){
233
- $role_key = sanitize_key($role_key);
234
- $role_name = sanitize_text_field($role_data['name']);
235
- $capabilities = $role_data['capabilities'];
236
- $role_capabilities = array_combine(
237
- array_map('sanitize_key', array_keys($capabilities)),
238
- array_map('sanitize_text_field', array_values($capabilities))
239
- );
240
-
241
- //return sanitized data
242
- $sanitized_role[$role_key] = ['name' => $role_name, 'capabilities' => $role_capabilities];
243
- }
244
-
245
- return $sanitized_role;
246
- }
247
-
248
- /**
249
- * Sanitize other data before import.
250
- *
251
- * @return mixed
252
- */
253
- function santize_import_data($data){
254
-
255
- $sanitized_data = [];
256
-
257
- if (is_array($data)) {
258
- foreach ($data as $data_key => $data_content) {
259
- $new_key = sanitize_key($data_key);
260
- $new_content = is_array($data_content) ? array_map('sanitize_text_field', $data_content) : sanitize_text_field($data_content);
261
- //return sanitized data
262
- $sanitized_data[$new_key] = $new_content;
263
- }
264
- }else{
265
- $sanitized_data = sanitize_text_field($data);
266
- }
267
-
268
- return $sanitized_data;
269
- }
270
-
271
- /**
272
- * Resets roles to WordPress defaults.
273
- *
274
- * @return void
275
- */
276
- function backupToolReset ()
277
- {
278
- check_admin_referer('capsman-reset-defaults');
279
-
280
- require_once(ABSPATH . 'wp-admin/includes/schema.php');
281
-
282
- if ( ! function_exists('populate_roles') ) {
283
- ak_admin_error(__('Needed function to create default roles not found!', 'capsman-enhanced'));
284
- return;
285
- }
286
-
287
- $roles = array_keys( ak_get_roles(true) );
288
-
289
- foreach ( $roles as $role) {
290
- remove_role($role);
291
- }
292
-
293
- populate_roles();
294
- $this->cm->setAdminCapability();
295
-
296
- $msg = esc_html__('Roles and Capabilities reset to WordPress defaults', 'capsman-enhanced');
297
-
298
- if ( function_exists( 'pp_populate_roles' ) ) {
299
- pp_populate_roles();
300
- } else {
301
- // force PP to repopulate roles
302
- $pp_ver = get_option( 'pp_c_version', true );
303
- if ( $pp_ver && is_array($pp_ver) ) {
304
- $pp_ver['version'] = ( preg_match( "/dev|alpha|beta|rc/i", $pp_ver['version'] ) ) ? '0.1-beta' : 0.1;
305
- } else {
306
- $pp_ver = array( 'version' => '0.1', 'db_version' => '1.0' );
307
- }
308
-
309
- update_option( 'pp_c_version', $pp_ver );
310
- delete_option( 'ppperm_added_role_caps_10beta' );
311
- }
312
-
313
- ak_admin_notify($msg);
314
- }
315
- }
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Process update operations from Backup screen
6
+ *
7
+ */
8
+
9
+ class Capsman_BackupHandler
10
+ {
11
+ var $cm;
12
+
13
+ function __construct( $manager_obj ) {
14
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles'))
15
+ wp_die( esc_html__( 'You do not have permission to restore roles.', 'capsman-enhanced' ) );
16
+
17
+ $this->cm = $manager_obj;
18
+ }
19
+
20
+ /**
21
+ * Processes backups and restores.
22
+ *
23
+ * @return void
24
+ */
25
+ function processBackupTool ()
26
+ {
27
+ global $wpdb;
28
+
29
+ if (isset($_POST['save_backup'])) {
30
+ check_admin_referer('pp-capabilities-backup');
31
+
32
+ $wp_roles = $wpdb->prefix . 'user_roles';
33
+ $cm_roles = $this->cm->ID . '_backup';
34
+ $cm_roles_initial = $this->cm->ID . '_backup_initial';
35
+
36
+ $backup_sections = pp_capabilities_backup_sections();
37
+
38
+ if ( ! get_option( $cm_roles_initial ) ) {
39
+ if ( $current_backup = get_option( $cm_roles ) ) {
40
+ update_option( $cm_roles_initial, $current_backup, false );
41
+
42
+ if ( $initial_datestamp = get_option( $this->cm->ID . '_backup_datestamp' ) ) {
43
+ update_option($this->cm->ID . '_backup_initial_datestamp', $initial_datestamp, false );
44
+ }
45
+ }
46
+ }
47
+
48
+ $active_backup = ['Roles and Capabilities'];
49
+
50
+ //role backup
51
+ $roles = get_option($wp_roles);
52
+ update_option($cm_roles, $roles, false);
53
+
54
+ //other backup
55
+ foreach($backup_sections as $backup_section){
56
+ $section_options = $backup_section['options'];
57
+ if(is_array($section_options) && !empty($section_options)){
58
+ foreach($section_options as $section_option){
59
+ $active_backup[] = $backup_section['label'];
60
+ $current_option = get_option($section_option);
61
+ update_option($section_option.'_backup', $current_option, false);
62
+ }
63
+ }
64
+ }
65
+
66
+ $active_backup = array_unique($active_backup);
67
+
68
+ //update last backup
69
+ update_option($this->cm->ID . '_last_backup', implode(', ', $active_backup));
70
+
71
+ //backup datestamp and response
72
+ update_option($this->cm->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
73
+ ak_admin_notify(__('New backup saved.', 'capsman-enhanced'));
74
+
75
+ }
76
+
77
+ if (isset($_POST['restore_backup']) && !empty($_POST['select_restore'])) {
78
+ check_admin_referer('pp-capabilities-backup');
79
+
80
+ $wp_roles = $wpdb->prefix . 'user_roles';
81
+ $cm_roles = $this->cm->ID . '_backup';
82
+ $cm_roles_initial = $this->cm->ID . '_backup_initial';
83
+
84
+ $backup_sections = pp_capabilities_backup_sections();
85
+
86
+ switch ($_POST['select_restore']) {
87
+ case 'restore_initial':
88
+ if ($roles = get_option($cm_roles_initial)) {
89
+ update_option($wp_roles, $roles);
90
+ ak_admin_notify(__('Roles and Capabilities restored from initial backup.', 'capsman-enhanced'));
91
+ } else {
92
+ ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
93
+ }
94
+ break;
95
+
96
+ case 'restore':
97
+ if ($roles = get_option($cm_roles)) {
98
+
99
+ $restored_backup = ['Roles and Capabilities'];
100
+
101
+ //restore role backup
102
+ update_option($wp_roles, $roles);
103
+
104
+ //restore other backup
105
+ foreach($backup_sections as $backup_section){
106
+ $section_options = $backup_section['options'];
107
+ if(is_array($section_options) && !empty($section_options)){
108
+ foreach($section_options as $section_option){
109
+ $backup_option = get_option($section_option.'_backup');
110
+ if ($backup_option) {
111
+ $restored_backup[] = $backup_section['label'];
112
+ update_option($section_option, $backup_option);
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ $restored_backup = array_unique($restored_backup);
119
+ ak_admin_notify(sprintf(__('%s restored from last backup.', 'capsman-enhanced'), implode(', ', $restored_backup)));
120
+ } else {
121
+ ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
122
+ }
123
+ break;
124
+
125
+ default:
126
+ if ($roles = get_option(sanitize_key($_POST['select_restore']))) {
127
+ update_option($wp_roles, $roles);
128
+ ak_admin_notify(__('Roles and Capabilities restored from selected auto-backup.', 'capsman-enhanced'));
129
+ } else {
130
+ ak_admin_error(__('Restore failed. No backup found.', 'capsman-enhanced'));
131
+ }
132
+ }
133
+ }
134
+
135
+ if (isset($_POST['import_backup'])) {
136
+
137
+ check_admin_referer('pp-capabilities-backup');
138
+
139
+ if (empty($_FILES['import_file']['tmp_name']) || empty($_FILES['import_file']['name'])) {
140
+ ak_admin_error(__( 'Please upload a file to import', 'capsman-enhanced'));
141
+ return;
142
+ }
143
+
144
+ if (pathinfo(sanitize_text_field($_FILES['import_file']['name']), PATHINFO_EXTENSION) !== 'json') {
145
+ ak_admin_error(__( 'Please upload a valid .json file', 'capsman-enhanced'));
146
+ return;
147
+ }
148
+
149
+ // Make sure WordPress upload support is loaded.
150
+ if ( ! function_exists( 'wp_handle_upload' ) ) {
151
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
152
+ }
153
+
154
+ // Setup internal vars.
155
+ $overrides = array( 'test_form' => false, 'test_type' => false, 'mimes' => array('json' => 'application/json') );
156
+ $file = wp_handle_upload( $_FILES['import_file'], $overrides );
157
+
158
+ // Make sure we have an uploaded file.
159
+ if (isset($file['error'])) {
160
+ ak_admin_error($file['error']);
161
+ return;
162
+ }
163
+
164
+ if ( ! file_exists( $file['file'] ) ) {
165
+ ak_admin_error(__( 'Error importing settings! Please try again.', 'capsman-enhanced'));
166
+ return;
167
+ }
168
+
169
+ // Get the upload data.
170
+ $raw = file_get_contents( $file['file'] );
171
+ $data = maybe_unserialize( $raw );
172
+
173
+ // Remove the uploaded file.
174
+ wp_delete_file( $file['file'] );
175
+
176
+ // Data checks.
177
+ if ( 'array' != gettype( $data ) ) {
178
+ ak_admin_error(__( 'Error importing settings! Please check that you uploaded a valid json file.', 'capsman-enhanced'));
179
+ return;
180
+ }
181
+
182
+ $backup_sections = pp_capabilities_backup_sections();
183
+ $restored_backup = [];
184
+
185
+ foreach ( $data as $option_key => $option_value ) {
186
+ if($option_key === 'user_roles'){
187
+ $restored_backup[] = 'Roles and Capabilities';
188
+ $section_data = $this->santize_import_role($option_value);
189
+ update_option($wpdb->prefix . 'user_roles', $section_data);
190
+ }else{
191
+ $restored_backup[] = $this->get_import_option_section($option_key, $backup_sections);
192
+ $section_data = $this->santize_import_data($option_value);
193
+ update_option($option_key, $section_data);
194
+ }
195
+ }
196
+
197
+ $restored_backup = array_unique($restored_backup);
198
+
199
+ ak_admin_notify(sprintf(__('%s successfully imported from uploaded data.', 'capsman-enhanced'), implode(', ', $restored_backup)));
200
+
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Sanitize role data before import.
206
+ *
207
+ * @return array
208
+ */
209
+ function get_import_option_section($option_key, $backup_sections)
210
+ {
211
+ $option_section = '';
212
+
213
+ foreach($backup_sections as $backup_section){
214
+ $section_options = $backup_section['options'];
215
+ if(is_array($section_options) && in_array($option_key, $section_options)){
216
+ $option_section= $backup_section['label'];
217
+ }
218
+ }
219
+
220
+ return $option_section;
221
+ }
222
+
223
+ /**
224
+ * Sanitize role data before import.
225
+ *
226
+ * @return array
227
+ */
228
+ function santize_import_role($role){
229
+
230
+ $sanitized_role = [];
231
+
232
+ foreach($role as $role_key => $role_data){
233
+ $role_key = sanitize_key($role_key);
234
+ $role_name = sanitize_text_field($role_data['name']);
235
+ $capabilities = $role_data['capabilities'];
236
+ $role_capabilities = array_combine(
237
+ array_map('sanitize_key', array_keys($capabilities)),
238
+ array_map('sanitize_text_field', array_values($capabilities))
239
+ );
240
+
241
+ //return sanitized data
242
+ $sanitized_role[$role_key] = ['name' => $role_name, 'capabilities' => $role_capabilities];
243
+ }
244
+
245
+ return $sanitized_role;
246
+ }
247
+
248
+ /**
249
+ * Sanitize other data before import.
250
+ *
251
+ * @return mixed
252
+ */
253
+ function santize_import_data($data){
254
+
255
+ $sanitized_data = [];
256
+
257
+ if (is_array($data)) {
258
+ foreach ($data as $data_key => $data_content) {
259
+ $new_key = sanitize_key($data_key);
260
+ $new_content = is_array($data_content) ? array_map('sanitize_text_field', $data_content) : sanitize_text_field($data_content);
261
+ //return sanitized data
262
+ $sanitized_data[$new_key] = $new_content;
263
+ }
264
+ }else{
265
+ $sanitized_data = sanitize_text_field($data);
266
+ }
267
+
268
+ return $sanitized_data;
269
+ }
270
+
271
+ /**
272
+ * Resets roles to WordPress defaults.
273
+ *
274
+ * @return void
275
+ */
276
+ function backupToolReset ()
277
+ {
278
+ check_admin_referer('capsman-reset-defaults');
279
+
280
+ require_once(ABSPATH . 'wp-admin/includes/schema.php');
281
+
282
+ if ( ! function_exists('populate_roles') ) {
283
+ ak_admin_error(__('Needed function to create default roles not found!', 'capsman-enhanced'));
284
+ return;
285
+ }
286
+
287
+ $roles = array_keys( ak_get_roles(true) );
288
+
289
+ foreach ( $roles as $role) {
290
+ remove_role($role);
291
+ }
292
+
293
+ populate_roles();
294
+ $this->cm->setAdminCapability();
295
+
296
+ $msg = esc_html__('Roles and Capabilities reset to WordPress defaults', 'capsman-enhanced');
297
+
298
+ if ( function_exists( 'pp_populate_roles' ) ) {
299
+ pp_populate_roles();
300
+ } else {
301
+ // force PP to repopulate roles
302
+ $pp_ver = get_option( 'pp_c_version', true );
303
+ if ( $pp_ver && is_array($pp_ver) ) {
304
+ $pp_ver['version'] = ( preg_match( "/dev|alpha|beta|rc/i", $pp_ver['version'] ) ) ? '0.1-beta' : 0.1;
305
+ } else {
306
+ $pp_ver = array( 'version' => '0.1', 'db_version' => '1.0' );
307
+ }
308
+
309
+ update_option( 'pp_c_version', $pp_ver );
310
+ delete_option( 'ppperm_added_role_caps_10beta' );
311
+ }
312
+
313
+ ak_admin_notify($msg);
314
+ }
315
+ }
includes/backup.php CHANGED
@@ -1,451 +1,451 @@
1
- <?php
2
- /**
3
- * Capability Manager Backup Tool.
4
- * Provides backup and restore functionality to Capability Manager.
5
- *
6
- * @version $Rev: 198515 $
7
- * @author Jordi Canals
8
- * @copyright Copyright (C) 2009, 2010 Jordi Canals
9
- * @license GNU General Public License version 2
10
- * @link http://alkivia.org
11
- * @package Alkivia
12
- * @subpackage CapsMan
13
- *
14
- *
15
- * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
- *
17
- * Modifications Copyright 2020, PublishPress <help@publishpress.com>
18
- *
19
- * This program is free software; you can redistribute it and/or
20
- * modify it under the terms of the GNU General Public License
21
- * version 2 as published by the Free Software Foundation.
22
- *
23
- * This program is distributed in the hope that it will be useful,
24
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
- * GNU General Public License for more details.
27
- *
28
- * You should have received a copy of the GNU General Public License
29
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
30
- */
31
-
32
- global $wpdb;
33
-
34
- $auto_backups = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%' ORDER BY option_id DESC");
35
- ?>
36
-
37
- <div class="wrap publishpress-caps-manage publishpress-caps-backup pressshack-admin-wrapper">
38
- <div id="icon-capsman-admin" class="icon32"></div>
39
- <h2><?php esc_html_e('Backup Tool for PublishPress Capabilities', 'capsman-enhanced');?></h2>
40
-
41
-
42
- <form method="post" action="admin.php?page=pp-capabilities-backup" enctype="multipart/form-data">
43
- <?php wp_nonce_field('pp-capabilities-backup'); ?>
44
-
45
- <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
46
- <div class="pp-column-left">
47
- <ul id="publishpress-capability-backup-tabs" class="nav-tab-wrapper">
48
- <li class="nav-tab nav-tab-active"><a href="#ppcb-tab-restore"><?php esc_html_e('Restore', 'capsman-enhanced');?></a></li>
49
- <li class="nav-tab"><a href="#ppcb-tab-backup"><?php esc_html_e('Backup', 'capsman-enhanced');?></a></li>
50
- <li class="nav-tab"><a href="#ppcb-tab-reset"><?php esc_html_e('Reset Roles', 'capsman-enhanced');?></a></li>
51
- <li class="nav-tab"><a href="#ppcb-tab-import-export"><?php esc_html_e('Export / Import', 'capsman-enhanced');?></a></li>
52
- </ul>
53
-
54
- <fieldset>
55
- <table id="akmin">
56
- <tr>
57
- <td class="content">
58
-
59
- <dl id="ppcb-tab-backup" style="display:none;">
60
- <dt><?php esc_html_e('Backup Roles and Capabilities', 'capsman-enhanced'); ?></dt>
61
- <dd>
62
- <p class="description">
63
- <?php
64
- $max_auto_backups = (defined('CME_AUTOBACKUPS')) ? (int) CME_AUTOBACKUPS : 20;
65
- printf(esc_html__('PublishPress Capabilities automatically creates a backup on installation and whenever you save changes. The initial backup and last %d auto-backups are kept.', 'capsman-enhanced'), esc_attr($max_auto_backups));
66
- ?>
67
- </p>
68
-
69
- <p class="description">
70
- <?php esc_html_e('A backup created on this screen replaces any previous manual backups, but is never automatically replaced.', 'capsman-enhanced');?>
71
- </p>
72
-
73
- <div class="pp-caps-backup-button">
74
- <input type="submit" name="save_backup"
75
- value="<?php esc_attr_e('Manual Backup', 'capsman-enhanced') ?>"
76
- class="button-primary"/>
77
- </div>
78
- </dd>
79
-
80
- </dl>
81
-
82
- <?php
83
- $listed_manual_backup = false;
84
- $backup_datestamp = get_option('capsman_backup_datestamp');
85
- $last_caption = ($backup_datestamp) ? sprintf(esc_html__('Last Manual Backup - %s', 'capsman-enhanced'), date('j M Y, g:i a', $backup_datestamp)) : esc_html__('Last Backup', 'capsman-enhanced');
86
- ?>
87
-
88
- <dl id="ppcb-tab-restore">
89
- <dt><?php esc_html_e('Restore Previous Roles and Capabilities', 'capsman-enhanced'); ?></dt>
90
- <dd>
91
- <p class="description">
92
- <?php esc_html_e('PublishPress Capabilities automatically creates a backup on installation and whenever you save changes.', 'capsman-enhanced');?>
93
- </p>
94
-
95
- <p class="description">
96
- <?php esc_html_e('On this screen, you can restore an earlier version of your roles and capabilities.', 'capsman-enhanced');?>
97
- </p>
98
-
99
- <table width='100%' class="form-table">
100
- <tr>
101
- <th scope="row"><?php esc_html_e('Available Backups:', 'capsman-enhanced'); ?></th>
102
- <td>
103
- <div id="cme_select_restore_div">
104
- <ul id="cme_select_restore">
105
- <?php foreach ($auto_backups as $row):
106
- $arr = explode('_', str_replace('cme_backup_auto_', '', $row->option_name));
107
- $arr[1] = str_replace('-', ':', $arr[1]);
108
- $date_caption = implode(' ', $arr);
109
-
110
- if (!$listed_manual_backup && ($backup_datestamp > strtotime($date_caption))) :
111
- $manual_date_caption = date('Y-m-d, g:i a', $backup_datestamp);
112
- $last_backup = get_option('capsman_last_backup');
113
- if(!$last_backup){
114
- $last_backup = __('all roles', 'capsman-enhanced');
115
- }
116
- ?>
117
- <li>
118
- <input type="radio" name="select_restore" value="restore" id="cme_restore_manual">
119
- <label for="cme_restore_manual"><?php printf(esc_html__('Manual backup of %s (%s)', 'capsman-enhanced'), esc_html($last_backup), esc_html($manual_date_caption)); ?></label>
120
- </li>
121
- <?php
122
- $listed_manual_backup = true;
123
- endif;
124
- ?>
125
-
126
- <?php
127
- $date_caption = str_replace(' ', ', ', $date_caption);
128
- $date_caption = str_replace(', am', ' am', $date_caption);
129
- $date_caption = str_replace(', pm', ' pm', $date_caption);
130
- ?>
131
-
132
- <li>
133
- <input type="radio" name="select_restore" value="<?php echo esc_attr($row->option_name);?>" id="<?php echo esc_attr($row->option_name);?>">
134
- <label for="<?php echo esc_attr($row->option_name);?>"><?php printf(esc_html__('Auto-backup of all roles (%s)', 'capsman-enhanced'), esc_html($date_caption)); ?></label>
135
- </li>
136
- <?php endforeach; ?>
137
-
138
- <?php
139
- if ($initial = get_option('capsman_backup_initial')):?>
140
- <li>
141
- <input type="radio" name="select_restore" value="restore_initial" id="cme_restore_initial">
142
- <label for="cme_restore_initial"><?php esc_html_e('Initial backup of all roles', 'capsman-enhanced'); ?></label>
143
- </li>
144
- <?php endif; ?>
145
- <!-- </select> -->
146
- </ul>
147
- </div>
148
-
149
- <div class="cme-restore-button">
150
- <input type="submit" name="restore_backup"
151
- value="<?php esc_attr_e('Restore Selected Roles', 'capsman-enhanced') ?>"
152
- class="button-primary"/>
153
-
154
- <div class="cme-selected-backup-caption">
155
- <span class="cme-selected-backup-caption cme-subtext"></span>
156
- </div>
157
- </div>
158
- </td>
159
-
160
- <td class="cme-backup-info">
161
- <div class="cme_backup_info_changes_only" style="display:none">
162
- <input type="checkbox" class="cme_backup_info_changes_only" autocomplete="off" checked="checked"> <?php esc_html_e('Show changes from current roles only', 'capsman-enhanced');?>
163
- </div>
164
-
165
- <?php
166
- global $wp_roles;
167
-
168
- $backup_datestamp = get_option('capsman_backup_initial_datestamp');
169
- $initial_caption = ($backup_datestamp) ? sprintf(esc_html__('Initial Backup - %s', 'capsman-enhanced'), date('j M Y, g:i a', $backup_datestamp)) : esc_html__('Initial Backup', 'capsman-enhanced');
170
-
171
- $backups = array(
172
- 'capsman_backup_initial' => $initial_caption,
173
- );
174
-
175
- if (empty($capsman_backup)) {
176
- $backups['capsman_backup'] = $last_caption;
177
- }
178
-
179
- foreach ($auto_backups as $row) {
180
- $arr = explode('_', str_replace('cme_backup_auto_', '', $row->option_name));
181
- $arr[1] = str_replace('-', ':', $arr[1]);
182
-
183
- $date_caption = implode(' ', $arr);
184
- $date_caption = str_replace(' ', ', ', $date_caption);
185
- $date_caption = str_replace(', am', ' am', $date_caption);
186
- $date_caption = str_replace(', pm', ' pm', $date_caption);
187
-
188
- $option_name = sanitize_key($row->option_name);
189
- $backups[$option_name] = "Auto-backup from " . $date_caption;
190
- }
191
-
192
- foreach ($backups as $name => $caption) {
193
- if ($backup_data = get_option($name)) :?>
194
- <div id="cme_display_<?php echo esc_attr($name); ?>" style="display:none;"
195
- class="cme-show-backup">
196
- <h3><?php printf(esc_html__("%s (%s roles)", 'capsman-enhanded'), esc_html($caption), count($backup_data)); ?></h3>
197
-
198
- <?php
199
- foreach ($wp_roles->role_objects as $role_name => $role_object) {
200
- if (empty($backup_data[$role_name])) {
201
- $role_caption = $role_object->name;
202
- ?>
203
- <h4><span class="cme-change cme-minus"><?php echo (esc_html(translate_user_role($role_caption)));?></span> <?php esc_html_e('(this role will be removed if you restore backup)', 'capsman-enhanced');?></h4>
204
- <?php
205
- }
206
- }
207
- ?>
208
-
209
- <?php foreach ($backup_data as $role_name => $props) :
210
- if (isset($wp_roles->role_objects[$role_name]->capabilities)) {
211
- $props['capabilities'] = array_merge(
212
- array_fill_keys(array_keys($wp_roles->role_objects[$role_name]->capabilities), 0),
213
- $props['capabilities']
214
- );
215
- }
216
- ?>
217
- <?php if (!isset($props['name'])) continue; ?>
218
- <?php
219
- $level = 0;
220
- for ($i = 10; $i >= 0; $i--) {
221
- if (!empty($props['capabilities']["level_{$i}"])) {
222
- $level = $i;
223
- break;
224
- }
225
- }
226
- ?>
227
- <?php
228
- $role_caption = $props['name'];
229
- $role_class = (empty($wp_roles->role_objects[$role_name])) ? 'cme-change cme-plus' : '';
230
- ?>
231
-
232
- <h4 class="<?php echo esc_attr($role_class);?>"><?php printf(esc_html__('%s (level %s)', 'capsman-enhanced'), esc_html(translate_user_role($role_caption)), esc_html($level)); ?></h4>
233
-
234
- <?php
235
- $items = [];
236
- $any_changes = false;
237
-
238
- ksort($props['capabilities']);
239
- foreach ($props['capabilities'] as $cap_name => $val) :
240
- if (0 === strpos($cap_name, 'level_')) continue;
241
- ?>
242
- <?php
243
- if ($val && (empty($wp_roles->role_objects[$role_name]) || empty($wp_roles->role_objects[$role_name]->capabilities[$cap_name]))) {
244
- $class = 'cme-change cme-plus';
245
-
246
- } elseif ((false === $props['capabilities'][$cap_name]) && (!isset($wp_roles->role_objects[$role_name]->capabilities[$cap_name]) || false !== $wp_roles->role_objects[$role_name]->capabilities[$cap_name])) {
247
- $class = 'cme-change cme-negate';
248
-
249
- } elseif (!$val && !empty($wp_roles->role_objects[$role_name]->capabilities[$cap_name])) {
250
- $class = 'cme-change cme-minus';
251
- $cap_name = "&nbsp;&nbsp;" . esc_attr($cap_name) . "&nbsp;&nbsp;";
252
- } else {
253
- $class = '';
254
- }
255
-
256
- $items[$cap_name] = $class;
257
-
258
- $any_changes = $any_changes || $class;
259
- ?>
260
- <?php endforeach; ?>
261
-
262
- <?php if ($items) :?>
263
- <ul class="pp-restore-caps">
264
- <?php foreach($items as $cap_name => $class) :?>
265
- <li class="<?php echo esc_attr($class);?>"><?php echo esc_html($cap_name);?></li>
266
- <?php endforeach; ?>
267
- </ul>
268
- <?php endif;?>
269
-
270
- <?php if (!$any_changes):?>
271
- <span class="pp-restore-caps-no-change">
272
- <?php esc_html_e('No changes', 'capsman-enhanced');?>
273
- </span>
274
- <?php endif;?>
275
- <?php endforeach; ?>
276
- </div>
277
- <?php endif;
278
- }
279
- ?>
280
- </td>
281
- </tr>
282
- </table>
283
- </dd>
284
- </dl>
285
-
286
-
287
- <dl id="ppcb-tab-reset" style="display:none;">
288
- <dt><?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('Reset WordPress Defaults', 'capsman-enhanced'); else echo 'Reset Roles to WordPress Defaults'; ?></dt>
289
- <dd>
290
- <p><strong><span class="pp-caps-warning"><?php esc_html_e('WARNING:', 'capsman-enhanced'); ?></span> <?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('Reseting default Roles and Capabilities will set them to the WordPress install defaults.', 'capsman-enhanced'); else echo 'This will delete and/or modify stored role definitions.'; ?>
291
- </strong><br/>
292
- <br/>
293
- <?php
294
- esc_html_e('If you have installed any plugin that adds new roles or capabilities, these will be lost.', 'capsman-enhanced') ?>
295
- <br/>
296
- <strong><?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('It is recommended to use this only as a last resource!', 'capsman-enhanced'); else echo('It is recommended to use this only as a last resort!'); ?></strong>
297
- </p>
298
- <p><a class="ak-delete button-primary"
299
- title="<?php echo esc_attr__('Reset Roles and Capabilities to WordPress defaults', 'capsman-enhanced') ?>"
300
- href="<?php echo esc_url_raw(wp_nonce_url("admin.php?page=pp-capabilities-backup&amp;action=reset-defaults", 'capsman-reset-defaults')); ?>"
301
- onclick="if ( confirm('<?php echo esc_js(__("You are about to reset Roles and Capabilities to WordPress defaults.\n 'Cancel' to stop, 'OK' to reset.", 'capsman-enhanced')); ?>') ) { return true;}return false;"><?php esc_html_e('Reset to WordPress defaults', 'capsman-enhanced') ?></a>
302
-
303
- </dd>
304
- </dl>
305
-
306
-
307
- <dl id="ppcb-tab-import-export" style="display:none;">
308
- <dt><?php
309
- esc_html_e('Export / Import', 'capsman-enhanced'); ?></dt>
310
- <dd>
311
-
312
- <div class="metabox-holder">
313
- <div class="postbox">
314
- <h3><span><?php esc_html_e('Export Settings', 'capsman-enhanced'); ?></span></h3>
315
- <div class="inside">
316
- <p><?php esc_html_e('Export the plugin settings for this site as a .json file. This allows you to easily import the configuration into another site.', 'capsman-enhanced'); ?></p>
317
- <ul>
318
- <li>
319
- <input id="pp_capabilities_export_roles" name="pp_capabilities_export_section[]" type="checkbox" value="user_roles" checked />
320
- <label for="pp_capabilities_export_roles">
321
- <?php esc_html_e('Roles and Capabilities', 'capsman-enhanced'); ?>
322
- </label>
323
- </li>
324
- <?php
325
- $backup_sections = pp_capabilities_backup_sections();
326
- foreach($backup_sections as $backup_key => $backup_section){
327
- ?>
328
- <li>
329
- <input id="pp_capabilities_export_<?php echo esc_attr($backup_key); ?>" name="pp_capabilities_export_section[]" type="checkbox" value="<?php echo esc_attr($backup_key); ?>" checked />
330
- <label for="pp_capabilities_export_<?php echo esc_attr($backup_key); ?>"> <?php esc_html_e($backup_section['label']); ?> </label>
331
- </li>
332
- <?php
333
- }
334
- ?>
335
- </ul>
336
- <p>
337
- <input type="submit" name="export_backup"
338
- value="<?php esc_attr_e('Export', 'capsman-enhanced') ?>"
339
- class="button-primary"/>
340
- </p>
341
- </div>
342
- </div>
343
-
344
- <div class="postbox">
345
- <h3><span><?php esc_html_e('Import Settings', 'capsman-enhanced'); ?></span></h3>
346
- <div class="inside">
347
- <p><strong><span class="pp-caps-warning"><?php esc_html_e('WARNING:', 'capsman-enhanced'); ?></span> <?php esc_html_e('Please make a \'Manual Backup\' in the backup tab to enable backup restore in case anything goes wrong.', 'capsman-enhanced'); ?></p>
348
-
349
- <p><?php esc_html_e('Import the plugin settings from a .json file. This file can be obtained by exporting the settings on another site using the form above.', 'capsman-enhanced'); ?></p>
350
-
351
- <p><?php esc_html_e('Before importing, we recommend using the "Backup" tab to create a backup of your current settings.', 'capsman-enhanced'); ?></p>
352
-
353
- <br />
354
-
355
- <p>
356
- <input type="file" name="import_file"/>
357
- </p>
358
- <p>
359
- <input type="submit" name="import_backup"
360
- value="<?php esc_attr_e('Import', 'capsman-enhanced') ?>"
361
- class="button-primary"/>
362
- </p>
363
- </div>
364
- </div>
365
- </div>
366
-
367
- </dd>
368
- </dl>
369
-
370
-
371
- </td>
372
- </tr>
373
- </table>
374
- </fieldset>
375
- </div><!-- .pp-column-left -->
376
- <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ) { ?>
377
- <div class="pp-column-right">
378
- <?php
379
- $banners = new PublishPress\WordPressBanners\BannersMain;
380
- $banners->pp_display_banner(
381
- esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
382
- esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
383
- array(
384
- esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
385
- esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
386
- esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
387
- ),
388
- admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
389
- esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
390
- 'install-permissions.jpg'
391
- );
392
- ?>
393
- </div><!-- .pp-column-right -->
394
- <?php } ?>
395
- </div><!-- .pp-columns-wrapper -->
396
- </form>
397
-
398
- <script type="text/javascript">
399
- /* <![CDATA[ */
400
- jQuery(document).ready(function ($) {
401
-
402
- $('#cme_select_restore input[name="select_restore"]').on('change click', function () {
403
- $('div.cme-show-backup').hide();
404
-
405
- $('span.cme-selected-backup-caption').html($(this).next('label').html());
406
-
407
- var selected_val = $(this).val();
408
-
409
- $('td.cme-backup-info div').hide();
410
-
411
- switch (selected_val) {
412
- case 'restore_initial':
413
- $('#cme_display_capsman_backup_initial').addClass('current-display').show();
414
- break;
415
- case 'restore':
416
- $('#cme_display_capsman_backup').addClass('current-display').show();
417
- break;
418
- default:
419
- $('#cme_display_' + selected_val).addClass('current-display').show();
420
- }
421
-
422
- $('input.cme_backup_info_changes_only').click();
423
- $('div.cme_backup_info_changes_only').show();
424
- });
425
-
426
- $('input.cme_backup_info_changes_only').click(function() {
427
- $(this).attr('disabled', true);
428
- $('td.cme-backup-info div.current-display li:not(.cme-change)').toggle(!$(this).prop('checked'));
429
- $('span.pp-restore-caps-no-change').toggle($(this).prop('checked'));
430
- $(this).removeAttr('disabled');
431
- });
432
-
433
- $('#publishpress-capability-backup-tabs').find('li').click(function (e) {
434
- e.preventDefault();
435
- $('#publishpress-capability-backup-tabs').children('li').filter('.nav-tab-active').removeClass('nav-tab-active');
436
- $(this).addClass('nav-tab-active');
437
-
438
- $('dl[id^="ppcb-"]').hide();
439
- $($(this).find('a').first().attr('href')).show();
440
- });
441
-
442
- });
443
- /* ]]> */
444
- </script>
445
-
446
-
447
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
448
- cme_publishpressFooter();
449
- }
450
- ?>
451
- </div>
1
+ <?php
2
+ /**
3
+ * Capability Manager Backup Tool.
4
+ * Provides backup and restore functionality to Capability Manager.
5
+ *
6
+ * @version $Rev: 198515 $
7
+ * @author Jordi Canals
8
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals
9
+ * @license GNU General Public License version 2
10
+ * @link http://alkivia.org
11
+ * @package Alkivia
12
+ * @subpackage CapsMan
13
+ *
14
+ *
15
+ * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
16
+ *
17
+ * Modifications Copyright 2020, PublishPress <help@publishpress.com>
18
+ *
19
+ * This program is free software; you can redistribute it and/or
20
+ * modify it under the terms of the GNU General Public License
21
+ * version 2 as published by the Free Software Foundation.
22
+ *
23
+ * This program is distributed in the hope that it will be useful,
24
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
+ * GNU General Public License for more details.
27
+ *
28
+ * You should have received a copy of the GNU General Public License
29
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
30
+ */
31
+
32
+ global $wpdb;
33
+
34
+ $auto_backups = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%' ORDER BY option_id DESC");
35
+ ?>
36
+
37
+ <div class="wrap publishpress-caps-manage publishpress-caps-backup pressshack-admin-wrapper">
38
+ <div id="icon-capsman-admin" class="icon32"></div>
39
+ <h2><?php esc_html_e('Backup Tool for PublishPress Capabilities', 'capsman-enhanced');?></h2>
40
+
41
+
42
+ <form method="post" action="admin.php?page=pp-capabilities-backup" enctype="multipart/form-data">
43
+ <?php wp_nonce_field('pp-capabilities-backup'); ?>
44
+
45
+ <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
46
+ <div class="pp-column-left">
47
+ <ul id="publishpress-capability-backup-tabs" class="nav-tab-wrapper">
48
+ <li class="nav-tab nav-tab-active"><a href="#ppcb-tab-restore"><?php esc_html_e('Restore', 'capsman-enhanced');?></a></li>
49
+ <li class="nav-tab"><a href="#ppcb-tab-backup"><?php esc_html_e('Backup', 'capsman-enhanced');?></a></li>
50
+ <li class="nav-tab"><a href="#ppcb-tab-reset"><?php esc_html_e('Reset Roles', 'capsman-enhanced');?></a></li>
51
+ <li class="nav-tab"><a href="#ppcb-tab-import-export"><?php esc_html_e('Export / Import', 'capsman-enhanced');?></a></li>
52
+ </ul>
53
+
54
+ <fieldset>
55
+ <table id="akmin">
56
+ <tr>
57
+ <td class="content">
58
+
59
+ <dl id="ppcb-tab-backup" style="display:none;">
60
+ <dt><?php esc_html_e('Backup Roles and Capabilities', 'capsman-enhanced'); ?></dt>
61
+ <dd>
62
+ <p class="description">
63
+ <?php
64
+ $max_auto_backups = (defined('CME_AUTOBACKUPS')) ? (int) CME_AUTOBACKUPS : 20;
65
+ printf(esc_html__('PublishPress Capabilities automatically creates a backup on installation and whenever you save changes. The initial backup and last %d auto-backups are kept.', 'capsman-enhanced'), esc_attr($max_auto_backups));
66
+ ?>
67
+ </p>
68
+
69
+ <p class="description">
70
+ <?php esc_html_e('A backup created on this screen replaces any previous manual backups, but is never automatically replaced.', 'capsman-enhanced');?>
71
+ </p>
72
+
73
+ <div class="pp-caps-backup-button">
74
+ <input type="submit" name="save_backup"
75
+ value="<?php esc_attr_e('Manual Backup', 'capsman-enhanced') ?>"
76
+ class="button-primary"/>
77
+ </div>
78
+ </dd>
79
+
80
+ </dl>
81
+
82
+ <?php
83
+ $listed_manual_backup = false;
84
+ $backup_datestamp = get_option('capsman_backup_datestamp');
85
+ $last_caption = ($backup_datestamp) ? sprintf(esc_html__('Last Manual Backup - %s', 'capsman-enhanced'), date('j M Y, g:i a', $backup_datestamp)) : esc_html__('Last Backup', 'capsman-enhanced');
86
+ ?>
87
+
88
+ <dl id="ppcb-tab-restore">
89
+ <dt><?php esc_html_e('Restore Previous Roles and Capabilities', 'capsman-enhanced'); ?></dt>
90
+ <dd>
91
+ <p class="description">
92
+ <?php esc_html_e('PublishPress Capabilities automatically creates a backup on installation and whenever you save changes.', 'capsman-enhanced');?>
93
+ </p>
94
+
95
+ <p class="description">
96
+ <?php esc_html_e('On this screen, you can restore an earlier version of your roles and capabilities.', 'capsman-enhanced');?>
97
+ </p>
98
+
99
+ <table width='100%' class="form-table">
100
+ <tr>
101
+ <th scope="row"><?php esc_html_e('Available Backups:', 'capsman-enhanced'); ?></th>
102
+ <td>
103
+ <div id="cme_select_restore_div">
104
+ <ul id="cme_select_restore">
105
+ <?php foreach ($auto_backups as $row):
106
+ $arr = explode('_', str_replace('cme_backup_auto_', '', $row->option_name));
107
+ $arr[1] = str_replace('-', ':', $arr[1]);
108
+ $date_caption = implode(' ', $arr);
109
+
110
+ if (!$listed_manual_backup && ($backup_datestamp > strtotime($date_caption))) :
111
+ $manual_date_caption = date('Y-m-d, g:i a', $backup_datestamp);
112
+ $last_backup = get_option('capsman_last_backup');
113
+ if(!$last_backup){
114
+ $last_backup = __('all roles', 'capsman-enhanced');
115
+ }
116
+ ?>
117
+ <li>
118
+ <input type="radio" name="select_restore" value="restore" id="cme_restore_manual">
119
+ <label for="cme_restore_manual"><?php printf(esc_html__('Manual backup of %s (%s)', 'capsman-enhanced'), esc_html($last_backup), esc_html($manual_date_caption)); ?></label>
120
+ </li>
121
+ <?php
122
+ $listed_manual_backup = true;
123
+ endif;
124
+ ?>
125
+
126
+ <?php
127
+ $date_caption = str_replace(' ', ', ', $date_caption);
128
+ $date_caption = str_replace(', am', ' am', $date_caption);
129
+ $date_caption = str_replace(', pm', ' pm', $date_caption);
130
+ ?>
131
+
132
+ <li>
133
+ <input type="radio" name="select_restore" value="<?php echo esc_attr($row->option_name);?>" id="<?php echo esc_attr($row->option_name);?>">
134
+ <label for="<?php echo esc_attr($row->option_name);?>"><?php printf(esc_html__('Auto-backup of all roles (%s)', 'capsman-enhanced'), esc_html($date_caption)); ?></label>
135
+ </li>
136
+ <?php endforeach; ?>
137
+
138
+ <?php
139
+ if ($initial = get_option('capsman_backup_initial')):?>
140
+ <li>
141
+ <input type="radio" name="select_restore" value="restore_initial" id="cme_restore_initial">
142
+ <label for="cme_restore_initial"><?php esc_html_e('Initial backup of all roles', 'capsman-enhanced'); ?></label>
143
+ </li>
144
+ <?php endif; ?>
145
+ <!-- </select> -->
146
+ </ul>
147
+ </div>
148
+
149
+ <div class="cme-restore-button">
150
+ <input type="submit" name="restore_backup"
151
+ value="<?php esc_attr_e('Restore Selected Roles', 'capsman-enhanced') ?>"
152
+ class="button-primary"/>
153
+
154
+ <div class="cme-selected-backup-caption">
155
+ <span class="cme-selected-backup-caption cme-subtext"></span>
156
+ </div>
157
+ </div>
158
+ </td>
159
+
160
+ <td class="cme-backup-info">
161
+ <div class="cme_backup_info_changes_only" style="display:none">
162
+ <input type="checkbox" class="cme_backup_info_changes_only" autocomplete="off" checked="checked"> <?php esc_html_e('Show changes from current roles only', 'capsman-enhanced');?>
163
+ </div>
164
+
165
+ <?php
166
+ global $wp_roles;
167
+
168
+ $backup_datestamp = get_option('capsman_backup_initial_datestamp');
169
+ $initial_caption = ($backup_datestamp) ? sprintf(esc_html__('Initial Backup - %s', 'capsman-enhanced'), date('j M Y, g:i a', $backup_datestamp)) : esc_html__('Initial Backup', 'capsman-enhanced');
170
+
171
+ $backups = array(
172
+ 'capsman_backup_initial' => $initial_caption,
173
+ );
174
+
175
+ if (empty($capsman_backup)) {
176
+ $backups['capsman_backup'] = $last_caption;
177
+ }
178
+
179
+ foreach ($auto_backups as $row) {
180
+ $arr = explode('_', str_replace('cme_backup_auto_', '', $row->option_name));
181
+ $arr[1] = str_replace('-', ':', $arr[1]);
182
+
183
+ $date_caption = implode(' ', $arr);
184
+ $date_caption = str_replace(' ', ', ', $date_caption);
185
+ $date_caption = str_replace(', am', ' am', $date_caption);
186
+ $date_caption = str_replace(', pm', ' pm', $date_caption);
187
+
188
+ $option_name = sanitize_key($row->option_name);
189
+ $backups[$option_name] = "Auto-backup from " . $date_caption;
190
+ }
191
+
192
+ foreach ($backups as $name => $caption) {
193
+ if ($backup_data = get_option($name)) :?>
194
+ <div id="cme_display_<?php echo esc_attr($name); ?>" style="display:none;"
195
+ class="cme-show-backup">
196
+ <h3><?php printf(esc_html__("%s (%s roles)", 'capsman-enhanded'), esc_html($caption), count($backup_data)); ?></h3>
197
+
198
+ <?php
199
+ foreach ($wp_roles->role_objects as $role_name => $role_object) {
200
+ if (empty($backup_data[$role_name])) {
201
+ $role_caption = $role_object->name;
202
+ ?>
203
+ <h4><span class="cme-change cme-minus"><?php echo (esc_html(translate_user_role($role_caption)));?></span> <?php esc_html_e('(this role will be removed if you restore backup)', 'capsman-enhanced');?></h4>
204
+ <?php
205
+ }
206
+ }
207
+ ?>
208
+
209
+ <?php foreach ($backup_data as $role_name => $props) :
210
+ if (isset($wp_roles->role_objects[$role_name]->capabilities)) {
211
+ $props['capabilities'] = array_merge(
212
+ array_fill_keys(array_keys($wp_roles->role_objects[$role_name]->capabilities), 0),
213
+ $props['capabilities']
214
+ );
215
+ }
216
+ ?>
217
+ <?php if (!isset($props['name'])) continue; ?>
218
+ <?php
219
+ $level = 0;
220
+ for ($i = 10; $i >= 0; $i--) {
221
+ if (!empty($props['capabilities']["level_{$i}"])) {
222
+ $level = $i;
223
+ break;
224
+ }
225
+ }
226
+ ?>
227
+ <?php
228
+ $role_caption = $props['name'];
229
+ $role_class = (empty($wp_roles->role_objects[$role_name])) ? 'cme-change cme-plus' : '';
230
+ ?>
231
+
232
+ <h4 class="<?php echo esc_attr($role_class);?>"><?php printf(esc_html__('%s (level %s)', 'capsman-enhanced'), esc_html(translate_user_role($role_caption)), esc_html($level)); ?></h4>
233
+
234
+ <?php
235
+ $items = [];
236
+ $any_changes = false;
237
+
238
+ ksort($props['capabilities']);
239
+ foreach ($props['capabilities'] as $cap_name => $val) :
240
+ if (0 === strpos($cap_name, 'level_')) continue;
241
+ ?>
242
+ <?php
243
+ if ($val && (empty($wp_roles->role_objects[$role_name]) || empty($wp_roles->role_objects[$role_name]->capabilities[$cap_name]))) {
244
+ $class = 'cme-change cme-plus';
245
+
246
+ } elseif ((false === $props['capabilities'][$cap_name]) && (!isset($wp_roles->role_objects[$role_name]->capabilities[$cap_name]) || false !== $wp_roles->role_objects[$role_name]->capabilities[$cap_name])) {
247
+ $class = 'cme-change cme-negate';
248
+
249
+ } elseif (!$val && !empty($wp_roles->role_objects[$role_name]->capabilities[$cap_name])) {
250
+ $class = 'cme-change cme-minus';
251
+ $cap_name = "&nbsp;&nbsp;" . esc_attr($cap_name) . "&nbsp;&nbsp;";
252
+ } else {
253
+ $class = '';
254
+ }
255
+
256
+ $items[$cap_name] = $class;
257
+
258
+ $any_changes = $any_changes || $class;
259
+ ?>
260
+ <?php endforeach; ?>
261
+
262
+ <?php if ($items) :?>
263
+ <ul class="pp-restore-caps">
264
+ <?php foreach($items as $cap_name => $class) :?>
265
+ <li class="<?php echo esc_attr($class);?>"><?php echo esc_html($cap_name);?></li>
266
+ <?php endforeach; ?>
267
+ </ul>
268
+ <?php endif;?>
269
+
270
+ <?php if (!$any_changes):?>
271
+ <span class="pp-restore-caps-no-change">
272
+ <?php esc_html_e('No changes', 'capsman-enhanced');?>
273
+ </span>
274
+ <?php endif;?>
275
+ <?php endforeach; ?>
276
+ </div>
277
+ <?php endif;
278
+ }
279
+ ?>
280
+ </td>
281
+ </tr>
282
+ </table>
283
+ </dd>
284
+ </dl>
285
+
286
+
287
+ <dl id="ppcb-tab-reset" style="display:none;">
288
+ <dt><?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('Reset WordPress Defaults', 'capsman-enhanced'); else echo 'Reset Roles to WordPress Defaults'; ?></dt>
289
+ <dd>
290
+ <p><strong><span class="pp-caps-warning"><?php esc_html_e('WARNING:', 'capsman-enhanced'); ?></span> <?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('Reseting default Roles and Capabilities will set them to the WordPress install defaults.', 'capsman-enhanced'); else echo 'This will delete and/or modify stored role definitions.'; ?>
291
+ </strong><br/>
292
+ <br/>
293
+ <?php
294
+ esc_html_e('If you have installed any plugin that adds new roles or capabilities, these will be lost.', 'capsman-enhanced') ?>
295
+ <br/>
296
+ <strong><?php if (!in_array(get_locale(), ['en_EN', 'en_US'])) esc_html_e('It is recommended to use this only as a last resource!', 'capsman-enhanced'); else echo('It is recommended to use this only as a last resort!'); ?></strong>
297
+ </p>
298
+ <p><a class="ak-delete button-primary"
299
+ title="<?php echo esc_attr__('Reset Roles and Capabilities to WordPress defaults', 'capsman-enhanced') ?>"
300
+ href="<?php echo esc_url_raw(wp_nonce_url("admin.php?page=pp-capabilities-backup&amp;action=reset-defaults", 'capsman-reset-defaults')); ?>"
301
+ onclick="if ( confirm('<?php echo esc_js(__("You are about to reset Roles and Capabilities to WordPress defaults.\n 'Cancel' to stop, 'OK' to reset.", 'capsman-enhanced')); ?>') ) { return true;}return false;"><?php esc_html_e('Reset to WordPress defaults', 'capsman-enhanced') ?></a>
302
+
303
+ </dd>
304
+ </dl>
305
+
306
+
307
+ <dl id="ppcb-tab-import-export" style="display:none;">
308
+ <dt><?php
309
+ esc_html_e('Export / Import', 'capsman-enhanced'); ?></dt>
310
+ <dd>
311
+
312
+ <div class="metabox-holder">
313
+ <div class="postbox">
314
+ <h3><span><?php esc_html_e('Export Settings', 'capsman-enhanced'); ?></span></h3>
315
+ <div class="inside">
316
+ <p><?php esc_html_e('Export the plugin settings for this site as a .json file. This allows you to easily import the configuration into another site.', 'capsman-enhanced'); ?></p>
317
+ <ul>
318
+ <li>
319
+ <input id="pp_capabilities_export_roles" name="pp_capabilities_export_section[]" type="checkbox" value="user_roles" checked />
320
+ <label for="pp_capabilities_export_roles">
321
+ <?php esc_html_e('Roles and Capabilities', 'capsman-enhanced'); ?>
322
+ </label>
323
+ </li>
324
+ <?php
325
+ $backup_sections = pp_capabilities_backup_sections();
326
+ foreach($backup_sections as $backup_key => $backup_section){
327
+ ?>
328
+ <li>
329
+ <input id="pp_capabilities_export_<?php echo esc_attr($backup_key); ?>" name="pp_capabilities_export_section[]" type="checkbox" value="<?php echo esc_attr($backup_key); ?>" checked />
330
+ <label for="pp_capabilities_export_<?php echo esc_attr($backup_key); ?>"> <?php esc_html_e($backup_section['label']); ?> </label>
331
+ </li>
332
+ <?php
333
+ }
334
+ ?>
335
+ </ul>
336
+ <p>
337
+ <input type="submit" name="export_backup"
338
+ value="<?php esc_attr_e('Export', 'capsman-enhanced') ?>"
339
+ class="button-primary"/>
340
+ </p>
341
+ </div>
342
+ </div>
343
+
344
+ <div class="postbox">
345
+ <h3><span><?php esc_html_e('Import Settings', 'capsman-enhanced'); ?></span></h3>
346
+ <div class="inside">
347
+ <p><strong><span class="pp-caps-warning"><?php esc_html_e('WARNING:', 'capsman-enhanced'); ?></span> <?php esc_html_e('Please make a \'Manual Backup\' in the backup tab to enable backup restore in case anything goes wrong.', 'capsman-enhanced'); ?></p>
348
+
349
+ <p><?php esc_html_e('Import the plugin settings from a .json file. This file can be obtained by exporting the settings on another site using the form above.', 'capsman-enhanced'); ?></p>
350
+
351
+ <p><?php esc_html_e('Before importing, we recommend using the "Backup" tab to create a backup of your current settings.', 'capsman-enhanced'); ?></p>
352
+
353
+ <br />
354
+
355
+ <p>
356
+ <input type="file" name="import_file"/>
357
+ </p>
358
+ <p>
359
+ <input type="submit" name="import_backup"
360
+ value="<?php esc_attr_e('Import', 'capsman-enhanced') ?>"
361
+ class="button-primary"/>
362
+ </p>
363
+ </div>
364
+ </div>
365
+ </div>
366
+
367
+ </dd>
368
+ </dl>
369
+
370
+
371
+ </td>
372
+ </tr>
373
+ </table>
374
+ </fieldset>
375
+ </div><!-- .pp-column-left -->
376
+ <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ) { ?>
377
+ <div class="pp-column-right">
378
+ <?php
379
+ $banners = new PublishPress\WordPressBanners\BannersMain;
380
+ $banners->pp_display_banner(
381
+ esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
382
+ esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
383
+ array(
384
+ esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
385
+ esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
386
+ esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
387
+ ),
388
+ admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
389
+ esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
390
+ 'install-permissions.jpg'
391
+ );
392
+ ?>
393
+ </div><!-- .pp-column-right -->
394
+ <?php } ?>
395
+ </div><!-- .pp-columns-wrapper -->
396
+ </form>
397
+
398
+ <script type="text/javascript">
399
+ /* <![CDATA[ */
400
+ jQuery(document).ready(function ($) {
401
+
402
+ $('#cme_select_restore input[name="select_restore"]').on('change click', function () {
403
+ $('div.cme-show-backup').hide();
404
+
405
+ $('span.cme-selected-backup-caption').html($(this).next('label').html());
406
+
407
+ var selected_val = $(this).val();
408
+
409
+ $('td.cme-backup-info div').hide();
410
+
411
+ switch (selected_val) {
412
+ case 'restore_initial':
413
+ $('#cme_display_capsman_backup_initial').addClass('current-display').show();
414
+ break;
415
+ case 'restore':
416
+ $('#cme_display_capsman_backup').addClass('current-display').show();
417
+ break;
418
+ default:
419
+ $('#cme_display_' + selected_val).addClass('current-display').show();
420
+ }
421
+
422
+ $('input.cme_backup_info_changes_only').click();
423
+ $('div.cme_backup_info_changes_only').show();
424
+ });
425
+
426
+ $('input.cme_backup_info_changes_only').click(function() {
427
+ $(this).attr('disabled', true);
428
+ $('td.cme-backup-info div.current-display li:not(.cme-change)').toggle(!$(this).prop('checked'));
429
+ $('span.pp-restore-caps-no-change').toggle($(this).prop('checked'));
430
+ $(this).removeAttr('disabled');
431
+ });
432
+
433
+ $('#publishpress-capability-backup-tabs').find('li').click(function (e) {
434
+ e.preventDefault();
435
+ $('#publishpress-capability-backup-tabs').children('li').filter('.nav-tab-active').removeClass('nav-tab-active');
436
+ $(this).addClass('nav-tab-active');
437
+
438
+ $('dl[id^="ppcb-"]').hide();
439
+ $($(this).find('a').first().attr('href')).show();
440
+ });
441
+
442
+ });
443
+ /* ]]> */
444
+ </script>
445
+
446
+
447
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
448
+ cme_publishpressFooter();
449
+ }
450
+ ?>
451
+ </div>
includes/cap-helper.php CHANGED
@@ -1,378 +1,378 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
-
4
- /*
5
- * PublishPress Capabilities [Free]
6
- *
7
- * For post types and taxonomies with "Type-Specific Capabilities" enabled, modify defined capabilities to be unique
8
- *
9
- */
10
-
11
- // @todo: port improvements back to PP Core
12
-
13
- class CME_Cap_Helper {
14
- var $all_taxonomy_caps = array(); // $all_taxonomy_caps = array of capability names
15
- var $all_type_caps = array(); // $all_type_caps = array of capability names
16
- var $processed_types = array();
17
- var $processed_taxonomies = array();
18
-
19
- function __construct() {
20
- $this->refresh();
21
- }
22
-
23
- function refresh() {
24
- $this->force_distinct_post_caps();
25
-
26
- // Work around bug in More Taxonomies (and possibly other plugins) where category taxonomy is overriden without setting it public
27
- foreach( array( 'category', 'post_tag' ) as $taxonomy ) {
28
- global $wp_taxonomies;
29
- if ( isset( $wp_taxonomies[$taxonomy] ) )
30
- $wp_taxonomies[$taxonomy]->public = true;
31
- }
32
-
33
- $this->force_distinct_taxonomy_caps();
34
- }
35
-
36
- function force_distinct_post_caps() { // for selected post types (as stored in option array presspermit_enabled_post_types)
37
- global $wp_post_types, $wp_roles;
38
-
39
- $core_meta_caps = array_fill_keys( array( 'read_post', 'edit_post', 'delete_post' ), true );
40
-
41
- $append_caps = array( 'edit_published_posts' => 'edit_posts', 'edit_private_posts' => 'edit_posts', 'delete_posts' => 'edit_posts', 'delete_others_posts' => 'delete_posts', 'delete_published_posts' => 'delete_posts', 'delete_private_posts' => 'delete_posts', 'read' => 'read' );
42
-
43
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
44
-
45
- if ( get_option("{$pp_prefix}_define_create_posts_cap") ) {
46
- foreach( array( 'post', 'page' ) as $post_type ) {
47
- if ( $wp_post_types[$post_type]->cap->create_posts == $wp_post_types[$post_type]->cap->edit_posts ) {
48
- $wp_post_types[$post_type]->cap->create_posts = "create_{$post_type}s";
49
- }
50
- }
51
-
52
- foreach( cme_get_assisted_post_types() as $post_type ) {
53
- if ( ! in_array( $post_type, array( 'post', 'page' ) ) ) {
54
- if ( $wp_post_types[$post_type]->cap->create_posts == $wp_post_types[$post_type]->cap->edit_posts ) {
55
- $wp_post_types[$post_type]->cap->create_posts = str_replace( 'edit_', 'create_', $wp_post_types[$post_type]->cap->edit_posts );
56
- }
57
- }
58
- }
59
-
60
- $append_caps['create_posts'] = 'create_posts';
61
- }
62
-
63
- // count the number of post types that use each capability
64
- foreach( $wp_post_types as $post_type => $type_obj ) {
65
- foreach( array_unique( (array) $type_obj->cap ) as $cap_name ) {
66
- if ( ! isset( $this->all_type_caps[$cap_name] ) ) {
67
- $this->all_type_caps[$cap_name] = 1;
68
- } else {
69
- $this->all_type_caps[$cap_name]++;
70
- }
71
- }
72
- }
73
-
74
- $post_caps = (array) $wp_post_types['post']->cap;
75
- $page_caps = ( isset( $wp_post_types['page'] ) ) ? (array) $wp_post_types['page']->cap : array();
76
-
77
- $enabled_types = array_diff( cme_get_assisted_post_types(), $this->processed_types );
78
-
79
- // post types which are enabled for PP filtering must have distinct type-related cap definitions
80
- foreach( $enabled_types as $post_type ) {
81
- // append missing capability definitions
82
- foreach( $append_caps as $prop => $default ) {
83
- if ( ! isset( $wp_post_types[$post_type]->cap->$prop ) ) {
84
- $wp_post_types[$post_type]->cap->$prop = ( 'read' == $prop ) ? 'read' : $wp_post_types[$post_type]->cap->$default;
85
- }
86
- }
87
-
88
- $wp_post_types[$post_type]->map_meta_cap = true;
89
-
90
- $type_caps = array_diff_key( (array) $wp_post_types[$post_type]->cap, $core_meta_caps );
91
-
92
- $cap_base = ( 'attachment' == $post_type ) ? 'file' : $post_type;
93
-
94
- $cap_properties = array_keys( $type_caps );
95
-
96
- if ( 'attachment' == $post_type ) {
97
- $cap_properties = array_diff( $cap_properties, array( 'publish_posts', 'edit_published_posts', 'delete_published_posts', 'edit_private_posts', 'delete_private_posts', 'read_private_posts' ) );
98
- }
99
-
100
- // 'read' is not converted to a type-specific equivalent, so disregard it for perf.
101
- $cap_properties = array_diff( $cap_properties, array( 'read' ) );
102
-
103
- foreach( $cap_properties as $k => $cap_property ) {
104
- // If a cap property is set to one of the generic post type's caps, we will replace it
105
- if ( ( 'post' != $post_type ) && in_array( $type_caps[$cap_property], $post_caps ) ) {
106
- continue;
107
- }
108
-
109
- if ( ( 'page' != $post_type ) && in_array( $type_caps[$cap_property], $page_caps ) ) {
110
- continue;
111
- }
112
-
113
- // If a cap property is non-generic and not used by any other post types, keep it as is
114
- if ( $this->all_type_caps[ $type_caps[$cap_property] ] <= 1 ) {
115
- unset( $cap_properties[$k] );
116
-
117
- // If a cap property is used by any other post types, still keep it if it is the standard type-specific capability form for this post type
118
- } elseif ( ( $type_caps[$cap_property] == str_replace( "_posts", "_{$post_type}s", $cap_property ) )
119
- || ( $type_caps[$cap_property] == str_replace( "_pages", "_{$post_type}s", $cap_property ) ) ) {
120
-
121
- unset( $cap_properties[$k] );
122
-
123
- // If a cap property is used by any other post types, still keep it if it is the custom pluralized type-specific capability form for this post type
124
- } else {
125
- $plural_type = _cme_get_plural( $post_type, $wp_post_types[$post_type] );
126
- if ( ( $type_caps[$cap_property] == str_replace( "_posts", "_{$plural_type}", $cap_property ) )
127
- || ( $type_caps[$cap_property] == str_replace( "_pages", "_{$plural_type}", $cap_property ) ) ) {
128
-
129
- unset( $cap_properties[$k] );
130
- }
131
- }
132
- }
133
-
134
- if ( ! $cap_properties ) {
135
- // This post type has no defaulted cap properties that need to be made type-specific.
136
- continue;
137
- }
138
-
139
- $plural_type = _cme_get_plural( $post_type, $wp_post_types[$post_type] );
140
-
141
- if ( "{$cap_base}s" != $plural_type ) {
142
- // If any role already has capabilities based on simple plural form, keep using that instead
143
- foreach ( $wp_roles as $role ) {
144
- foreach( array_keys( $type_caps ) as $cap_property ) {
145
- $generic_type = ( strpos( $cap_property, '_pages' ) ) ? 'page' : 'post';
146
-
147
- $simple_plural = str_replace( "_{$generic_type}s", "_{$cap_base}s", $cap_property );
148
-
149
- if ( isset( $role->capabilities[$simple_plural] ) ) {
150
- // A simple plural capability was manually stored to a role, so stick with that form
151
- $plural_type = "{$cap_base}s";
152
- break 2;
153
- }
154
- }
155
- }
156
- }
157
-
158
- // Replace "edit_posts" and other post type caps with an equivalent for this post type, using pluralization determined above.
159
- // If a this is a problem, register the post type with an array capability_type arg including the desired plural form.
160
- // It is also possible to modify existing $wp_post_types[$post_type]->cap values by hooking to the init action at priority 40.
161
- foreach( $cap_properties as $cap_property ) {
162
- // create_posts capability may be defaulted to "edit_posts" / "edit_pages"
163
- $generic_type = ( strpos( $cap_property, '_pages' ) ) ? 'page' : 'post';
164
-
165
- $target_cap_property = ( 'create_posts' == $cap_property ) ? $wp_post_types[$generic_type]->cap->$cap_property : $cap_property;
166
-
167
- if ( $plural_type != "{$cap_base}s" ) {
168
- // Since plural form is not simple, first replace plurals ('edit_posts' > 'edit_doohickies')
169
- $wp_post_types[$post_type]->cap->$cap_property = str_replace( "_{$generic_type}s", "_{$plural_type}", $target_cap_property );
170
- } else {
171
- // Replace based on simple plural ('edit_posts' > 'edit_doohickys')
172
- $wp_post_types[$post_type]->cap->$cap_property = str_replace( "_{$generic_type}", "_{$cap_base}", $target_cap_property );
173
- }
174
- }
175
-
176
- // Force distinct capability_type. This may be an array with plural form in second element (but not useful here if set as default 'post' / 'posts' ).
177
- // Some caution here against changing the variable data type. Although array is supported, other plugin code may assume string.
178
- if ( is_array( $wp_post_types[$post_type]->capability_type ) ) {
179
- $wp_post_types[$post_type]->capability_type = array( $post_type, $plural_type );
180
-
181
- } elseif ( in_array( $wp_post_types[$post_type]->capability_type, array('post','page') ) ) {
182
- $wp_post_types[$post_type]->capability_type = $post_type;
183
- }
184
-
185
- $type_caps = array_diff_key( (array) $wp_post_types[$post_type]->cap, $core_meta_caps );
186
-
187
- $wp_post_types[$post_type]->cap = (object) array_merge( (array) $wp_post_types[$post_type]->cap, $type_caps );
188
-
189
- foreach( array_unique( (array) $wp_post_types[$post_type]->cap ) as $cap_name ) {
190
- if ( ! isset( $this->all_type_caps[$cap_name] ) ) {
191
- $this->all_type_caps[$cap_name] = 1;
192
- } else {
193
- $this->all_type_caps[$cap_name]++;
194
- }
195
- }
196
-
197
- } // end foreach post type
198
-
199
- $this->processed_types = array_merge( $this->processed_types, $enabled_types );
200
-
201
- // need this for casting to other types even if "post" type is not enabled for PP filtering
202
- $wp_post_types['post']->cap->set_posts_status = 'set_posts_status';
203
-
204
- if ((is_multisite() && is_super_admin()) || current_user_can('administrator') || current_user_can('pp_administer_content')) { // @ todo: support restricted administrator
205
- global $current_user;
206
- $current_user->allcaps = array_merge( $current_user->allcaps, array_fill_keys( array_keys( $this->all_type_caps ), true ) );
207
-
208
- global $pp_current_user;
209
- if ( ! empty( $pp_current_user ) ) {
210
- $pp_current_user->allcaps = array_merge( $pp_current_user->allcaps, array_fill_keys( array_keys( $this->all_type_caps ), true ) );
211
- }
212
- }
213
-
214
- do_action( 'cme_distinct_post_capabilities', $enabled_types );
215
- }
216
-
217
- function force_distinct_taxonomy_caps() {
218
- global $wp_taxonomies, $wp_roles;
219
-
220
- $use_taxonomies = array_diff( cme_get_assisted_taxonomies(), $this->processed_taxonomies );
221
- $detailed_taxonomies = cme_get_detailed_taxonomies();
222
-
223
- $tx_specific_caps = array( 'manage_terms' => 'manage_terms', 'edit_terms' => 'manage_terms', 'delete_terms' => 'manage_terms' );
224
- $tx_detail_caps = array( 'edit_terms' => 'edit_terms', 'delete_terms' => 'delete_terms', 'assign_terms' => 'assign_terms' );
225
-
226
- $core_tx_caps = array();
227
- $this->all_taxonomy_caps = array();
228
-
229
- // currently, disallow category and post_tag cap use by selected custom taxonomies, but don't require category and post_tag to have different caps
230
- $core_taxonomies = array( 'category' );
231
- foreach( $core_taxonomies as $taxonomy ) {
232
- foreach( array_keys($tx_specific_caps) as $cap_property ) {
233
- $core_tx_caps[ $wp_taxonomies[$taxonomy]->cap->$cap_property ] = true;
234
- }
235
- }
236
-
237
- // count the number of taxonomies that use each capability
238
- foreach( $wp_taxonomies as $taxonomy => $tx_obj ) {
239
- $this_tx_caps = (array) $tx_obj->cap;
240
-
241
- foreach( $this_tx_caps as $cap_name ) {
242
- if ( ! isset( $this->all_taxonomy_caps[$cap_name] ) ) {
243
- $this->all_taxonomy_caps[$cap_name] = 1;
244
- } else {
245
- $this->all_taxonomy_caps[$cap_name]++;
246
- }
247
- }
248
- }
249
-
250
- foreach( array_keys($wp_taxonomies) as $taxonomy ) {
251
- if ( 'yes' == $wp_taxonomies[$taxonomy]->public ) { // clean up a GD Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true)
252
- $wp_taxonomies[$taxonomy]->public = true;
253
-
254
- } elseif ( ( '' === $wp_taxonomies[$taxonomy]->public ) && ( ! empty( $wp_taxonomies[$taxonomy]->query_var_bool ) ) ) { // clean up a More Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true)
255
- $wp_taxonomies[$taxonomy]->public = true;
256
- }
257
-
258
- $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
259
-
260
- if ( ( ! in_array($taxonomy, $use_taxonomies) || empty( $wp_taxonomies[$taxonomy]->public ) ) && ( 'nav_menu' != $taxonomy ) )
261
- continue;
262
-
263
- if ( ! in_array( $taxonomy, $core_taxonomies ) ) {
264
- $plural_type = _cme_get_plural( $taxonomy, $wp_taxonomies[$taxonomy] );
265
-
266
- if ( "{$taxonomy}s" != $plural_type ) {
267
- // ... unless any role already has capabilities based on simple plural form
268
- foreach ( $wp_roles as $role ) {
269
- foreach( array_keys( $tx_caps ) as $cap_property ) {
270
- $simple_plural = str_replace( "_terms", "_{$taxonomy}s", $cap_property );
271
-
272
- if ( isset( $role->capabilities[$simple_plural] ) ) {
273
- // A simple plural capability was manually stored to a role, so stick with that form
274
- $plural_type = "{$taxonomy}s";
275
- break 2;
276
- }
277
- }
278
- }
279
- }
280
-
281
- // First, force taxonomy-specific capabilities.
282
- // (Don't allow any capability defined for this taxonomy to match any capability defined for category or post tag (unless this IS category or post tag)
283
- foreach( $tx_specific_caps as $cap_property => $replacement_cap_format ) {
284
- // If this capability is also defined as another taxonomy cap, replace it
285
- if ( ! empty($tx_caps[$cap_property]) && ( $this->all_taxonomy_caps[ $tx_caps[$cap_property] ] > 1 ) ) { // note: greater than check is on array value, not count
286
-
287
- // ... but leave it alone if it is a standard taxonomy-specific cap for this taxonomy
288
- if ( ( $tx_caps[$cap_property] != str_replace( '_terms', "_{$plural_type}", $cap_property ) )
289
- && ( $tx_caps[$cap_property] != str_replace( '_terms', "_{$taxonomy}s", $cap_property ) ) ) {
290
-
291
- $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
292
- }
293
- }
294
- }
295
- $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
296
-
297
-
298
- // Optionally, also force edit_terms and delete_terms to be distinct from manage_terms, and force a distinct assign_terms capability
299
- if ( in_array( $taxonomy, $detailed_taxonomies ) ) {
300
- foreach( $tx_detail_caps as $cap_property => $replacement_cap_format ) {
301
- $tx_cap_usage = array_count_values($tx_caps);
302
-
303
- // If a unique edit/delete capability is already defined, don't change the definition
304
- if (!empty($tx_caps[$cap_property])
305
- && (empty($this->all_taxonomy_caps[$tx_caps[$cap_property]]) || $this->all_taxonomy_caps[$tx_caps[$cap_property]] == 1)
306
- && ($tx_cap_usage[$tx_caps[$cap_property]] == 1)
307
- && !defined('CAPSMAN_LEGACY_DETAILED_TAX_CAPS')
308
- ) {
309
- // If roles were already configured with generated capability name, migrate to custom predefined capability name
310
- $custom_detailed_taxonomy_caps = true;
311
- $generated_cap_name = str_replace('_terms', "_{$plural_type}", $replacement_cap_format);
312
-
313
- if (!get_option("cme_migrated_taxonomy_caps")) {
314
- foreach ($wp_roles->roles as $role_name => $role) {
315
- if (!empty($role['capabilities'][$generated_cap_name])) {
316
- $_role = get_role($role_name);
317
- $_role->add_cap($tx_caps[$cap_property]);
318
- $_role->remove_cap($generated_cap_name);
319
- }
320
- }
321
- }
322
-
323
- continue;
324
- }
325
-
326
- if ( ! empty( $this->all_taxonomy_caps[ $tx_caps[$cap_property] ] ) ) {
327
- // assign_terms is otherwise not forced taxonomy-distinct
328
- $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
329
- break;
330
- }
331
-
332
- foreach( $tx_caps as $other_cap_property => $other_cap ) {
333
- if ( $other_cap_property == $cap_property ) {
334
- continue;
335
- }
336
-
337
- if ( $other_cap == $tx_caps[$cap_property] ) {
338
- $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
339
- break;
340
- }
341
- }
342
- }
343
-
344
- if (!empty($custom_detailed_taxonomy_caps)) {
345
- update_option("cme_migrated_taxonomy_caps", true);
346
- }
347
- }
348
-
349
- $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
350
- }
351
-
352
- foreach( array_unique( $tx_caps ) as $cap_name ) {
353
- if ( ! isset( $this->all_taxonomy_caps[$cap_name] ) ) {
354
- $this->all_taxonomy_caps[$cap_name] = 1;
355
- } else {
356
- $this->all_taxonomy_caps[$cap_name]++;
357
- }
358
- }
359
- }
360
-
361
- $this->all_taxonomy_caps = array_merge( $this->all_taxonomy_caps, array( 'assign_term' => true ) );
362
-
363
- if ((is_multisite() && is_super_admin()) || current_user_can('administrator') || current_user_can('pp_administer_content')) { // @ todo: support restricted administrator
364
- global $current_user;
365
- $current_user->allcaps = array_merge( $current_user->allcaps, array_fill_keys( array_keys( $this->all_taxonomy_caps ), true ) );
366
-
367
- global $pp_current_user;
368
- if ( ! empty( $pp_current_user ) ) {
369
- $pp_current_user->allcaps = array_merge( $pp_current_user->allcaps, array_fill_keys( array_keys( $this->all_taxonomy_caps ), true ) );
370
- }
371
- }
372
-
373
- // make sure Nav Menu Managers can also add menu items
374
- $wp_taxonomies['nav_menu']->cap->assign_terms = 'manage_nav_menus';
375
-
376
- $this->processed_taxonomies = array_merge( $this->processed_taxonomies, $use_taxonomies );
377
- }
378
- } // end class CME_Cap_Helper
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
+
4
+ /*
5
+ * PublishPress Capabilities [Free]
6
+ *
7
+ * For post types and taxonomies with "Type-Specific Capabilities" enabled, modify defined capabilities to be unique
8
+ *
9
+ */
10
+
11
+ // @todo: port improvements back to PP Core
12
+
13
+ class CME_Cap_Helper {
14
+ var $all_taxonomy_caps = array(); // $all_taxonomy_caps = array of capability names
15
+ var $all_type_caps = array(); // $all_type_caps = array of capability names
16
+ var $processed_types = array();
17
+ var $processed_taxonomies = array();
18
+
19
+ function __construct() {
20
+ $this->refresh();
21
+ }
22
+
23
+ function refresh() {
24
+ $this->force_distinct_post_caps();
25
+
26
+ // Work around bug in More Taxonomies (and possibly other plugins) where category taxonomy is overriden without setting it public
27
+ foreach( array( 'category', 'post_tag' ) as $taxonomy ) {
28
+ global $wp_taxonomies;
29
+ if ( isset( $wp_taxonomies[$taxonomy] ) )
30
+ $wp_taxonomies[$taxonomy]->public = true;
31
+ }
32
+
33
+ $this->force_distinct_taxonomy_caps();
34
+ }
35
+
36
+ function force_distinct_post_caps() { // for selected post types (as stored in option array presspermit_enabled_post_types)
37
+ global $wp_post_types, $wp_roles;
38
+
39
+ $core_meta_caps = array_fill_keys( array( 'read_post', 'edit_post', 'delete_post' ), true );
40
+
41
+ $append_caps = array( 'edit_published_posts' => 'edit_posts', 'edit_private_posts' => 'edit_posts', 'delete_posts' => 'edit_posts', 'delete_others_posts' => 'delete_posts', 'delete_published_posts' => 'delete_posts', 'delete_private_posts' => 'delete_posts', 'read' => 'read' );
42
+
43
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
44
+
45
+ if ( get_option("{$pp_prefix}_define_create_posts_cap") ) {
46
+ foreach( array( 'post', 'page' ) as $post_type ) {
47
+ if ( $wp_post_types[$post_type]->cap->create_posts == $wp_post_types[$post_type]->cap->edit_posts ) {
48
+ $wp_post_types[$post_type]->cap->create_posts = "create_{$post_type}s";
49
+ }
50
+ }
51
+
52
+ foreach( cme_get_assisted_post_types() as $post_type ) {
53
+ if ( ! in_array( $post_type, array( 'post', 'page' ) ) ) {
54
+ if ( $wp_post_types[$post_type]->cap->create_posts == $wp_post_types[$post_type]->cap->edit_posts ) {
55
+ $wp_post_types[$post_type]->cap->create_posts = str_replace( 'edit_', 'create_', $wp_post_types[$post_type]->cap->edit_posts );
56
+ }
57
+ }
58
+ }
59
+
60
+ $append_caps['create_posts'] = 'create_posts';
61
+ }
62
+
63
+ // count the number of post types that use each capability
64
+ foreach( $wp_post_types as $post_type => $type_obj ) {
65
+ foreach( array_unique( (array) $type_obj->cap ) as $cap_name ) {
66
+ if ( ! isset( $this->all_type_caps[$cap_name] ) ) {
67
+ $this->all_type_caps[$cap_name] = 1;
68
+ } else {
69
+ $this->all_type_caps[$cap_name]++;
70
+ }
71
+ }
72
+ }
73
+
74
+ $post_caps = (array) $wp_post_types['post']->cap;
75
+ $page_caps = ( isset( $wp_post_types['page'] ) ) ? (array) $wp_post_types['page']->cap : array();
76
+
77
+ $enabled_types = array_diff( cme_get_assisted_post_types(), $this->processed_types );
78
+
79
+ // post types which are enabled for PP filtering must have distinct type-related cap definitions
80
+ foreach( $enabled_types as $post_type ) {
81
+ // append missing capability definitions
82
+ foreach( $append_caps as $prop => $default ) {
83
+ if ( ! isset( $wp_post_types[$post_type]->cap->$prop ) ) {
84
+ $wp_post_types[$post_type]->cap->$prop = ( 'read' == $prop ) ? 'read' : $wp_post_types[$post_type]->cap->$default;
85
+ }
86
+ }
87
+
88
+ $wp_post_types[$post_type]->map_meta_cap = true;
89
+
90
+ $type_caps = array_diff_key( (array) $wp_post_types[$post_type]->cap, $core_meta_caps );
91
+
92
+ $cap_base = ( 'attachment' == $post_type ) ? 'file' : $post_type;
93
+
94
+ $cap_properties = array_keys( $type_caps );
95
+
96
+ if ( 'attachment' == $post_type ) {
97
+ $cap_properties = array_diff( $cap_properties, array( 'publish_posts', 'edit_published_posts', 'delete_published_posts', 'edit_private_posts', 'delete_private_posts', 'read_private_posts' ) );
98
+ }
99
+
100
+ // 'read' is not converted to a type-specific equivalent, so disregard it for perf.
101
+ $cap_properties = array_diff( $cap_properties, array( 'read' ) );
102
+
103
+ foreach( $cap_properties as $k => $cap_property ) {
104
+ // If a cap property is set to one of the generic post type's caps, we will replace it
105
+ if ( ( 'post' != $post_type ) && in_array( $type_caps[$cap_property], $post_caps ) ) {
106
+ continue;
107
+ }
108
+
109
+ if ( ( 'page' != $post_type ) && in_array( $type_caps[$cap_property], $page_caps ) ) {
110
+ continue;
111
+ }
112
+
113
+ // If a cap property is non-generic and not used by any other post types, keep it as is
114
+ if ( $this->all_type_caps[ $type_caps[$cap_property] ] <= 1 ) {
115
+ unset( $cap_properties[$k] );
116
+
117
+ // If a cap property is used by any other post types, still keep it if it is the standard type-specific capability form for this post type
118
+ } elseif ( ( $type_caps[$cap_property] == str_replace( "_posts", "_{$post_type}s", $cap_property ) )
119
+ || ( $type_caps[$cap_property] == str_replace( "_pages", "_{$post_type}s", $cap_property ) ) ) {
120
+
121
+ unset( $cap_properties[$k] );
122
+
123
+ // If a cap property is used by any other post types, still keep it if it is the custom pluralized type-specific capability form for this post type
124
+ } else {
125
+ $plural_type = _cme_get_plural( $post_type, $wp_post_types[$post_type] );
126
+ if ( ( $type_caps[$cap_property] == str_replace( "_posts", "_{$plural_type}", $cap_property ) )
127
+ || ( $type_caps[$cap_property] == str_replace( "_pages", "_{$plural_type}", $cap_property ) ) ) {
128
+
129
+ unset( $cap_properties[$k] );
130
+ }
131
+ }
132
+ }
133
+
134
+ if ( ! $cap_properties ) {
135
+ // This post type has no defaulted cap properties that need to be made type-specific.
136
+ continue;
137
+ }
138
+
139
+ $plural_type = _cme_get_plural( $post_type, $wp_post_types[$post_type] );
140
+
141
+ if ( "{$cap_base}s" != $plural_type ) {
142
+ // If any role already has capabilities based on simple plural form, keep using that instead
143
+ foreach ( $wp_roles as $role ) {
144
+ foreach( array_keys( $type_caps ) as $cap_property ) {
145
+ $generic_type = ( strpos( $cap_property, '_pages' ) ) ? 'page' : 'post';
146
+
147
+ $simple_plural = str_replace( "_{$generic_type}s", "_{$cap_base}s", $cap_property );
148
+
149
+ if ( isset( $role->capabilities[$simple_plural] ) ) {
150
+ // A simple plural capability was manually stored to a role, so stick with that form
151
+ $plural_type = "{$cap_base}s";
152
+ break 2;
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ // Replace "edit_posts" and other post type caps with an equivalent for this post type, using pluralization determined above.
159
+ // If a this is a problem, register the post type with an array capability_type arg including the desired plural form.
160
+ // It is also possible to modify existing $wp_post_types[$post_type]->cap values by hooking to the init action at priority 40.
161
+ foreach( $cap_properties as $cap_property ) {
162
+ // create_posts capability may be defaulted to "edit_posts" / "edit_pages"
163
+ $generic_type = ( strpos( $cap_property, '_pages' ) ) ? 'page' : 'post';
164
+
165
+ $target_cap_property = ( 'create_posts' == $cap_property ) ? $wp_post_types[$generic_type]->cap->$cap_property : $cap_property;
166
+
167
+ if ( $plural_type != "{$cap_base}s" ) {
168
+ // Since plural form is not simple, first replace plurals ('edit_posts' > 'edit_doohickies')
169
+ $wp_post_types[$post_type]->cap->$cap_property = str_replace( "_{$generic_type}s", "_{$plural_type}", $target_cap_property );
170
+ } else {
171
+ // Replace based on simple plural ('edit_posts' > 'edit_doohickys')
172
+ $wp_post_types[$post_type]->cap->$cap_property = str_replace( "_{$generic_type}", "_{$cap_base}", $target_cap_property );
173
+ }
174
+ }
175
+
176
+ // Force distinct capability_type. This may be an array with plural form in second element (but not useful here if set as default 'post' / 'posts' ).
177
+ // Some caution here against changing the variable data type. Although array is supported, other plugin code may assume string.
178
+ if ( is_array( $wp_post_types[$post_type]->capability_type ) ) {
179
+ $wp_post_types[$post_type]->capability_type = array( $post_type, $plural_type );
180
+
181
+ } elseif ( in_array( $wp_post_types[$post_type]->capability_type, array('post','page') ) ) {
182
+ $wp_post_types[$post_type]->capability_type = $post_type;
183
+ }
184
+
185
+ $type_caps = array_diff_key( (array) $wp_post_types[$post_type]->cap, $core_meta_caps );
186
+
187
+ $wp_post_types[$post_type]->cap = (object) array_merge( (array) $wp_post_types[$post_type]->cap, $type_caps );
188
+
189
+ foreach( array_unique( (array) $wp_post_types[$post_type]->cap ) as $cap_name ) {
190
+ if ( ! isset( $this->all_type_caps[$cap_name] ) ) {
191
+ $this->all_type_caps[$cap_name] = 1;
192
+ } else {
193
+ $this->all_type_caps[$cap_name]++;
194
+ }
195
+ }
196
+
197
+ } // end foreach post type
198
+
199
+ $this->processed_types = array_merge( $this->processed_types, $enabled_types );
200
+
201
+ // need this for casting to other types even if "post" type is not enabled for PP filtering
202
+ $wp_post_types['post']->cap->set_posts_status = 'set_posts_status';
203
+
204
+ if ((is_multisite() && is_super_admin()) || current_user_can('administrator') || current_user_can('pp_administer_content')) { // @ todo: support restricted administrator
205
+ global $current_user;
206
+ $current_user->allcaps = array_merge( $current_user->allcaps, array_fill_keys( array_keys( $this->all_type_caps ), true ) );
207
+
208
+ global $pp_current_user;
209
+ if ( ! empty( $pp_current_user ) ) {
210
+ $pp_current_user->allcaps = array_merge( $pp_current_user->allcaps, array_fill_keys( array_keys( $this->all_type_caps ), true ) );
211
+ }
212
+ }
213
+
214
+ do_action( 'cme_distinct_post_capabilities', $enabled_types );
215
+ }
216
+
217
+ function force_distinct_taxonomy_caps() {
218
+ global $wp_taxonomies, $wp_roles;
219
+
220
+ $use_taxonomies = array_diff( cme_get_assisted_taxonomies(), $this->processed_taxonomies );
221
+ $detailed_taxonomies = cme_get_detailed_taxonomies();
222
+
223
+ $tx_specific_caps = array( 'manage_terms' => 'manage_terms', 'edit_terms' => 'manage_terms', 'delete_terms' => 'manage_terms' );
224
+ $tx_detail_caps = array( 'edit_terms' => 'edit_terms', 'delete_terms' => 'delete_terms', 'assign_terms' => 'assign_terms' );
225
+
226
+ $core_tx_caps = array();
227
+ $this->all_taxonomy_caps = array();
228
+
229
+ // currently, disallow category and post_tag cap use by selected custom taxonomies, but don't require category and post_tag to have different caps
230
+ $core_taxonomies = array( 'category' );
231
+ foreach( $core_taxonomies as $taxonomy ) {
232
+ foreach( array_keys($tx_specific_caps) as $cap_property ) {
233
+ $core_tx_caps[ $wp_taxonomies[$taxonomy]->cap->$cap_property ] = true;
234
+ }
235
+ }
236
+
237
+ // count the number of taxonomies that use each capability
238
+ foreach( $wp_taxonomies as $taxonomy => $tx_obj ) {
239
+ $this_tx_caps = (array) $tx_obj->cap;
240
+
241
+ foreach( $this_tx_caps as $cap_name ) {
242
+ if ( ! isset( $this->all_taxonomy_caps[$cap_name] ) ) {
243
+ $this->all_taxonomy_caps[$cap_name] = 1;
244
+ } else {
245
+ $this->all_taxonomy_caps[$cap_name]++;
246
+ }
247
+ }
248
+ }
249
+
250
+ foreach( array_keys($wp_taxonomies) as $taxonomy ) {
251
+ if ( 'yes' == $wp_taxonomies[$taxonomy]->public ) { // clean up a GD Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true)
252
+ $wp_taxonomies[$taxonomy]->public = true;
253
+
254
+ } elseif ( ( '' === $wp_taxonomies[$taxonomy]->public ) && ( ! empty( $wp_taxonomies[$taxonomy]->query_var_bool ) ) ) { // clean up a More Taxonomies quirk (otherwise wp_get_taxonomy_object will fail when filtering for public => true)
255
+ $wp_taxonomies[$taxonomy]->public = true;
256
+ }
257
+
258
+ $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
259
+
260
+ if ( ( ! in_array($taxonomy, $use_taxonomies) || empty( $wp_taxonomies[$taxonomy]->public ) ) && ( 'nav_menu' != $taxonomy ) )
261
+ continue;
262
+
263
+ if ( ! in_array( $taxonomy, $core_taxonomies ) ) {
264
+ $plural_type = _cme_get_plural( $taxonomy, $wp_taxonomies[$taxonomy] );
265
+
266
+ if ( "{$taxonomy}s" != $plural_type ) {
267
+ // ... unless any role already has capabilities based on simple plural form
268
+ foreach ( $wp_roles as $role ) {
269
+ foreach( array_keys( $tx_caps ) as $cap_property ) {
270
+ $simple_plural = str_replace( "_terms", "_{$taxonomy}s", $cap_property );
271
+
272
+ if ( isset( $role->capabilities[$simple_plural] ) ) {
273
+ // A simple plural capability was manually stored to a role, so stick with that form
274
+ $plural_type = "{$taxonomy}s";
275
+ break 2;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ // First, force taxonomy-specific capabilities.
282
+ // (Don't allow any capability defined for this taxonomy to match any capability defined for category or post tag (unless this IS category or post tag)
283
+ foreach( $tx_specific_caps as $cap_property => $replacement_cap_format ) {
284
+ // If this capability is also defined as another taxonomy cap, replace it
285
+ if ( ! empty($tx_caps[$cap_property]) && ( $this->all_taxonomy_caps[ $tx_caps[$cap_property] ] > 1 ) ) { // note: greater than check is on array value, not count
286
+
287
+ // ... but leave it alone if it is a standard taxonomy-specific cap for this taxonomy
288
+ if ( ( $tx_caps[$cap_property] != str_replace( '_terms', "_{$plural_type}", $cap_property ) )
289
+ && ( $tx_caps[$cap_property] != str_replace( '_terms', "_{$taxonomy}s", $cap_property ) ) ) {
290
+
291
+ $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
292
+ }
293
+ }
294
+ }
295
+ $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
296
+
297
+
298
+ // Optionally, also force edit_terms and delete_terms to be distinct from manage_terms, and force a distinct assign_terms capability
299
+ if ( in_array( $taxonomy, $detailed_taxonomies ) ) {
300
+ foreach( $tx_detail_caps as $cap_property => $replacement_cap_format ) {
301
+ $tx_cap_usage = array_count_values($tx_caps);
302
+
303
+ // If a unique edit/delete capability is already defined, don't change the definition
304
+ if (!empty($tx_caps[$cap_property])
305
+ && (empty($this->all_taxonomy_caps[$tx_caps[$cap_property]]) || $this->all_taxonomy_caps[$tx_caps[$cap_property]] == 1)
306
+ && ($tx_cap_usage[$tx_caps[$cap_property]] == 1)
307
+ && !defined('CAPSMAN_LEGACY_DETAILED_TAX_CAPS')
308
+ ) {
309
+ // If roles were already configured with generated capability name, migrate to custom predefined capability name
310
+ $custom_detailed_taxonomy_caps = true;
311
+ $generated_cap_name = str_replace('_terms', "_{$plural_type}", $replacement_cap_format);
312
+
313
+ if (!get_option("cme_migrated_taxonomy_caps")) {
314
+ foreach ($wp_roles->roles as $role_name => $role) {
315
+ if (!empty($role['capabilities'][$generated_cap_name])) {
316
+ $_role = get_role($role_name);
317
+ $_role->add_cap($tx_caps[$cap_property]);
318
+ $_role->remove_cap($generated_cap_name);
319
+ }
320
+ }
321
+ }
322
+
323
+ continue;
324
+ }
325
+
326
+ if ( ! empty( $this->all_taxonomy_caps[ $tx_caps[$cap_property] ] ) ) {
327
+ // assign_terms is otherwise not forced taxonomy-distinct
328
+ $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
329
+ break;
330
+ }
331
+
332
+ foreach( $tx_caps as $other_cap_property => $other_cap ) {
333
+ if ( $other_cap_property == $cap_property ) {
334
+ continue;
335
+ }
336
+
337
+ if ( $other_cap == $tx_caps[$cap_property] ) {
338
+ $wp_taxonomies[$taxonomy]->cap->$cap_property = str_replace( '_terms', "_{$plural_type}", $replacement_cap_format );
339
+ break;
340
+ }
341
+ }
342
+ }
343
+
344
+ if (!empty($custom_detailed_taxonomy_caps)) {
345
+ update_option("cme_migrated_taxonomy_caps", true);
346
+ }
347
+ }
348
+
349
+ $tx_caps = (array) $wp_taxonomies[$taxonomy]->cap;
350
+ }
351
+
352
+ foreach( array_unique( $tx_caps ) as $cap_name ) {
353
+ if ( ! isset( $this->all_taxonomy_caps[$cap_name] ) ) {
354
+ $this->all_taxonomy_caps[$cap_name] = 1;
355
+ } else {
356
+ $this->all_taxonomy_caps[$cap_name]++;
357
+ }
358
+ }
359
+ }
360
+
361
+ $this->all_taxonomy_caps = array_merge( $this->all_taxonomy_caps, array( 'assign_term' => true ) );
362
+
363
+ if ((is_multisite() && is_super_admin()) || current_user_can('administrator') || current_user_can('pp_administer_content')) { // @ todo: support restricted administrator
364
+ global $current_user;
365
+ $current_user->allcaps = array_merge( $current_user->allcaps, array_fill_keys( array_keys( $this->all_taxonomy_caps ), true ) );
366
+
367
+ global $pp_current_user;
368
+ if ( ! empty( $pp_current_user ) ) {
369
+ $pp_current_user->allcaps = array_merge( $pp_current_user->allcaps, array_fill_keys( array_keys( $this->all_taxonomy_caps ), true ) );
370
+ }
371
+ }
372
+
373
+ // make sure Nav Menu Managers can also add menu items
374
+ $wp_taxonomies['nav_menu']->cap->assign_terms = 'manage_nav_menus';
375
+
376
+ $this->processed_taxonomies = array_merge( $this->processed_taxonomies, $use_taxonomies );
377
+ }
378
+ } // end class CME_Cap_Helper
includes/features/admin-features.php CHANGED
@@ -1,349 +1,349 @@
1
- <?php
2
- /**
3
- * Capability Manager Admin Features.
4
- * Hide and block selected Admin Features like toolbar, dashboard widgets etc per-role.
5
- *
6
- * Copyright 2020, PublishPress <help@publishpress.com>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * version 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
- require_once(dirname(CME_FILE) . '/includes/features/restrict-admin-features.php');
22
-
23
- global $capsman;
24
-
25
- $roles = $capsman->roles;
26
- $default_role = $capsman->get_last_role();
27
-
28
-
29
- $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
30
- $disabled_admin_items = array_key_exists($default_role, $disabled_admin_items) ? (array)$disabled_admin_items[$default_role] : [];
31
-
32
- $admin_features_elements = PP_Capabilities_Admin_Features::elementsLayout();
33
- ?>
34
-
35
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper">
36
- <div id="icon-capsman-admin" class="icon32"></div>
37
- <h2><?php esc_html_e('Admin Feature Restrictions', 'capabilities-pro'); ?></h2>
38
-
39
- <form method="post" id="ppc-admin-features-form" action="admin.php?page=pp-capabilities-admin-features">
40
- <?php wp_nonce_field('pp-capabilities-admin-features'); ?>
41
-
42
- <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
43
- <div class="pp-column-left">
44
- <fieldset>
45
- <table id="akmin">
46
- <tr>
47
- <td class="content">
48
-
49
- <div class="publishpress-headline">
50
- <span class="cme-subtext">
51
- <span class='pp-capability-role-caption'>
52
- <?php
53
- esc_html_e('Note: You are only restricting access to admin features screens. Some plugins may also add features to other areas of WordPress.',
54
- 'capabilities-pro');
55
- ?>
56
- </span>
57
- </span>
58
- </div>
59
- <div class="publishpress-filters">
60
- <select name="ppc-admin-features-role" class="ppc-admin-features-role">
61
- <?php
62
- foreach ($roles as $role_name => $name) :
63
- $name = translate_user_role($name);
64
- ?>
65
- <option value="<?php echo esc_attr($role_name); ?>" <?php selected($default_role,
66
- $role_name); ?>><?php echo esc_html($name); ?></option>
67
- <?php
68
- endforeach;
69
- ?>
70
- </select> &nbsp;
71
-
72
- <img class="loading" src="<?php echo esc_url_raw($capsman->mod_url); ?>/images/wpspin_light.gif"
73
- style="display: none">
74
-
75
- <input type="submit" name="admin-features-submit"
76
- value="<?php esc_attr_e('Save Changes', 'capabilities-pro') ?>"
77
- class="button-primary ppc-admin-features-submit" style="float:right"/>
78
- </div>
79
-
80
- <div id="pp-capability-menu-wrapper" class="postbox">
81
- <div class="pp-capability-menus">
82
-
83
- <div class="pp-capability-menus-wrap">
84
- <div id="pp-capability-menus-general"
85
- class="pp-capability-menus-content editable-role" style="display: block;">
86
-
87
- <table
88
- class="wp-list-table widefat striped pp-capability-menus-select">
89
-
90
- <tfoot>
91
- <tr class="ppc-menu-row parent-menu">
92
-
93
- <td class="restrict-column ppc-menu-checkbox">
94
- <input id="check-all-item-2"
95
- class="check-item check-all-menu-item" type="checkbox"/>
96
- </td>
97
- <td class="menu-column ppc-menu-item">
98
- </td>
99
-
100
- </tr>
101
- </tfoot>
102
-
103
- <tbody>
104
-
105
- <?php
106
- $icon_list = (array)PP_Capabilities_Admin_Features::elementLayoutItemIcons();
107
-
108
- $sn = 0;
109
- foreach ($admin_features_elements as $section_title => $section_elements) :
110
- $sn++;
111
- $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
112
- $icon_name = isset($icon_list[$section_slug]) ? $icon_list[$section_slug] : '&mdash;';
113
- ?>
114
-
115
- <tr class="ppc-menu-row parent-menu <?php echo esc_attr($section_slug); ?>">
116
- <?php if ($section_slug === 'admintoolbar') :
117
- $restrict_value = 'ppc_adminbar||admintoolbar';
118
- ?>
119
- <td class="features-section-header restrict-column ppc-menu-checkbox" style="text-align: left;" colspan="2">
120
- <input
121
- id="check-item-<?php echo (int) $sn; ?>"
122
- class="check-item" type="checkbox"
123
- name="capsman_disabled_admin_features[]"
124
- value="<?php echo esc_attr($restrict_value); ?>"
125
- <?php echo (in_array($restrict_value, $disabled_admin_items)) ? 'checked' : ''; ?>/>
126
- <label for="check-item-<?php echo (int) $sn; ?>">
127
- <strong class="menu-column ppc-menu-item menu-item-link<?php echo (in_array($restrict_value,
128
- $disabled_admin_items)) ? ' restricted' : ''; ?>">
129
- <i class="dashicons dashicons-<?php echo esc_attr($icon_name) ?>"></i> <?php echo esc_html($section_title); ?>
130
- </strong>
131
- </label>
132
- </td>
133
- <?php else : ?>
134
- <td class="features-section-header" colspan="2">
135
- <strong><i
136
- class="dashicons dashicons-<?php echo esc_attr($icon_name) ?>"></i> <?php echo esc_html($section_title); ?>
137
- </strong>
138
- </td>
139
- <?php endif; ?>
140
-
141
- </tr>
142
-
143
- <?php
144
- foreach ($section_elements as $section_id => $section_array) :
145
- $sn++;
146
- if (!$section_id) {
147
- continue;
148
- }
149
- $item_name = $section_array['label'];
150
- $item_action = $section_array['action'];
151
- $restrict_value = $item_action.'||'.$section_id;
152
- if($item_action === 'ppc_dashboard_widget'){
153
- $restrict_value .= '||'.$section_array['context'];
154
- }
155
- ?>
156
-
157
- <tr class="ppc-menu-row child-menu <?php echo esc_attr($section_slug); ?>">
158
-
159
- <td class="restrict-column ppc-menu-checkbox">
160
- <input
161
- id="check-item-<?php echo (int) $sn; ?>"
162
- class="check-item" type="checkbox"
163
- name="capsman_disabled_admin_features[]"
164
- value="<?php echo esc_attr($restrict_value); ?>"
165
- <?php echo (in_array($restrict_value, $disabled_admin_items)) ? 'checked' : ''; ?>/>
166
- </td>
167
- <td class="menu-column ppc-menu-item">
168
-
169
- <label for="check-item-<?php echo (int) $sn; ?>">
170
- <span
171
- class="menu-item-link<?php echo (in_array($restrict_value,
172
- $disabled_admin_items)) ? ' restricted' : ''; ?>">
173
- <strong>
174
- <?php
175
- if ((isset($section_array['step']) && $section_array['step'] > 0) && isset($section_array['parent']) && !empty($section_array['parent'])) {
176
- $step_margin = $section_array['step'] * 20;
177
- echo '<span style="margin-left: ' . (int) $step_margin . 'px;"></span>';
178
- echo ' &mdash; ';
179
- } else {
180
- if (isset($icon_list[$section_id])) {
181
- echo '<i class="dashicons dashicons-' . esc_attr($icon_list[$section_id]) . '"></i>';
182
- } else {
183
- echo '&mdash;';
184
- }
185
- }
186
- ?>
187
- <?php
188
- if(isset($section_array['custom_element']) && ($section_array['custom_element'] === true)){
189
- echo esc_html($section_array['element_label']) . ' <small class="entry">(' . esc_html($section_array['element_items']). ')</small> &nbsp; '
190
- . '<span class="' . esc_attr($section_array['button_class']) . '" data-id="' . esc_attr($section_array['button_data_id']) . '"><small>(' . esc_html__('Delete', 'capabilities-pro') . ')</small></span>' . '';
191
- }else{
192
- echo esc_html($item_name);
193
- }
194
- ?>
195
- </strong></span>
196
- </label>
197
- </td>
198
-
199
- </tr>
200
-
201
- <?php
202
- endforeach; // $section_elements subsection loop
203
- endforeach; // $admin_features_elements section loop
204
- ?>
205
- <?php do_action('pp_capabilities_admin_features_after_table_tr'); ?>
206
- </tbody>
207
- </table>
208
- <?php do_action('pp_capabilities_admin_features_after_table'); ?>
209
- </div>
210
-
211
- </div>
212
- </div>
213
- </div>
214
- <input type="submit" name="admin-features-submit"
215
- value="<?php esc_attr_e('Save Changes', 'capabilities-pro') ?>"
216
- class="button-primary ppc-admin-features-submit"/>
217
- </td>
218
- </tr>
219
- </table>
220
-
221
- </fieldset>
222
- </div><!-- .pp-column-left -->
223
- <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED) { ?>
224
- <div class="pp-column-right">
225
- <?php
226
- $banners = new PublishPress\WordPressBanners\BannersMain;
227
- $banners->pp_display_banner(
228
- esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
229
- esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
230
- array(
231
- esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
232
- esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
233
- esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
234
- ),
235
- admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
236
- esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
237
- 'install-permissions.jpg'
238
- );
239
- ?>
240
- </div><!-- .pp-column-right -->
241
- <?php } ?>
242
- </div><!-- .pp-columns-wrapper -->
243
- </form>
244
-
245
- <script type="text/javascript">
246
- /* <![CDATA[ */
247
- jQuery(document).ready(function($) {
248
-
249
- // -------------------------------------------------------------
250
- // reload page for instant reflection if user is updating own role
251
- // -------------------------------------------------------------
252
- <?php if(!empty($ppc_page_reload) && (int)$ppc_page_reload === 1){ ?>
253
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=' . $default_role . '')); ?>'
254
- <?php } ?>
255
-
256
- // -------------------------------------------------------------
257
- // Set form action attribute to include role
258
- // -------------------------------------------------------------
259
- $('#ppc-admin-features-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=' . $default_role . '')); ?>')
260
-
261
- // -------------------------------------------------------------
262
- // Instant restricted item class
263
- // -------------------------------------------------------------
264
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function() {
265
-
266
- if ($(this).is(':checked')) {
267
- //add class if value is checked
268
- $(this).closest('tr').find('.menu-item-link').addClass('restricted')
269
-
270
- //toggle all checkbox
271
- if ($(this).hasClass('check-all-menu-item')) {
272
- $("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', true)
273
- $('.menu-item-link').addClass('restricted')
274
- } else {
275
- $('.check-all-menu-link').removeClass('restricted')
276
- $('.check-all-menu-item').prop('checked', false)
277
- }
278
-
279
- } else {
280
- //unchecked value
281
- $(this).closest('tr').find('.menu-item-link').removeClass('restricted')
282
-
283
- //toggle all checkbox
284
- if ($(this).hasClass('check-all-menu-item')) {
285
- $("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', false)
286
- $('.menu-item-link').removeClass('restricted')
287
- } else {
288
- $('.check-all-menu-link').removeClass('restricted')
289
- $('.check-all-menu-item').prop('checked', false)
290
- }
291
-
292
- }
293
-
294
- })
295
-
296
- // -------------------------------------------------------------
297
- // Load selected roles menu
298
- // -------------------------------------------------------------
299
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-admin-features-role', function() {
300
-
301
- //disable select
302
- $('.pp-capability-menus-wrapper .ppc-admin-features-role').attr('disabled', true)
303
-
304
- //hide button
305
- $('.pp-capability-menus-wrapper .ppc-admin-features-submit').hide()
306
-
307
- //show loading
308
- $('#pp-capability-menu-wrapper').hide()
309
- $('div.publishpress-caps-manage img.loading').show()
310
-
311
- //go to url
312
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=')); ?>' + $(this).val() + ''
313
-
314
- })
315
-
316
- // -------------------------------------------------------------
317
- // Admin Toolbar Check
318
- // -------------------------------------------------------------
319
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row.parent-menu.admintoolbar .check-item', function() {
320
-
321
- if ($(this).is(':checked')) {
322
- //add class if value is checked
323
- $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').addClass('restricted')
324
-
325
- //toggle all checkbox
326
- $('.ppc-menu-row.child-menu.admintoolbar').find("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', true)
327
- $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').addClass('restricted')
328
-
329
- } else {
330
- //unchecked value
331
- $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').removeClass('restricted')
332
-
333
- //toggle all checkbox
334
- $('.ppc-menu-row.child-menu.admintoolbar').find("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', false)
335
- $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').removeClass('restricted')
336
-
337
- }
338
-
339
- })
340
- })
341
- /* ]]> */
342
- </script>
343
-
344
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
345
- cme_publishpressFooter();
346
- }
347
- ?>
348
- </div>
349
- <?php
1
+ <?php
2
+ /**
3
+ * Capability Manager Admin Features.
4
+ * Hide and block selected Admin Features like toolbar, dashboard widgets etc per-role.
5
+ *
6
+ * Copyright 2020, PublishPress <help@publishpress.com>
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * version 2 as published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+ require_once(dirname(CME_FILE) . '/includes/features/restrict-admin-features.php');
22
+
23
+ global $capsman;
24
+
25
+ $roles = $capsman->roles;
26
+ $default_role = $capsman->get_last_role();
27
+
28
+
29
+ $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
30
+ $disabled_admin_items = array_key_exists($default_role, $disabled_admin_items) ? (array)$disabled_admin_items[$default_role] : [];
31
+
32
+ $admin_features_elements = PP_Capabilities_Admin_Features::elementsLayout();
33
+ ?>
34
+
35
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper">
36
+ <div id="icon-capsman-admin" class="icon32"></div>
37
+ <h2><?php esc_html_e('Admin Feature Restrictions', 'capabilities-pro'); ?></h2>
38
+
39
+ <form method="post" id="ppc-admin-features-form" action="admin.php?page=pp-capabilities-admin-features">
40
+ <?php wp_nonce_field('pp-capabilities-admin-features'); ?>
41
+
42
+ <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
43
+ <div class="pp-column-left">
44
+ <fieldset>
45
+ <table id="akmin">
46
+ <tr>
47
+ <td class="content">
48
+
49
+ <div class="publishpress-headline">
50
+ <span class="cme-subtext">
51
+ <span class='pp-capability-role-caption'>
52
+ <?php
53
+ esc_html_e('Note: You are only restricting access to admin features screens. Some plugins may also add features to other areas of WordPress.',
54
+ 'capabilities-pro');
55
+ ?>
56
+ </span>
57
+ </span>
58
+ </div>
59
+ <div class="publishpress-filters">
60
+ <select name="ppc-admin-features-role" class="ppc-admin-features-role">
61
+ <?php
62
+ foreach ($roles as $role_name => $name) :
63
+ $name = translate_user_role($name);
64
+ ?>
65
+ <option value="<?php echo esc_attr($role_name); ?>" <?php selected($default_role,
66
+ $role_name); ?>><?php echo esc_html($name); ?></option>
67
+ <?php
68
+ endforeach;
69
+ ?>
70
+ </select> &nbsp;
71
+
72
+ <img class="loading" src="<?php echo esc_url_raw($capsman->mod_url); ?>/images/wpspin_light.gif"
73
+ style="display: none">
74
+
75
+ <input type="submit" name="admin-features-submit"
76
+ value="<?php esc_attr_e('Save Changes', 'capabilities-pro') ?>"
77
+ class="button-primary ppc-admin-features-submit" style="float:right"/>
78
+ </div>
79
+
80
+ <div id="pp-capability-menu-wrapper" class="postbox">
81
+ <div class="pp-capability-menus">
82
+
83
+ <div class="pp-capability-menus-wrap">
84
+ <div id="pp-capability-menus-general"
85
+ class="pp-capability-menus-content editable-role" style="display: block;">
86
+
87
+ <table
88
+ class="wp-list-table widefat striped pp-capability-menus-select">
89
+
90
+ <tfoot>
91
+ <tr class="ppc-menu-row parent-menu">
92
+
93
+ <td class="restrict-column ppc-menu-checkbox">
94
+ <input id="check-all-item-2"
95
+ class="check-item check-all-menu-item" type="checkbox"/>
96
+ </td>
97
+ <td class="menu-column ppc-menu-item">
98
+ </td>
99
+
100
+ </tr>
101
+ </tfoot>
102
+
103
+ <tbody>
104
+
105
+ <?php
106
+ $icon_list = (array)PP_Capabilities_Admin_Features::elementLayoutItemIcons();
107
+
108
+ $sn = 0;
109
+ foreach ($admin_features_elements as $section_title => $section_elements) :
110
+ $sn++;
111
+ $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
112
+ $icon_name = isset($icon_list[$section_slug]) ? $icon_list[$section_slug] : '&mdash;';
113
+ ?>
114
+
115
+ <tr class="ppc-menu-row parent-menu <?php echo esc_attr($section_slug); ?>">
116
+ <?php if ($section_slug === 'admintoolbar') :
117
+ $restrict_value = 'ppc_adminbar||admintoolbar';
118
+ ?>
119
+ <td class="features-section-header restrict-column ppc-menu-checkbox" style="text-align: left;" colspan="2">
120
+ <input
121
+ id="check-item-<?php echo (int) $sn; ?>"
122
+ class="check-item" type="checkbox"
123
+ name="capsman_disabled_admin_features[]"
124
+ value="<?php echo esc_attr($restrict_value); ?>"
125
+ <?php echo (in_array($restrict_value, $disabled_admin_items)) ? 'checked' : ''; ?>/>
126
+ <label for="check-item-<?php echo (int) $sn; ?>">
127
+ <strong class="menu-column ppc-menu-item menu-item-link<?php echo (in_array($restrict_value,
128
+ $disabled_admin_items)) ? ' restricted' : ''; ?>">
129
+ <i class="dashicons dashicons-<?php echo esc_attr($icon_name) ?>"></i> <?php echo esc_html($section_title); ?>
130
+ </strong>
131
+ </label>
132
+ </td>
133
+ <?php else : ?>
134
+ <td class="features-section-header" colspan="2">
135
+ <strong><i
136
+ class="dashicons dashicons-<?php echo esc_attr($icon_name) ?>"></i> <?php echo esc_html($section_title); ?>
137
+ </strong>
138
+ </td>
139
+ <?php endif; ?>
140
+
141
+ </tr>
142
+
143
+ <?php
144
+ foreach ($section_elements as $section_id => $section_array) :
145
+ $sn++;
146
+ if (!$section_id) {
147
+ continue;
148
+ }
149
+ $item_name = $section_array['label'];
150
+ $item_action = $section_array['action'];
151
+ $restrict_value = $item_action.'||'.$section_id;
152
+ if($item_action === 'ppc_dashboard_widget'){
153
+ $restrict_value .= '||'.$section_array['context'];
154
+ }
155
+ ?>
156
+
157
+ <tr class="ppc-menu-row child-menu <?php echo esc_attr($section_slug); ?>">
158
+
159
+ <td class="restrict-column ppc-menu-checkbox">
160
+ <input
161
+ id="check-item-<?php echo (int) $sn; ?>"
162
+ class="check-item" type="checkbox"
163
+ name="capsman_disabled_admin_features[]"
164
+ value="<?php echo esc_attr($restrict_value); ?>"
165
+ <?php echo (in_array($restrict_value, $disabled_admin_items)) ? 'checked' : ''; ?>/>
166
+ </td>
167
+ <td class="menu-column ppc-menu-item">
168
+
169
+ <label for="check-item-<?php echo (int) $sn; ?>">
170
+ <span
171
+ class="menu-item-link<?php echo (in_array($restrict_value,
172
+ $disabled_admin_items)) ? ' restricted' : ''; ?>">
173
+ <strong>
174
+ <?php
175
+ if ((isset($section_array['step']) && $section_array['step'] > 0) && isset($section_array['parent']) && !empty($section_array['parent'])) {
176
+ $step_margin = $section_array['step'] * 20;
177
+ echo '<span style="margin-left: ' . (int) $step_margin . 'px;"></span>';
178
+ echo ' &mdash; ';
179
+ } else {
180
+ if (isset($icon_list[$section_id])) {
181
+ echo '<i class="dashicons dashicons-' . esc_attr($icon_list[$section_id]) . '"></i>';
182
+ } else {
183
+ echo '&mdash;';
184
+ }
185
+ }
186
+ ?>
187
+ <?php
188
+ if(isset($section_array['custom_element']) && ($section_array['custom_element'] === true)){
189
+ echo esc_html($section_array['element_label']) . ' <small class="entry">(' . esc_html($section_array['element_items']). ')</small> &nbsp; '
190
+ . '<span class="' . esc_attr($section_array['button_class']) . '" data-id="' . esc_attr($section_array['button_data_id']) . '"><small>(' . esc_html__('Delete', 'capabilities-pro') . ')</small></span>' . '';
191
+ }else{
192
+ echo esc_html($item_name);
193
+ }
194
+ ?>
195
+ </strong></span>
196
+ </label>
197
+ </td>
198
+
199
+ </tr>
200
+
201
+ <?php
202
+ endforeach; // $section_elements subsection loop
203
+ endforeach; // $admin_features_elements section loop
204
+ ?>
205
+ <?php do_action('pp_capabilities_admin_features_after_table_tr'); ?>
206
+ </tbody>
207
+ </table>
208
+ <?php do_action('pp_capabilities_admin_features_after_table'); ?>
209
+ </div>
210
+
211
+ </div>
212
+ </div>
213
+ </div>
214
+ <input type="submit" name="admin-features-submit"
215
+ value="<?php esc_attr_e('Save Changes', 'capabilities-pro') ?>"
216
+ class="button-primary ppc-admin-features-submit"/>
217
+ </td>
218
+ </tr>
219
+ </table>
220
+
221
+ </fieldset>
222
+ </div><!-- .pp-column-left -->
223
+ <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED) { ?>
224
+ <div class="pp-column-right">
225
+ <?php
226
+ $banners = new PublishPress\WordPressBanners\BannersMain;
227
+ $banners->pp_display_banner(
228
+ esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
229
+ esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
230
+ array(
231
+ esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
232
+ esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
233
+ esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
234
+ ),
235
+ admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
236
+ esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
237
+ 'install-permissions.jpg'
238
+ );
239
+ ?>
240
+ </div><!-- .pp-column-right -->
241
+ <?php } ?>
242
+ </div><!-- .pp-columns-wrapper -->
243
+ </form>
244
+
245
+ <script type="text/javascript">
246
+ /* <![CDATA[ */
247
+ jQuery(document).ready(function($) {
248
+
249
+ // -------------------------------------------------------------
250
+ // reload page for instant reflection if user is updating own role
251
+ // -------------------------------------------------------------
252
+ <?php if(!empty($ppc_page_reload) && (int)$ppc_page_reload === 1){ ?>
253
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=' . $default_role . '')); ?>'
254
+ <?php } ?>
255
+
256
+ // -------------------------------------------------------------
257
+ // Set form action attribute to include role
258
+ // -------------------------------------------------------------
259
+ $('#ppc-admin-features-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=' . $default_role . '')); ?>')
260
+
261
+ // -------------------------------------------------------------
262
+ // Instant restricted item class
263
+ // -------------------------------------------------------------
264
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function() {
265
+
266
+ if ($(this).is(':checked')) {
267
+ //add class if value is checked
268
+ $(this).closest('tr').find('.menu-item-link').addClass('restricted')
269
+
270
+ //toggle all checkbox
271
+ if ($(this).hasClass('check-all-menu-item')) {
272
+ $("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', true)
273
+ $('.menu-item-link').addClass('restricted')
274
+ } else {
275
+ $('.check-all-menu-link').removeClass('restricted')
276
+ $('.check-all-menu-item').prop('checked', false)
277
+ }
278
+
279
+ } else {
280
+ //unchecked value
281
+ $(this).closest('tr').find('.menu-item-link').removeClass('restricted')
282
+
283
+ //toggle all checkbox
284
+ if ($(this).hasClass('check-all-menu-item')) {
285
+ $("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', false)
286
+ $('.menu-item-link').removeClass('restricted')
287
+ } else {
288
+ $('.check-all-menu-link').removeClass('restricted')
289
+ $('.check-all-menu-item').prop('checked', false)
290
+ }
291
+
292
+ }
293
+
294
+ })
295
+
296
+ // -------------------------------------------------------------
297
+ // Load selected roles menu
298
+ // -------------------------------------------------------------
299
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-admin-features-role', function() {
300
+
301
+ //disable select
302
+ $('.pp-capability-menus-wrapper .ppc-admin-features-role').attr('disabled', true)
303
+
304
+ //hide button
305
+ $('.pp-capability-menus-wrapper .ppc-admin-features-submit').hide()
306
+
307
+ //show loading
308
+ $('#pp-capability-menu-wrapper').hide()
309
+ $('div.publishpress-caps-manage img.loading').show()
310
+
311
+ //go to url
312
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-admin-features&role=')); ?>' + $(this).val() + ''
313
+
314
+ })
315
+
316
+ // -------------------------------------------------------------
317
+ // Admin Toolbar Check
318
+ // -------------------------------------------------------------
319
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row.parent-menu.admintoolbar .check-item', function() {
320
+
321
+ if ($(this).is(':checked')) {
322
+ //add class if value is checked
323
+ $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').addClass('restricted')
324
+
325
+ //toggle all checkbox
326
+ $('.ppc-menu-row.child-menu.admintoolbar').find("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', true)
327
+ $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').addClass('restricted')
328
+
329
+ } else {
330
+ //unchecked value
331
+ $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').removeClass('restricted')
332
+
333
+ //toggle all checkbox
334
+ $('.ppc-menu-row.child-menu.admintoolbar').find("input[type='checkbox'][name='capsman_disabled_admin_features[]']").prop('checked', false)
335
+ $('.ppc-menu-row.child-menu.admintoolbar').find('.menu-item-link').removeClass('restricted')
336
+
337
+ }
338
+
339
+ })
340
+ })
341
+ /* ]]> */
342
+ </script>
343
+
344
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
345
+ cme_publishpressFooter();
346
+ }
347
+ ?>
348
+ </div>
349
+ <?php
includes/features/editor-features-classic.php CHANGED
@@ -1,107 +1,76 @@
1
- <?php
2
- $ce_elements = PP_Capabilities_Post_Features::elementsLayoutClassic();
3
-
4
- $ce_post_disabled = [];
5
-
6
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
7
-
8
- asort($def_post_types);
9
-
10
- $types_limit = (defined('PP_CAPABILITIES_EDITOR_FEATURES_MAX_TYPES')) ? PP_CAPABILITIES_EDITOR_FEATURES_MAX_TYPES : 12;
11
-
12
- if (count($def_post_types) > $types_limit ) {
13
- ?>
14
- <style type="text/css">
15
- .pp-columns-wrapper.pp-enable-sidebar .pp-column-left {width: 100% !important;}
16
- .pp-columns-wrapper.pp-enable-sidebar .pp-column-left, .pp-columns-wrapper.pp-enable-sidebar .pp-column-right {float: none !important;}
17
- </style>
18
- <?php
19
- }
20
-
21
- foreach($def_post_types as $type_name) {
22
- $_disabled = get_option("capsman_feature_restrict_classic_{$type_name}", []);
23
- $ce_post_disabled[$type_name] = !empty($_disabled[$default_role]) ? (array)$_disabled[$default_role] : [];
24
- }
25
- ?>
26
-
27
- <table class="wp-list-table widefat fixed striped pp-capability-menus-select editor-features-classic" <?php if (empty($_REQUEST['ppc-tab']) || ('classic' != $_REQUEST['ppc-tab'])) echo 'style="display:none;"';?>>
28
- <?php foreach(['thead', 'tfoot'] as $tag_name):?>
29
- <<?php echo esc_attr($tag_name);?>>
30
- <tr>
31
- <th class="menu-column"><?php if ('thead' == $tag_name || !defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {esc_html_e('Classic Editor Screen', 'capsman-enhanced');}?></th>
32
-
33
- <?php foreach($def_post_types as $type_name) :
34
- $type_obj = get_post_type_object($type_name);
35
- ?>
36
- <th class="restrict-column ppc-menu-row"><?php printf(esc_html__('%s Restrict', 'capsman-enhanced'), esc_html($type_obj->labels->singular_name));?><br />
37
- <input class="check-item classic check-all-menu-item" type="checkbox" title="<?php esc_attr_e('Toggle all', 'capsman-enhanced');?>" data-pp_type="<?php echo esc_attr($type_name);?>" />
38
- </th>
39
- <?php endforeach;?>
40
- </tr>
41
- </<?php echo esc_attr($tag_name);?>>
42
- <?php endforeach;?>
43
-
44
- <tbody>
45
- <?php
46
- foreach ($ce_elements as $section_title => $arr) {
47
- $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
48
- ?>
49
- <tr class="ppc-menu-row parent-menu">
50
- <td colspan="<?php echo (count($def_post_types) + 1);?>">
51
- <h4 class="ppc-menu-row-section"><?php echo esc_html($section_title);?></h4>
52
- <?php
53
- /**
54
- * Add support for section description
55
- *
56
- * @param array $def_post_types Post type.
57
- * @param array $ce_elements All classic editor elements.
58
- * @param array $ce_post_disabled All classic editor disabled post type element.
59
- *
60
- * @since 2.1.1
61
- */
62
- do_action( "pp_capabilities_feature_classic_{$section_slug}_section", $def_post_types, $ce_elements, $ce_post_disabled );
63
- ?>
64
- </td>
65
- </tr>
66
-
67
- <?php
68
- foreach ($arr as $feature_slug => $arr_feature) {
69
- if (!$feature_slug) {
70
- continue;
71
- }
72
- ?>
73
- <tr class="ppc-menu-row parent-menu">
74
- <td class="menu-column ppc-menu-item">
75
- <span class="classic menu-item-link<?php echo (in_array($feature_slug, $ce_post_disabled['post'])) ? ' restricted' : ''; ?>">
76
- <strong><i class="dashicons dashicons-arrow-right"></i>
77
- <?php
78
- if(isset($arr_feature['custom_element']) && ($arr_feature['custom_element'] === true)){
79
- echo esc_html($arr_feature['element_label']) . ' <small class="entry">(' . esc_html($arr_feature['element_items']). ')</small> &nbsp; '
80
- . '<span class="' . esc_attr($arr_feature['button_class']) . '" data-id="' . esc_attr($arr_feature['button_data_id']) . '" data-parent="' . esc_attr($arr_feature['button_data_parent']) . '"><small>(' . esc_html__('Delete', 'capsman-enhanced') . ')</small></span>';
81
- }else{
82
- echo esc_html($arr_feature['label']);
83
- }
84
- ?>
85
- </strong></span>
86
- </td>
87
-
88
- <?php foreach($def_post_types as $type_name) :?>
89
- <td class="restrict-column ppc-menu-checkbox">
90
- <input id="cb_<?php echo esc_attr($type_name) . '-' . esc_attr(str_replace(['#', '.'], '_', $feature_slug));?>" class="check-item" type="checkbox"
91
- name="capsman_feature_restrict_classic_<?php echo esc_attr($type_name);?>[]"
92
- value="<?php echo esc_attr($feature_slug); ?>" <?php checked(in_array($feature_slug, $ce_post_disabled[$type_name]));?> />
93
- </td>
94
- <?php endforeach;?>
95
- </tr>
96
- <?php
97
- }
98
- }
99
-
100
- do_action('pp_capabilities_features_classic_after_table_tr');
101
- ?>
102
-
103
- </tbody>
104
- </table>
105
-
106
- <?php
107
- do_action('pp_capabilities_features_classic_after_table');
1
+ <h3 class="editor-features-classic-show" <?php if (empty($_REQUEST['ppc-tab']) || (!empty($_REQUEST['ppc-tab']) && ('classic' != $_REQUEST['ppc-tab']))) echo 'style="display:none;"';?> data-post_type="<?php echo esc_attr($type_obj->name); ?>"><?php echo sprintf( esc_html__('Classic Editor %s Restriction', 'capsman-enhanced'), esc_html__($type_obj->labels->singular_name)); ?></h3>
2
+ <table class="wp-list-table widefat fixed striped pp-capability-menus-select editor-features-classic" <?php if (empty($_REQUEST['ppc-tab']) || ('classic' != $_REQUEST['ppc-tab'])) echo 'style="display:none;"';?> data-post_type="<?php echo esc_attr($type_obj->name); ?>">
3
+ <?php foreach(['thead', 'tfoot'] as $tag_name):?>
4
+ <<?php echo esc_attr($tag_name);?>>
5
+ <tr>
6
+ <th class="menu-column"></th>
7
+
8
+ <th class="restrict-column ppc-menu-row">
9
+ <input class="check-item gutenberg check-all-menu-item" type="checkbox" data-pp_type="<?php echo esc_attr($type_obj->name);?>" />
10
+ </th>
11
+ </tr>
12
+ </<?php echo esc_attr($tag_name);?>>
13
+ <?php endforeach;?>
14
+
15
+ <tbody>
16
+ <?php
17
+ foreach ($ce_elements as $section_title => $arr) {
18
+ $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
19
+ ?>
20
+ <tr class="ppc-menu-row parent-menu">
21
+ <td colspan="2">
22
+ <h4 class="ppc-menu-row-section"><?php echo esc_html($section_title);?></h4>
23
+ <?php
24
+ /**
25
+ * Add support for section description
26
+ *
27
+ * @param array $def_post_types Post type.
28
+ * @param array $ce_elements All classic editor elements.
29
+ * @param array $ce_post_disabled All classic editor disabled post type element.
30
+ *
31
+ * @since 2.1.1
32
+ */
33
+ do_action( "pp_capabilities_feature_classic_{$section_slug}_section", $def_post_types, $ce_elements, $ce_post_disabled );
34
+ ?>
35
+ </td>
36
+ </tr>
37
+
38
+ <?php
39
+ foreach ($arr as $feature_slug => $arr_feature) {
40
+ if (!$feature_slug) {
41
+ continue;
42
+ }
43
+ ?>
44
+ <tr class="ppc-menu-row parent-menu">
45
+ <td class="menu-column ppc-menu-item">
46
+ <span class="classic menu-item-link<?php echo (in_array($feature_slug, $ce_post_disabled[$type_obj->name])) ? ' restricted' : ''; ?>">
47
+ <strong><i class="dashicons dashicons-arrow-right"></i>
48
+ <?php
49
+ if(isset($arr_feature['custom_element']) && ($arr_feature['custom_element'] === true)){
50
+ echo esc_html($arr_feature['element_label']) . ' <small class="entry">(' . esc_html($arr_feature['element_items']). ')</small> &nbsp; '
51
+ . '<span class="' . esc_attr($arr_feature['button_class']) . '" data-id="' . esc_attr($arr_feature['button_data_id']) . '" data-parent="' . esc_attr($arr_feature['button_data_parent']) . '"><small>(' . esc_html__('Delete', 'capsman-enhanced') . ')</small></span>';
52
+ }else{
53
+ echo esc_html($arr_feature['label']);
54
+ }
55
+ ?>
56
+ </strong></span>
57
+ </td>
58
+
59
+ <td class="restrict-column ppc-menu-checkbox">
60
+ <input id="cb_<?php echo esc_attr($type_obj->name) . '-' . esc_attr(str_replace(['#', '.'], '_', $feature_slug));?>" class="check-item" type="checkbox"
61
+ name="capsman_feature_restrict_classic_<?php echo esc_attr($type_obj->name);?>[]"
62
+ value="<?php echo esc_attr($feature_slug); ?>" <?php checked(in_array($feature_slug, $ce_post_disabled[$type_obj->name]));?> />
63
+ </td>
64
+ </tr>
65
+ <?php
66
+ }
67
+ }
68
+
69
+ do_action('pp_capabilities_features_classic_after_table_tr');
70
+ ?>
71
+
72
+ </tbody>
73
+ </table>
74
+
75
+ <?php
76
+ do_action('pp_capabilities_features_classic_after_table');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/features/editor-features-gutenberg.php CHANGED
@@ -1,106 +1,75 @@
1
- <?php
2
- $gutenberg_elements = PP_Capabilities_Post_Features::elementsLayout();
3
-
4
- $gutenberg_post_disabled = [];
5
-
6
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
7
-
8
- asort($def_post_types);
9
-
10
- $types_limit = (defined('PP_CAPABILITIES_EDITOR_FEATURES_MAX_TYPES')) ? PP_CAPABILITIES_EDITOR_FEATURES_MAX_TYPES : 12;
11
-
12
- if (count($def_post_types) > $types_limit ) {
13
- ?>
14
- <style type="text/css">
15
- .pp-columns-wrapper.pp-enable-sidebar .pp-column-left {width: 100% !important;}
16
- .pp-columns-wrapper.pp-enable-sidebar .pp-column-left, .pp-columns-wrapper.pp-enable-sidebar .pp-column-right {float: none !important;}
17
- </style>
18
- <?php
19
- }
20
-
21
- foreach($def_post_types as $type_name) {
22
- $_disabled = get_option("capsman_feature_restrict_{$type_name}", []);
23
- $gutenberg_post_disabled[$type_name] = !empty($_disabled[$default_role]) ? (array)$_disabled[$default_role] : [];
24
- }
25
- ?>
26
-
27
- <table class="wp-list-table widefat fixed striped pp-capability-menus-select editor-features-gutenberg" <?php if (!empty($_REQUEST['ppc-tab']) && ('gutenberg' != $_REQUEST['ppc-tab'])) echo 'style="display:none;"';?>>
28
- <?php foreach(['thead', 'tfoot'] as $tag_name):?>
29
- <<?php echo esc_attr($tag_name);?>>
30
- <tr>
31
- <th class="menu-column"><?php if ('thead' == $tag_name) {esc_html_e('Gutenberg Screen', 'capsman-enhanced');}?></th>
32
-
33
- <?php foreach($def_post_types as $type_name) :
34
- $type_obj = get_post_type_object($type_name);
35
- ?>
36
- <th class="restrict-column ppc-menu-row"><?php printf(esc_html__('%s Restrict', 'capsman-enhanced'), esc_html($type_obj->labels->singular_name));?><br />
37
- <input class="check-item gutenberg check-all-menu-item" type="checkbox" title="<?php esc_attr_e('Toggle all', 'capsman-enhanced');?>" data-pp_type="<?php echo esc_attr($type_name);?>" />
38
- </th>
39
- <?php endforeach;?>
40
- </tr>
41
- </<?php echo esc_attr($tag_name);?>>
42
- <?php endforeach;?>
43
-
44
- <tbody>
45
- <?php
46
- foreach ($gutenberg_elements as $section_title => $arr) {
47
- $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
48
- ?>
49
- <tr class="ppc-menu-row parent-menu">
50
- <td colspan="<?php echo (count($def_post_types) + 1);?>">
51
- <h4 class="ppc-menu-row-section"><?php echo esc_html($section_title);?></h4>
52
- <?php
53
- /**
54
- * Add support for section description
55
- *
56
- * @param array $def_post_types Post type.
57
- * @param array $gutenberg_elements All gutenberg elements.
58
- * @param array $gutenberg_post_disabled All gutenberg disabled post type element.
59
- *
60
- * @since 2.1.1
61
- */
62
- do_action( "pp_capabilities_feature_gutenberg_{$section_slug}_section", $def_post_types, $gutenberg_elements, $gutenberg_post_disabled );
63
- ?>
64
- </td>
65
- </tr>
66
-
67
- <?php
68
- foreach ($arr as $feature_slug => $arr_feature) {
69
- $feature_slug = esc_attr($feature_slug);
70
-
71
- ?>
72
- <tr class="ppc-menu-row parent-menu">
73
- <td class="menu-column ppc-menu-item">
74
- <span class="gutenberg menu-item-link<?php checked(in_array($feature_slug, $gutenberg_post_disabled['post']), true, 'restricted');?>">
75
- <strong><i class="dashicons dashicons-arrow-right"></i>
76
- <?php
77
- if(isset($arr_feature['custom_element']) && ($arr_feature['custom_element'] === true)){
78
- echo esc_html($arr_feature['element_label']) . ' <small class="entry">(' . esc_html($arr_feature['element_items']). ')</small> &nbsp; '
79
- . '<span class="' . esc_attr($arr_feature['button_class']) . '" data-id="' . esc_attr($arr_feature['button_data_id']) . '" data-parent="' . esc_attr($arr_feature['button_data_parent']) . '"><small>(' . esc_html__('Delete', 'capsman-enhanced') . ')</small></span>';
80
- }else{
81
- echo esc_html($arr_feature['label']);
82
- }
83
- ?>
84
- </strong></span>
85
- </td>
86
-
87
- <?php foreach($def_post_types as $type_name) :?>
88
- <td class="restrict-column ppc-menu-checkbox">
89
- <input id="check-item-<?php echo esc_attr($type_name) . '-' . esc_attr($feature_slug);?>" class="check-item" type="checkbox"
90
- name="capsman_feature_restrict_<?php echo esc_attr($type_name);?>[]"
91
- value="<?php echo esc_attr($feature_slug);?>"<?php checked(in_array($feature_slug, $gutenberg_post_disabled[$type_name]));?> />
92
- </td>
93
- <?php endforeach;?>
94
- </tr>
95
- <?php
96
- }
97
- }
98
-
99
- do_action('pp_capabilities_features_gutenberg_after_table_tr');
100
- ?>
101
-
102
- </tbody>
103
- </table>
104
-
105
- <?php
106
- do_action('pp_capabilities_features_gutenberg_after_table');
1
+ <h3 class="editor-features-gutenberg-show" <?php if (!empty($_REQUEST['ppc-tab']) && ('gutenberg' !== $_REQUEST['ppc-tab'])) echo 'style="display:none;"';?> data-post_type="<?php echo esc_attr($type_obj->name); ?>"><?php echo sprintf( esc_html__('Gutenberg Editor %s Restriction', 'capsman-enhanced'), esc_html__($type_obj->labels->singular_name)); ; ?></h3>
2
+ <table class="wp-list-table widefat fixed striped pp-capability-menus-select editor-features-gutenberg" <?php if (!empty($_REQUEST['ppc-tab']) && ('gutenberg' != $_REQUEST['ppc-tab'])) echo 'style="display:none;"';?> data-post_type="<?php echo esc_attr($type_obj->name); ?>">
3
+ <?php foreach(['thead', 'tfoot'] as $tag_name):?>
4
+ <<?php echo esc_attr($tag_name);?>>
5
+ <tr>
6
+ <th class="menu-column"></th>
7
+
8
+ <th class="restrict-column ppc-menu-row">
9
+ <input class="check-item gutenberg check-all-menu-item" type="checkbox" data-pp_type="<?php echo esc_attr($type_obj->name);?>" />
10
+ </th>
11
+ </tr>
12
+ </<?php echo esc_attr($tag_name);?>>
13
+ <?php endforeach;?>
14
+
15
+ <tbody>
16
+ <?php
17
+ foreach ($gutenberg_elements as $section_title => $arr) {
18
+ $section_slug = strtolower(ppc_remove_non_alphanumeric_space_characters($section_title));
19
+ ?>
20
+ <tr class="ppc-menu-row parent-menu">
21
+ <td colspan="2">
22
+ <h4 class="ppc-menu-row-section"><?php echo esc_html($section_title);?></h4>
23
+ <?php
24
+ /**
25
+ * Add support for section description
26
+ *
27
+ * @param array $def_post_types Post type.
28
+ * @param array $gutenberg_elements All gutenberg elements.
29
+ * @param array $gutenberg_post_disabled All gutenberg disabled post type element.
30
+ *
31
+ * @since 2.1.1
32
+ */
33
+ do_action( "pp_capabilities_feature_gutenberg_{$section_slug}_section", $def_post_types, $gutenberg_elements, $gutenberg_post_disabled );
34
+ ?>
35
+ </td>
36
+ </tr>
37
+
38
+ <?php
39
+ foreach ($arr as $feature_slug => $arr_feature) {
40
+ $feature_slug = esc_attr($feature_slug);
41
+
42
+ ?>
43
+ <tr class="ppc-menu-row parent-menu">
44
+ <td class="menu-column ppc-menu-item">
45
+ <span class="gutenberg menu-item-link<?php echo (in_array($feature_slug, $gutenberg_post_disabled[$type_obj->name])) ? ' restricted' : ''; ?>">
46
+ <strong><i class="dashicons dashicons-arrow-right"></i>
47
+ <?php
48
+ if(isset($arr_feature['custom_element']) && ($arr_feature['custom_element'] === true)){
49
+ echo esc_html($arr_feature['element_label']) . ' <small class="entry">(' . esc_html($arr_feature['element_items']). ')</small> &nbsp; '
50
+ . '<span class="' . esc_attr($arr_feature['button_class']) . '" data-id="' . esc_attr($arr_feature['button_data_id']) . '" data-parent="' . esc_attr($arr_feature['button_data_parent']) . '"><small>(' . esc_html__('Delete', 'capsman-enhanced') . ')</small></span>';
51
+ }else{
52
+ echo esc_html($arr_feature['label']);
53
+ }
54
+ ?>
55
+ </strong></span>
56
+ </td>
57
+
58
+ <td class="restrict-column ppc-menu-checkbox">
59
+ <input id="check-item-<?php echo esc_attr($type_obj->name) . '-' . esc_attr($feature_slug);?>" class="check-item" type="checkbox"
60
+ name="capsman_feature_restrict_<?php echo esc_attr($type_obj->name);?>[]"
61
+ value="<?php echo esc_attr($feature_slug);?>"<?php checked(in_array($feature_slug, $gutenberg_post_disabled[$type_obj->name]));?> />
62
+ </td>
63
+ </tr>
64
+ <?php
65
+ }
66
+ }
67
+
68
+ do_action('pp_capabilities_features_gutenberg_after_table_tr');
69
+ ?>
70
+
71
+ </tbody>
72
+ </table>
73
+
74
+ <?php
75
+ do_action('pp_capabilities_features_gutenberg_after_table');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/features/editor-features.php CHANGED
@@ -1,257 +1,400 @@
1
- <?php
2
- /**
3
- * Capability Manager Edit Posts Permission.
4
- * Edit Posts permission and visibility per roles.
5
- *
6
- * Copyright 2021, PublishPress <help@publishpress.com>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * version 2 as published by the Free Software Foundation.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- */
20
-
21
- require_once (dirname(CME_FILE) . '/includes/features/restrict-editor-features.php');
22
-
23
- global $capsman;
24
- $roles = $capsman->roles;
25
-
26
- $default_role = $capsman->get_last_role();
27
-
28
- $classic_editor = pp_capabilities_is_classic_editor_available();
29
- ?>
30
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper">
31
- <div id="icon-capsman-admin" class="icon32"></div>
32
- <h2><?php esc_html_e('Editor Feature Restriction', 'capsman-enhanced'); ?></h2>
33
-
34
- <form method="post" id="ppc-editor-features-form"
35
- action="admin.php?page=pp-capabilities-editor-features">
36
- <?php wp_nonce_field('pp-capabilities-editor-features'); ?>
37
-
38
- <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
39
- <div class="pp-column-left">
40
- <table id="akmin">
41
- <tr>
42
- <td class="content">
43
-
44
- <div class="publishpress-headline">
45
- <span class="cme-subtext">
46
- <span class='pp-capability-role-caption'>
47
- <?php
48
- esc_html_e('Select editor features to remove. Note that this screen cannot be used to grant additional features to any role.', 'capabilities-pro');
49
- ?>
50
- </span>
51
- </span>
52
- </div>
53
-
54
- <div class="publishpress-filters">
55
- <select name="ppc-editor-features-role" class="ppc-editor-features-role">
56
- <?php
57
- foreach ($roles as $role_name => $name) :
58
- $name = translate_user_role($name);
59
- ?>
60
- <option value="<?php echo esc_attr($role_name);?>" <?php selected($default_role, $role_name);?>><?php echo esc_html($name);?></option>
61
- <?php
62
- endforeach;
63
- ?>
64
- </select> &nbsp;
65
-
66
- <img class="loading" src="<?php echo esc_url_raw($capsman->mod_url); ?>/images/wpspin_light.gif" style="display: none">
67
-
68
- <input type="submit" name="editor-features-submit"
69
- value="<?php esc_attr_e('Save Changes', 'capabilities-pro') ?>"
70
- class="button-primary ppc-editor-features-submit" style="float:right" />
71
-
72
- <input type="hidden" name="ppc-tab" value="<?php echo (!empty($_REQUEST['ppc-tab'])) ? sanitize_key($_REQUEST['ppc-tab']) : 'gutenberg';?>" />
73
- </div>
74
-
75
- <script type="text/javascript">
76
- /* <![CDATA[ */
77
- jQuery(document).ready(function($) {
78
- $('li.gutenberg-tab').click(function() {
79
- $('div.publishpress-filters input[name=ppc-tab]').val('gutenberg');
80
- });
81
-
82
- $('li.classic-tab').click(function() {
83
- $('div.publishpress-filters input[name=ppc-tab]').val('classic');
84
- });
85
- });
86
- /* ]]> */
87
- </script>
88
-
89
- <?php if ($classic_editor) { ?>
90
- <ul class="nav-tab-wrapper">
91
- <li class="editor-features-tab gutenberg-tab nav-tab <?php if (empty($_REQUEST['ppc-tab']) || ('gutenberg' == $_REQUEST['ppc-tab'])) echo 'nav-tab-active';?>"
92
- data-tab=".editor-features-gutenberg"><a href="#"><?php esc_html_e('Gutenberg', 'capsman-enhanced') ?></a></li>
93
-
94
- <li class="editor-features-tab classic-tab nav-tab <?php if (!empty($_REQUEST['ppc-tab']) && ('classic' == $_REQUEST['ppc-tab'])) echo 'nav-tab-active';?>"
95
- data-tab=".editor-features-classic"><a href="#"><?php esc_html_e('Classic', 'capsman-enhanced') ?></a></li>
96
- </ul>
97
- <?php } ?>
98
-
99
- <div id="pp-capability-menu-wrapper" class="postbox">
100
- <div class="pp-capability-menus">
101
-
102
- <div class="pp-capability-menus-wrap">
103
- <div id="pp-capability-menus-general"
104
- class="pp-capability-menus-content editable-role"
105
- style="display: block;">
106
- <?php
107
- $sn = 0;
108
- include(dirname(__FILE__) . '/editor-features-gutenberg.php');
109
-
110
- if ($classic_editor) {
111
- include(dirname(__FILE__) . '/editor-features-classic.php');
112
- }
113
- ?>
114
-
115
- </div>
116
- </div>
117
-
118
- </div>
119
- </div>
120
-
121
- <input type="submit" name="editor-features-submit"
122
- value="<?php esc_attr_e('Save Changes', 'capsman-enhanced') ?>"
123
- class="button-primary ppc-editor-features-submit"/> &nbsp;
124
-
125
-
126
- </td>
127
- </tr>
128
- </table>
129
- </div><!-- .pp-column-left -->
130
- <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED) { ?>
131
- <div class="pp-column-right">
132
- <?php
133
- $banners = new PublishPress\WordPressBanners\BannersMain;
134
- $banners->pp_display_banner(
135
- esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
136
- esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
137
- array(
138
- esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
139
- esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
140
- esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
141
- ),
142
- admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
143
- esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
144
- 'install-permissions.jpg'
145
- );
146
- ?>
147
- </div><!-- .pp-column-right -->
148
- <?php } ?>
149
- </div><!-- .pp-columns-wrapper -->
150
- </form>
151
-
152
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
153
- cme_publishpressFooter();
154
- }
155
- ?>
156
- </div>
157
-
158
- <style>
159
- span.menu-item-link {
160
- webkit-user-select: none; /* Safari */
161
- -moz-user-select: none; /* Firefox */
162
- -ms-user-select: none; /* IE10+/Edge */
163
- user-select: none; /* Standard */
164
- }
165
-
166
- input.check-all-menu-item {margin-top: 5px !important;}
167
- </style>
168
-
169
- <script type="text/javascript">
170
- /* <![CDATA[ */
171
- jQuery(document).ready(function ($) {
172
-
173
- // -------------------------------------------------------------
174
- // Set form action attribute to include role
175
- // -------------------------------------------------------------
176
- $('#ppc-editor-features-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-editor-features&role=' . $default_role . '')); ?>');
177
-
178
- // -------------------------------------------------------------
179
- // Instant restricted item class
180
- // -------------------------------------------------------------
181
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function () {
182
- var current_tab;
183
-
184
- <?php if ($classic_editor) { ?>
185
- if ($('.nav-tab-wrapper .classic-tab').hasClass('nav-tab-active')) {
186
- current_tab = 'classic';
187
- } else {
188
- current_tab = 'gutenberg';
189
- }
190
- <?php } else { ?>
191
- current_tab = 'gutenberg';
192
- <?php } ?>
193
-
194
- //add class if feature is restricted for any post type
195
- var anyRestricted = $(this).closest('tr').find('input:checked').length > 0;
196
- $(this).closest('tr').find('.menu-item-link').toggleClass('restricted', anyRestricted);
197
-
198
- var isChecked = $(this).is(':checked');
199
-
200
- //toggle all checkbox
201
- if ($(this).hasClass('check-all-menu-item')) {
202
- var suffix = ('gutenberg' == current_tab) ? '' : current_tab + '_';
203
- $("input[type='checkbox'][name='capsman_feature_restrict_" + suffix + $(this).data('pp_type') + "[]']").prop('checked', isChecked);
204
-
205
- $('.' + current_tab + '.menu-item-link').each(function(i,e) {
206
- $(this).toggleClass('restricted', $(this).closest('tr').find('input:checked').length > 0);
207
- });
208
- } else {
209
- $('.' + current_tab + '.check-all-menu-link').removeClass('restricted').prop('checked', false);
210
- }
211
- });
212
-
213
- $(document).on("click", "span.menu-item-link", function (e) {
214
- if($(e.target).parent().hasClass('ppc-custom-features-delete')){
215
- return;
216
- }
217
- var chks = $(this).closest('tr').find('input');
218
- $(chks).prop('checked', !$(this).hasClass('restricted'));
219
- $(this).toggleClass('restricted', $(chks).filter(':checked').length);
220
- });
221
-
222
- // -------------------------------------------------------------
223
- // Load selected roles menu
224
- // -------------------------------------------------------------
225
- $(document).on('change', '.pp-capability-menus-wrapper .ppc-editor-features-role', function () {
226
-
227
- //disable select
228
- $('.pp-capability-menus-wrapper .ppc-editor-features-role').attr('disabled', true);
229
-
230
- //hide button
231
- $('.pp-capability-menus-wrapper .ppc-editor-features-submit').hide();
232
-
233
- //show loading
234
- $('#pp-capability-menu-wrapper').hide();
235
- $('div.publishpress-caps-manage img.loading').show();
236
-
237
- //go to url
238
- window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-editor-features&role=')); ?>' + $(this).val() + '';
239
-
240
- });
241
-
242
-
243
- // -------------------------------------------------------------
244
- // Editor features tab
245
- // -------------------------------------------------------------
246
- $('.editor-features-tab').click(function (e) {
247
- e.preventDefault();
248
- $('.editor-features-tab').removeClass('nav-tab-active');
249
- $(this).addClass('nav-tab-active');
250
- $('.pp-capability-menus-select').hide();
251
- $($(this).attr('data-tab')).show();
252
- });
253
-
254
- });
255
- /* ]]> */
256
- </script>
257
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Capability Manager Edit Posts Permission.
4
+ * Edit Posts permission and visibility per roles.
5
+ *
6
+ * Copyright 2021, PublishPress <help@publishpress.com>
7
+ *
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * version 2 as published by the Free Software Foundation.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ */
20
+
21
+ require_once (dirname(CME_FILE) . '/includes/features/restrict-editor-features.php');
22
+
23
+ global $capsman;
24
+ $roles = $capsman->roles;
25
+
26
+ $default_role = $capsman->get_last_role();
27
+
28
+ $classic_editor = pp_capabilities_is_classic_editor_available();
29
+
30
+ $def_post_types = apply_filters('pp_capabilities_feature_post_types', []);
31
+ asort($def_post_types);
32
+ $def_post_types = array_unique(array_merge(['post', 'page'], $def_post_types));
33
+
34
+ //gutenberg element
35
+ $gutenberg_elements = PP_Capabilities_Post_Features::elementsLayout();
36
+ $gutenberg_post_disabled = [];
37
+ $ce_post_disabled = [];
38
+
39
+ //classic editor element
40
+ if ($classic_editor) {
41
+ $ce_elements = PP_Capabilities_Post_Features::elementsLayoutClassic();
42
+ }
43
+
44
+ foreach($def_post_types as $type_name) {
45
+
46
+ $_disabled = get_option("capsman_feature_restrict_{$type_name}", []);
47
+ $gutenberg_post_disabled[$type_name] = !empty($_disabled[$default_role]) ? (array)$_disabled[$default_role] : [];
48
+
49
+ //classic editor cpt disabled element
50
+ if ($classic_editor) {
51
+ $_disabled = get_option("capsman_feature_restrict_classic_{$type_name}", []);
52
+ $ce_post_disabled[$type_name] = !empty($_disabled[$default_role]) ? (array)$_disabled[$default_role] : [];
53
+ }
54
+ }
55
+
56
+ $active_tab_slug = (!empty($_REQUEST['pp_caps_tab'])) ? sanitize_key($_REQUEST['pp_caps_tab']) : 'post';
57
+
58
+ $active_tab_type_obj = get_post_type_object($active_tab_slug);
59
+
60
+ $active_tab_text = is_object($active_tab_type_obj)
61
+ && isset($active_tab_type_obj->labels)
62
+ && isset($active_tab_type_obj->labels->singular_name)
63
+ ?
64
+ $active_tab_type_obj->labels->singular_name : '';
65
+ ?>
66
+
67
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-menus-wrapper">
68
+ <div id="icon-capsman-admin" class="icon32"></div>
69
+ <h2><?php esc_html_e('Editor Feature Restriction', 'capsman-enhanced'); ?></h2>
70
+
71
+ <form method="post" id="ppc-editor-features-form"
72
+ action="admin.php?page=pp-capabilities-editor-features">
73
+ <?php wp_nonce_field('pp-capabilities-editor-features'); ?>
74
+ <input type="hidden" name="pp_caps_tab" value="<?php echo esc_attr($active_tab_slug);?>" />
75
+ <div class="pp-columns-wrapper<?php echo defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED ? ' pp-enable-sidebar' : '' ?>">
76
+ <div class="pp-column-left">
77
+ <table id="akmin">
78
+ <tr>
79
+ <td class="content">
80
+
81
+ <div class="publishpress-headline">
82
+ <span class="cme-subtext">
83
+ <span class='pp-capability-role-caption'>
84
+ <?php
85
+ esc_html_e('Select editor features to remove. Note that this screen cannot be used to grant additional features to any role.', 'capsman-enhanced');
86
+ ?>
87
+ </span>
88
+ </span>
89
+ </div>
90
+
91
+ <div class="publishpress-filters">
92
+ <select name="ppc-editor-features-role" class="ppc-editor-features-role">
93
+ <?php
94
+ foreach ($roles as $role_name => $name) :
95
+ $name = translate_user_role($name);
96
+ ?>
97
+ <option value="<?php echo esc_attr($role_name);?>" <?php selected($default_role, $role_name);?>><?php echo esc_html($name);?></option>
98
+ <?php
99
+ endforeach;
100
+ ?>
101
+ </select> &nbsp;
102
+
103
+ <img class="loading" src="<?php echo esc_url_raw($capsman->mod_url); ?>/images/wpspin_light.gif" style="display: none">
104
+
105
+
106
+ <input type="submit" name="editor-features-all-submit"
107
+ value="<?php esc_attr_e('Save for all Post Types', 'capsman-enhanced') ?>"
108
+ class="button-secondary ppc-editor-features-submit" style="float:right" />
109
+
110
+ <input type="submit" name="editor-features-submit"
111
+ value="<?php esc_attr_e(sprintf(esc_html__('Save %s Restrictions', 'capsman-enhanced'), esc_html($active_tab_text))); ?>"
112
+ class="button-primary ppc-editor-features-submit" style="float:right"
113
+ data-current_cpt="<?php esc_attr_e(sprintf(esc_html__('Save %s Restrictions', 'capsman-enhanced'), 'post_type')); ?>" />
114
+
115
+ <input type="hidden" name="ppc-tab" value="<?php echo (!empty($_REQUEST['ppc-tab'])) ? sanitize_key($_REQUEST['ppc-tab']) : 'gutenberg';?>" />
116
+ </div>
117
+
118
+ <script type="text/javascript">
119
+ /* <![CDATA[ */
120
+ jQuery(document).ready(function($) {
121
+ $('li.gutenberg-tab').click(function() {
122
+ $('div.publishpress-filters input[name=ppc-tab]').val('gutenberg');
123
+ });
124
+
125
+ $('li.classic-tab').click(function() {
126
+ $('div.publishpress-filters input[name=ppc-tab]').val('classic');
127
+ });
128
+ });
129
+ /* ]]> */
130
+ </script>
131
+
132
+ <?php if ($classic_editor) { ?>
133
+ <ul class="nav-tab-wrapper">
134
+ <li class="editor-features-tab gutenberg-tab nav-tab <?php if (empty($_REQUEST['ppc-tab']) || ('gutenberg' == $_REQUEST['ppc-tab'])) echo 'nav-tab-active';?>"
135
+ data-tab=".editor-features-gutenberg"><a href="#"><?php esc_html_e('Gutenberg', 'capsman-enhanced') ?></a></li>
136
+
137
+ <li class="editor-features-tab classic-tab nav-tab <?php if (!empty($_REQUEST['ppc-tab']) && ('classic' == $_REQUEST['ppc-tab'])) echo 'nav-tab-active';?>"
138
+ data-tab=".editor-features-classic"><a href="#"><?php esc_html_e('Classic', 'capsman-enhanced') ?></a></li>
139
+ </ul>
140
+ <?php } ?>
141
+
142
+ <div id="pp-capability-menu-wrapper" class="postbox">
143
+ <div class="pp-capability-menus">
144
+
145
+ <div class="pp-capability-menus-wrap">
146
+ <div id="pp-capability-menus-general"
147
+ class="pp-capability-menus-content editable-role"
148
+ style="display: block;">
149
+ <div id="ppc-capabilities-wrapper" class="postbox">
150
+
151
+ <div class="ppc-capabilities-tabs">
152
+ <ul>
153
+ <?php
154
+
155
+ foreach($def_post_types as $type_name) {
156
+ $type_obj = get_post_type_object($type_name);
157
+ $active_class = ($type_name === $active_tab_slug) ? 'ppc-capabilities-tab-active' : '';
158
+
159
+ $disabled_count = 0;
160
+ $disabled_count += (is_array($gutenberg_post_disabled) && isset($gutenberg_post_disabled[$type_name])) ? count($gutenberg_post_disabled[$type_name]) : 0;
161
+ $disabled_count += (is_array($ce_post_disabled) && isset($ce_post_disabled[$type_name])) ? count($ce_post_disabled[$type_name]) : 0;
162
+
163
+ ?>
164
+ <li data-slug="<?php esc_attr_e($type_name); ?>"
165
+ data-content="cme-cap-type-tables-<?php esc_attr_e($type_name); ?>"
166
+ data-name="<?php esc_attr_e($type_obj->labels->singular_name); ?>"
167
+ class="<?php esc_attr_e($active_class); ?>">
168
+ <?php esc_html_e($type_obj->labels->singular_name); ?>
169
+ <?php if ($disabled_count > 0) : ?>
170
+ <span class="pp-capabilities-feature-count">
171
+ <?php echo esc_html__('Restricted:', 'capsman-enhanced') . ' ' . esc_html($disabled_count); ?>
172
+ </span>
173
+ <?php endif; ?>
174
+ </li>
175
+ <?php
176
+ }
177
+ ?>
178
+ </ul>
179
+ </div>
180
+
181
+ <div class="ppc-capabilities-content">
182
+ <?php
183
+ foreach($def_post_types as $type_name) {
184
+ $type_obj = get_post_type_object($type_name);
185
+ $active_style = ($type_name === $active_tab_slug) ? '' : 'display:none;';
186
+ ?>
187
+ <div id="cme-cap-type-tables-<?php esc_attr_e($type_name); ?>" style="<?php esc_attr_e($active_style); ?>">
188
+ <?php
189
+ include(dirname(__FILE__) . '/editor-features-gutenberg.php');
190
+
191
+ if ($classic_editor) {
192
+ include(dirname(__FILE__) . '/editor-features-classic.php');
193
+ }
194
+ ?>
195
+ </div>
196
+ <?php
197
+ }
198
+ ?>
199
+ </div>
200
+ </div>
201
+
202
+
203
+ </div>
204
+ </div>
205
+
206
+ </div>
207
+ </div>
208
+
209
+
210
+ <input type="submit" name="editor-features-all-submit"
211
+ value="<?php esc_attr_e('Save for all Post Types', 'capsman-enhanced') ?>"
212
+ class="button-secondary ppc-editor-features-submit" style="float:right" />
213
+
214
+ <input type="submit" name="editor-features-submit"
215
+ value="<?php esc_attr_e(sprintf(esc_html__('Save %s Restrictions', 'capsman-enhanced'), esc_html($active_tab_text))); ?>"
216
+ class="button-primary ppc-editor-features-submit" style="float:right"
217
+ data-current_cpt="<?php esc_attr_e(sprintf(esc_html__('Save %s Restrictions', 'capsman-enhanced'), 'post_type')); ?>" />
218
+
219
+ </td>
220
+ </tr>
221
+ </table>
222
+ </div><!-- .pp-column-left -->
223
+ <?php if (defined('CAPSMAN_PERMISSIONS_INSTALLED') && !CAPSMAN_PERMISSIONS_INSTALLED) { ?>
224
+ <div class="pp-column-right">
225
+ <?php
226
+ $banners = new PublishPress\WordPressBanners\BannersMain;
227
+ $banners->pp_display_banner(
228
+ esc_html__( 'Recommendations for you', 'capsman-enhanced' ),
229
+ esc_html__( 'Control permissions for individual posts and pages', 'capsman-enhanced' ),
230
+ array(
231
+ esc_html__( 'Choose who can read and edit each post.', 'capsman-enhanced' ),
232
+ esc_html__( 'Allow specific user roles or users to manage each post.', 'capsman-enhanced' ),
233
+ esc_html__( 'PublishPress Permissions is 100% free to install.', 'capsman-enhanced' )
234
+ ),
235
+ admin_url( 'plugin-install.php?s=publishpress-ppcore-install&tab=search&type=term' ),
236
+ esc_html__( 'Click here to install PublishPress Permissions', 'capsman-enhanced' ),
237
+ 'install-permissions.jpg'
238
+ );
239
+ ?>
240
+ </div><!-- .pp-column-right -->
241
+ <?php } ?>
242
+ </div><!-- .pp-columns-wrapper -->
243
+ </form>
244
+
245
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
246
+ cme_publishpressFooter();
247
+ }
248
+ ?>
249
+ </div>
250
+
251
+ <style>
252
+ span.menu-item-link {
253
+ webkit-user-select: none; /* Safari */
254
+ -moz-user-select: none; /* Firefox */
255
+ -ms-user-select: none; /* IE10+/Edge */
256
+ user-select: none; /* Standard */
257
+ }
258
+
259
+ input.check-all-menu-item {margin-top: 5px !important;}
260
+
261
+ .pp-promo-overlay-row .pp-promo-upgrade-notice {
262
+ left: calc(50% - 125px) !important;
263
+ }
264
+ table#akmin .pp-capability-menus-select .restrict-column {
265
+ text-align: right !important;
266
+ }
267
+ table#akmin .pp-capability-menus-select tr:first-of-type {
268
+ border-right: 1px solid #c3c4c7;
269
+ }
270
+ table#akmin .pp-capability-menus-select tr:first-of-type th {
271
+ border-top: 1px solid #c3c4c7;
272
+ }
273
+ input[name="editor-features-all-submit"].ppc-editor-features-submit {
274
+ margin-left: 10px;
275
+ }
276
+ .pp-capability-menus-wrap {
277
+ border: 1px solid #c3c4c7;
278
+ }
279
+ .pp-columns-wrapper .nav-tab-wrapper,
280
+ .pp-columns-wrapper .postbox {
281
+ border: unset;
282
+ }
283
+ .pp-capability-menus {
284
+ overflow: initial;
285
+ }
286
+ </style>
287
+
288
+ <script type="text/javascript">
289
+ /* <![CDATA[ */
290
+ jQuery(document).ready(function ($) {
291
+
292
+ // Tabs and Content display
293
+ $('.ppc-capabilities-tabs > ul > li').click( function() {
294
+ var $pp_tab = $(this).attr('data-content');
295
+ var $current_cpt = $('input[name="editor-features-submit"]').attr('data-current_cpt');
296
+ var $button_text = $current_cpt.replace("post_type", $(this).attr('data-name'));
297
+
298
+ $("[name='pp_caps_tab']").val($(this).attr('data-slug'));
299
+
300
+ // Show current Content
301
+ $('.ppc-capabilities-content > div').hide();
302
+ $('#' + $pp_tab).show();
303
+
304
+ // Active current Tab
305
+ $('.ppc-capabilities-tabs > ul > li').removeClass('ppc-capabilities-tab-active');
306
+ $(this).addClass('ppc-capabilities-tab-active');
307
+
308
+ //Update button text
309
+ $('input[name="editor-features-submit"]').val($button_text);
310
+
311
+ });
312
+
313
+ // -------------------------------------------------------------
314
+ // Set form action attribute to include role
315
+ // -------------------------------------------------------------
316
+ $('#ppc-editor-features-form').attr('action', '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-editor-features&role=' . $default_role . '')); ?>');
317
+
318
+ // -------------------------------------------------------------
319
+ // Instant restricted item class
320
+ // -------------------------------------------------------------
321
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-menu-row .check-item', function () {
322
+ var current_tab;
323
+
324
+ <?php if ($classic_editor) { ?>
325
+ if ($('.nav-tab-wrapper .classic-tab').hasClass('nav-tab-active')) {
326
+ current_tab = 'classic';
327
+ } else {
328
+ current_tab = 'gutenberg';
329
+ }
330
+ <?php } else { ?>
331
+ current_tab = 'gutenberg';
332
+ <?php } ?>
333
+
334
+ //add class if feature is restricted for any post type
335
+ var anyRestricted = $(this).closest('tr').find('input:checked').length > 0;
336
+ $(this).closest('tr').find('.menu-item-link').toggleClass('restricted', anyRestricted);
337
+
338
+ var isChecked = $(this).is(':checked');
339
+
340
+ //toggle all checkbox
341
+ if ($(this).hasClass('check-all-menu-item')) {
342
+ var suffix = ('gutenberg' == current_tab) ? '' : current_tab + '_';
343
+ $("input[type='checkbox'][name='capsman_feature_restrict_" + suffix + $(this).data('pp_type') + "[]']").prop('checked', isChecked);
344
+
345
+ $('.' + current_tab + '.menu-item-link').each(function(i,e) {
346
+ $(this).toggleClass('restricted', $(this).closest('tr').find('input:checked').length > 0);
347
+ });
348
+ } else {
349
+ $('.' + current_tab + '.check-all-menu-link').removeClass('restricted').prop('checked', false);
350
+ }
351
+ });
352
+
353
+ $(document).on("click", "span.menu-item-link", function (e) {
354
+ if($(e.target).parent().hasClass('ppc-custom-features-delete')){
355
+ return;
356
+ }
357
+ var chks = $(this).closest('tr').find('input');
358
+ $(chks).prop('checked', !$(this).hasClass('restricted'));
359
+ $(this).toggleClass('restricted', $(chks).filter(':checked').length);
360
+ });
361
+
362
+ // -------------------------------------------------------------
363
+ // Load selected roles menu
364
+ // -------------------------------------------------------------
365
+ $(document).on('change', '.pp-capability-menus-wrapper .ppc-editor-features-role', function () {
366
+
367
+ //disable select
368
+ $('.pp-capability-menus-wrapper .ppc-editor-features-role').attr('disabled', true);
369
+
370
+ //hide button
371
+ $('.pp-capability-menus-wrapper .ppc-editor-features-submit').hide();
372
+
373
+ //show loading
374
+ $('#pp-capability-menu-wrapper').hide();
375
+ $('div.publishpress-caps-manage img.loading').show();
376
+
377
+ //go to url
378
+ window.location = '<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities-editor-features&role=')); ?>' + $(this).val() + '';
379
+
380
+ });
381
+
382
+
383
+ // -------------------------------------------------------------
384
+ // Editor features tab
385
+ // -------------------------------------------------------------
386
+ $('.editor-features-tab').click(function (e) {
387
+ e.preventDefault();
388
+ $('.editor-features-tab').removeClass('nav-tab-active');
389
+ $(this).addClass('nav-tab-active');
390
+ $('.pp-capability-menus-select').hide();
391
+ $('.editor-features-classic-show').hide();
392
+ $('.editor-features-gutenberg-show').hide();
393
+ $($(this).attr('data-tab')).show();
394
+ $($(this).attr('data-tab')+'-show').show();
395
+ });
396
+
397
+ });
398
+ /* ]]> */
399
+ </script>
400
+ <?php
includes/features/features-block-script.js CHANGED
@@ -1,35 +1,35 @@
1
- if(ppc_features.disabled_panel){
2
- var disabled_panel = ppc_features.disabled_panel;
3
- var disabled_panel = disabled_panel.split(',');
4
-
5
- var taxs = ppc_features.taxonomies;
6
- taxs = taxs.split(',');
7
-
8
- taxs.forEach ((tax) => {
9
- if(disabled_panel.includes("taxonomy-panel-" + tax)){
10
- wp.data.dispatch('core/edit-post').removeEditorPanel('taxonomy-panel-' + tax); // category / tag / custom taxonomy
11
- }
12
- });
13
-
14
- if(disabled_panel.includes("featured-image")){
15
- wp.data.dispatch('core/edit-post').removeEditorPanel( 'featured-image' ); // featured image
16
- }
17
- if(disabled_panel.includes("post-link")){
18
- wp.data.dispatch('core/edit-post').removeEditorPanel( 'post-link' ); // permalink
19
- }
20
- if(disabled_panel.includes("page-attributes")){
21
- wp.data.dispatch('core/edit-post').removeEditorPanel( 'page-attributes' ); // page attributes
22
- }
23
- if(disabled_panel.includes("post-excerpt")){
24
- wp.data.dispatch('core/edit-post').removeEditorPanel( 'post-excerpt' ); // Excerpt
25
- }
26
- if(disabled_panel.includes("discussion-panel")){
27
- wp.data.dispatch('core/edit-post').removeEditorPanel( 'discussion-panel' ); // Discussion
28
- }
29
- if(disabled_panel.includes("post-status")){
30
- wp.data.dispatch( 'core/edit-post').removeEditorPanel( 'post-status' ) ;// Post status
31
- }
32
- if(disabled_panel.includes("template")){
33
- wp.data.dispatch( 'core/edit-post').removeEditorPanel( 'template' ) ;// Template
34
- }
35
  }
1
+ if(ppc_features.disabled_panel){
2
+ var disabled_panel = ppc_features.disabled_panel;
3
+ var disabled_panel = disabled_panel.split(',');
4
+
5
+ var taxs = ppc_features.taxonomies;
6
+ taxs = taxs.split(',');
7
+
8
+ taxs.forEach ((tax) => {
9
+ if(disabled_panel.includes("taxonomy-panel-" + tax)){
10
+ wp.data.dispatch('core/edit-post').removeEditorPanel('taxonomy-panel-' + tax); // category / tag / custom taxonomy
11
+ }
12
+ });
13
+
14
+ if(disabled_panel.includes("featured-image")){
15
+ wp.data.dispatch('core/edit-post').removeEditorPanel( 'featured-image' ); // featured image
16
+ }
17
+ if(disabled_panel.includes("post-link")){
18
+ wp.data.dispatch('core/edit-post').removeEditorPanel( 'post-link' ); // permalink
19
+ }
20
+ if(disabled_panel.includes("page-attributes")){
21
+ wp.data.dispatch('core/edit-post').removeEditorPanel( 'page-attributes' ); // page attributes
22
+ }
23
+ if(disabled_panel.includes("post-excerpt")){
24
+ wp.data.dispatch('core/edit-post').removeEditorPanel( 'post-excerpt' ); // Excerpt
25
+ }
26
+ if(disabled_panel.includes("discussion-panel")){
27
+ wp.data.dispatch('core/edit-post').removeEditorPanel( 'discussion-panel' ); // Discussion
28
+ }
29
+ if(disabled_panel.includes("post-status")){
30
+ wp.data.dispatch( 'core/edit-post').removeEditorPanel( 'post-status' ) ;// Post status
31
+ }
32
+ if(disabled_panel.includes("template")){
33
+ wp.data.dispatch( 'core/edit-post').removeEditorPanel( 'template' ) ;// Template
34
+ }
35
  }
includes/features/restrict-admin-features.php CHANGED
@@ -1,401 +1,401 @@
1
- <?php
2
-
3
- class PP_Capabilities_Admin_Features
4
- {
5
-
6
- /**
7
- * Get all admin features layout.
8
- *
9
- * @return array Elements layout.
10
- */
11
- public static function elementsLayout()
12
- {
13
- $elements = [];
14
-
15
- //Add header and footer
16
- $elements[esc_html__('Header and Footer', 'capsman-enhanced')] = self::formatHeaderFooter();
17
-
18
- //Add toolbar
19
- $elements[esc_html__('Admin Toolbar', 'capsman-enhanced')] = self::formatAdminToolbar();
20
-
21
- //Add dashboard widget
22
- $elements[esc_html__('Dashboard widgets', 'capsman-enhanced')] = self::formatDashboardWidgets();
23
-
24
- return apply_filters('pp_capabilities_admin_features_elements', $elements);
25
- }
26
-
27
- /**
28
- * Retrieve all items icons.
29
- *
30
- * @return array Items icons.
31
- */
32
- public static function elementLayoutItemIcons()
33
- {
34
- $icons = [];
35
-
36
- $icons['admintoolbar'] = 'open-folder';
37
- $icons['dashboardwidgets'] = 'dashboard';
38
- $icons['menu-toggle'] = 'menu';
39
- $icons['wp-logo'] = 'wordpress';
40
- $icons['site-name'] = 'admin-home';
41
- $icons['updates'] = 'update';
42
- $icons['comments'] = 'admin-comments';
43
- $icons['new-content'] = 'plus';
44
- $icons['wpseo-menu'] = 'open-folder';
45
- $icons['top-secondary'] = 'admin-users';
46
- $icons['headerandfooter'] = 'admin-multisite';
47
-
48
- return apply_filters('pp_capabilities_admin_features_icons', $icons);
49
- }
50
-
51
- /**
52
- * Let provide support for known adminbar with empty title due to icon title only.
53
- *
54
- */
55
- public static function elementToolbarTitleFallback($id)
56
- {
57
- $title = [];
58
-
59
- $title['menu-toggle'] = esc_html__('Mobile Menu Toggle', 'capsman-enhanced');
60
- $title['wp-logo'] = esc_html__('WordPress Logo', 'capsman-enhanced');
61
- $title['wp-logo-external'] = esc_html__('WordPress External Links', 'capsman-enhanced');
62
- $title['updates'] = esc_html__('Updates', 'capsman-enhanced');
63
- $title['comments'] = esc_html__('Comments', 'capsman-enhanced');
64
- $title['top-secondary'] = esc_html__('Right bar', 'capsman-enhanced');
65
- $title['user-actions'] = esc_html__('User actions', 'capsman-enhanced');
66
- $title['new-content'] = esc_html__('New', 'capsman-enhanced');
67
- $title['new-content'] = esc_html__('New', 'capsman-enhanced');
68
- $title['user-info'] = esc_html__('User Display Name', 'capsman-enhanced');
69
- $title['wpseo-menu'] = esc_html__('Yoast SEO', 'capsman-enhanced');
70
-
71
- return isset($title[$id]) ? $title[$id] : $id;
72
- }
73
-
74
- /**
75
- * Format header and footer items
76
- *
77
- * @return array Elements layout item.
78
- */
79
- public static function formatHeaderFooter()
80
- {
81
- $elements_item['screen_options'] = ['label' => esc_html__('Screen Options', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
82
- $elements_item['screen_help'] = ['label' => esc_html__('Help', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
83
- $elements_item['footer_thankyou'] = ['label' => esc_html__('Thank you for creating with WordPress', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
84
- $elements_item['footer_upgrade'] = ['label' => sprintf( esc_html__( 'Version %s' ), get_bloginfo('version'), 'capsman-enhanced' ), 'action' => 'ppc_header_footer'];
85
-
86
- return $elements_item;
87
- }
88
-
89
- /**
90
- * Get the list of dashboard widgets.
91
- *
92
- * @return array dashboard widgets.
93
- */
94
- public static function dashboardWidgets()
95
- {
96
- global $wp_meta_boxes;
97
-
98
- $screen = is_network_admin() ? 'dashboard-network' : 'dashboard';
99
- $action = is_network_admin() ? 'wp_network_dashboard_setup' : 'wp_dashboard_setup';
100
- $current_screen = get_current_screen();
101
-
102
- //set current screen as dashboard to get widgets
103
- if (!isset($wp_meta_boxes[$screen]) || !is_array($wp_meta_boxes[$screen])) {
104
- require_once ABSPATH . '/wp-admin/includes/dashboard.php';
105
- set_current_screen($screen);
106
- remove_action( $action, [ __CLASS__, 'disableDashboardWidgets' ], 99 );
107
- wp_dashboard_setup();
108
- add_action( $action, [ __CLASS__, 'disableDashboardWidgets' ], 99 );
109
- }
110
-
111
- $widgets = [];
112
- if (isset($wp_meta_boxes[$screen])) {
113
- $widgets = $wp_meta_boxes[$screen];
114
- }
115
-
116
- //set current screen to it original stage
117
- set_current_screen($current_screen);
118
-
119
- return $widgets;
120
- }
121
-
122
- /**
123
- * Format dashboard widgets.
124
- *
125
- * @return array Elements layout item.
126
- */
127
- public static function formatDashboardWidgets()
128
- {
129
- $widgets = self::dashboardWidgets();
130
-
131
- $elements_widget = [];
132
- //add widget that may not be part of wp_meta_boxes
133
- $elements_widget['dashboard_welcome_panel'] = ['label' => esc_html__('Welcome panel', 'capsman-enhanced'), 'context' => 'normal', 'action' => 'ppc_dashboard_widget'];
134
- //loop other widgets
135
- foreach ($widgets as $context => $priority) {
136
- foreach ($priority as $data) {
137
- foreach ($data as $id => $widget) {
138
- if ($widget) {
139
- $widget_title = isset($widget['title']) ? wp_strip_all_tags($widget['title']) : '';
140
- $elements_widget[$id] = ['label' => $widget_title, 'context' => $context, 'action' => 'ppc_dashboard_widget'];
141
- }
142
- }
143
- }
144
- }
145
-
146
- return $elements_widget;
147
- }
148
-
149
- /**
150
- * Format admin toolbar.
151
- *
152
- * @return array Elements layout item.
153
- */
154
- public static function formatAdminToolbar()
155
- {
156
- global $toolbar_items;
157
-
158
- $toolbars = (array)$GLOBALS['ppcAdminBar'];
159
- $toolbarTree = self::formatAdminToolbarTree($toolbars);
160
- //set toolbar element with steps
161
- self::setAdminToolbarElement($toolbarTree);
162
-
163
- return $toolbar_items;
164
- }
165
-
166
- /**
167
- * Build multidimensional array for admin toolbar.
168
- *
169
- * @return array.
170
- */
171
- public static function formatAdminToolbarTree(array $items, $parentId = '')
172
- {
173
- $branch = [];
174
-
175
- foreach ($items as $item) {
176
- if ($item['parent'] == $parentId) {
177
- $children = self::formatAdminToolbarTree($items, $item['id']);
178
- if ($children) {
179
- $item['children'] = $children;
180
- }
181
- $branch[] = $item;
182
- }
183
- }
184
-
185
- return $branch;
186
- }
187
-
188
- /**
189
- * Set admin toolbar element.
190
- *
191
- */
192
- public static function setAdminToolbarElement(array $toolbarTrees, $steps = 1, $step_list = [])
193
- {
194
- global $toolbar_items;
195
-
196
- $position = 0;
197
- foreach ($toolbarTrees as $toolbarTree) {
198
- $position++;
199
- $id = $toolbarTree['id'];
200
- $itemTitle = self::cleanTitleText($toolbarTree['title']);
201
-
202
- //let fall back to known title/id if title still empty
203
- if (empty(trim($itemTitle))) {
204
- $itemTitle = self::elementToolbarTitleFallback($id);
205
- }
206
-
207
- $toolbar_items[$id] = ['label' => $itemTitle,
208
- 'parent' => $toolbarTree['parent'],
209
- 'step' => $steps,
210
- 'position' => $position,
211
- 'action' => 'ppc_adminbar'
212
- ];
213
- foreach ($toolbarTree as $key => $value) {
214
- if (is_array($value)) {
215
- self::setAdminToolbarElement($value, $steps + 1, $step_list);
216
- }
217
- }
218
- }
219
- }
220
-
221
- /**
222
- * Process admin features title.
223
- *
224
- */
225
- public static function cleanTitleText($title)
226
- {
227
- //strip span and div content
228
- $title = preg_replace('#(<span.*?>).*?(</span>)#', '', $title);
229
- $title = preg_replace('#(<img.*?>)#', '', $title);
230
-
231
- //strip other html tags
232
- $title = wp_strip_all_tags($title);
233
-
234
- return $title;
235
- }
236
-
237
- /**
238
- * Get array elements that starts with a specific word
239
- *
240
- * @param array $restricted_features All restricted elements to check agains.
241
- * @param string $start_with The word to look for in array.
242
- *
243
- * @return array Filtered array.
244
- */
245
- public static function adminFeaturesRestrictedElements($restricted_elements, $start_with = 'ppc_adminbar')
246
- {
247
- //get all items of the array starting with the specified string.
248
- $new_elements = array_filter(
249
- $restricted_elements,
250
- function($value, $key) use ($start_with) {return strpos($value, $start_with) === 0;}, ARRAY_FILTER_USE_BOTH
251
- );
252
-
253
- return $new_elements;
254
- }
255
-
256
-
257
- /**
258
- * Apply admin feature restrictions
259
- */
260
- public static function adminFeaturedRestriction()
261
- {
262
- global $ppc_disabled_toolbar, $ppc_disabled_widget;
263
-
264
- if (is_multisite() && is_super_admin() && !defined('PP_CAPABILITIES_RESTRICT_SUPER_ADMIN')) {
265
- return;
266
- }
267
-
268
- // Get all user roles.
269
- $user_roles = wp_get_current_user()->roles;
270
- $disabled_features = get_option("capsman_disabled_admin_features", []);
271
-
272
- $all_disabled_elements = [];
273
-
274
- foreach ($user_roles as $role) {
275
- if (!empty($disabled_features[$role])) {
276
- $all_disabled_elements[] = $disabled_features[$role];
277
- }
278
- }
279
-
280
- //merge all array values incase it's more than role
281
- //$all_disabled_elements = array_merge(...$all_disabled_elements); // This is a PHP 7.4 operator
282
- $all_disabled_elements = (is_array($all_disabled_elements) && isset($all_disabled_elements[0])) ? array_merge($all_disabled_elements[0]) : [];
283
-
284
- do_action('ppc_admin_feature_restriction', $all_disabled_elements);
285
-
286
- //disable toolbar
287
- $ppc_disabled_toolbar = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_adminbar');
288
- if(count($ppc_disabled_toolbar) > 0){
289
- if(in_array('ppc_adminbar||admintoolbar', $ppc_disabled_toolbar)){//whole admin bar disabled
290
- //frontend admin tool bar
291
- add_filter('show_admin_bar', '__return_false');
292
- //backend admin tool bar
293
- add_action('admin_head', [__CLASS__, 'disableDashboardBarBackend']);
294
- } else {
295
- add_action( 'wp_before_admin_bar_render', [ __CLASS__, 'disableDashboardBar' ], 99 );
296
- }
297
- }
298
-
299
- if(is_admin()){
300
- $ppc_disabled_widget = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_dashboard_widget');
301
- $ppc_header_footer = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_header_footer');
302
-
303
- //disable widget
304
- if(count($ppc_disabled_widget) > 0){
305
- add_action( 'wp_dashboard_setup', [ __CLASS__, 'disableDashboardWidgets' ], 99 );
306
- add_action( 'wp_network_dashboard_setup', [ __CLASS__, 'disableDashboardWidgets' ], 99 );
307
- }
308
-
309
- //admin header and footer item
310
- if(count($ppc_header_footer) > 0){
311
- self::disableHeaderFooterElement($ppc_header_footer);
312
- }
313
- }
314
- }
315
-
316
- /**
317
- * Disable header and footer item
318
- *
319
- */
320
- public static function disableHeaderFooterElement($ppc_header_footer) {
321
- if(in_array('ppc_header_footer||screen_options', $ppc_header_footer)){
322
- add_filter( 'screen_options_show_screen', '__return_false', 999 );
323
- }
324
- if(in_array('ppc_header_footer||screen_help', $ppc_header_footer)){
325
- add_action('admin_head', [__CLASS__, 'contextual_help_list_remove'], 999);
326
- }
327
- if(in_array('ppc_header_footer||footer_thankyou', $ppc_header_footer)){
328
- add_filter( 'admin_footer_text', '__return_false', 999 );
329
- }
330
- if(in_array('ppc_header_footer||footer_upgrade', $ppc_header_footer)){
331
- add_filter( 'update_footer', '__return_false', 999 );
332
- }
333
- }
334
-
335
- /**
336
- * Remove help tab
337
- *
338
- */
339
- public static function contextual_help_list_remove(){
340
- $screen = get_current_screen();
341
- $screen->remove_help_tabs();
342
- }
343
-
344
- /**
345
- * Disable backend admin bar.
346
- *
347
- */
348
- public static function disableDashboardBarBackend()
349
- {
350
- //add inline styles
351
- ppc_add_inline_style('html.wp-toolbar { padding-top:0!important; } #wpadminbar {display:none !important;}');
352
- }
353
-
354
- /**
355
- * Disable admin bar.
356
- *
357
- */
358
- public static function disableDashboardBar() {
359
- global $wp_admin_bar, $ppc_disabled_toolbar;
360
- $admin_bar_options = (array)$ppc_disabled_toolbar;
361
- $admin_bar_items = (array)$GLOBALS['ppcAdminBar'];
362
-
363
- if (count($admin_bar_options) > 0 && ( is_array($admin_bar_items) || is_object($admin_bar_items) ) ) {
364
- foreach ($admin_bar_items as $barItem) {
365
- $id = $barItem['id'];
366
- $item_id = 'ppc_adminbar||'.$id;
367
- if ($id && in_array($item_id, $admin_bar_options)) {
368
- $wp_admin_bar->remove_menu($id);
369
- }
370
- }
371
- }
372
-
373
- }
374
-
375
- /**
376
- * Disable dashboard widgets.
377
- *
378
- */
379
- public static function disableDashboardWidgets() {
380
- global $ppc_disabled_widget;
381
-
382
- $widgets = (array)$ppc_disabled_widget;
383
-
384
- if ( count($widgets) === 0 ) {
385
- return;
386
- }
387
-
388
- foreach ( $widgets as $widget) {
389
- $widget_data = explode("||", $widget);
390
- $widget_id = $widget_data[1];
391
- $widget_content = $widget_data[2];
392
-
393
- if ( $widget_id === 'dashboard_welcome_panel' ) {
394
- remove_action( 'welcome_panel', 'wp_welcome_panel' );
395
- }else{
396
- remove_meta_box( $widget_id, get_current_screen()->base, $widget_content );
397
- }
398
- }
399
- }
400
-
401
- }
1
+ <?php
2
+
3
+ class PP_Capabilities_Admin_Features
4
+ {
5
+
6
+ /**
7
+ * Get all admin features layout.
8
+ *
9
+ * @return array Elements layout.
10
+ */
11
+ public static function elementsLayout()
12
+ {
13
+ $elements = [];
14
+
15
+ //Add header and footer
16
+ $elements[esc_html__('Header and Footer', 'capsman-enhanced')] = self::formatHeaderFooter();
17
+
18
+ //Add toolbar
19
+ $elements[esc_html__('Admin Toolbar', 'capsman-enhanced')] = self::formatAdminToolbar();
20
+
21
+ //Add dashboard widget
22
+ $elements[esc_html__('Dashboard widgets', 'capsman-enhanced')] = self::formatDashboardWidgets();
23
+
24
+ return apply_filters('pp_capabilities_admin_features_elements', $elements);
25
+ }
26
+
27
+ /**
28
+ * Retrieve all items icons.
29
+ *
30
+ * @return array Items icons.
31
+ */
32
+ public static function elementLayoutItemIcons()
33
+ {
34
+ $icons = [];
35
+
36
+ $icons['admintoolbar'] = 'open-folder';
37
+ $icons['dashboardwidgets'] = 'dashboard';
38
+ $icons['menu-toggle'] = 'menu';
39
+ $icons['wp-logo'] = 'wordpress';
40
+ $icons['site-name'] = 'admin-home';
41
+ $icons['updates'] = 'update';
42
+ $icons['comments'] = 'admin-comments';
43
+ $icons['new-content'] = 'plus';
44
+ $icons['wpseo-menu'] = 'open-folder';
45
+ $icons['top-secondary'] = 'admin-users';
46
+ $icons['headerandfooter'] = 'admin-multisite';
47
+
48
+ return apply_filters('pp_capabilities_admin_features_icons', $icons);
49
+ }
50
+
51
+ /**
52
+ * Let provide support for known adminbar with empty title due to icon title only.
53
+ *
54
+ */
55
+ public static function elementToolbarTitleFallback($id)
56
+ {
57
+ $title = [];
58
+
59
+ $title['menu-toggle'] = esc_html__('Mobile Menu Toggle', 'capsman-enhanced');
60
+ $title['wp-logo'] = esc_html__('WordPress Logo', 'capsman-enhanced');
61
+ $title['wp-logo-external'] = esc_html__('WordPress External Links', 'capsman-enhanced');
62
+ $title['updates'] = esc_html__('Updates', 'capsman-enhanced');
63
+ $title['comments'] = esc_html__('Comments', 'capsman-enhanced');
64
+ $title['top-secondary'] = esc_html__('Right bar', 'capsman-enhanced');
65
+ $title['user-actions'] = esc_html__('User actions', 'capsman-enhanced');
66
+ $title['new-content'] = esc_html__('New', 'capsman-enhanced');
67
+ $title['new-content'] = esc_html__('New', 'capsman-enhanced');
68
+ $title['user-info'] = esc_html__('User Display Name', 'capsman-enhanced');
69
+ $title['wpseo-menu'] = esc_html__('Yoast SEO', 'capsman-enhanced');
70
+
71
+ return isset($title[$id]) ? $title[$id] : $id;
72
+ }
73
+
74
+ /**
75
+ * Format header and footer items
76
+ *
77
+ * @return array Elements layout item.
78
+ */
79
+ public static function formatHeaderFooter()
80
+ {
81
+ $elements_item['screen_options'] = ['label' => esc_html__('Screen Options', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
82
+ $elements_item['screen_help'] = ['label' => esc_html__('Help', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
83
+ $elements_item['footer_thankyou'] = ['label' => esc_html__('Thank you for creating with WordPress', 'capsman-enhanced'), 'action' => 'ppc_header_footer'];
84
+ $elements_item['footer_upgrade'] = ['label' => sprintf( esc_html__( 'Version %s' ), get_bloginfo('version'), 'capsman-enhanced' ), 'action' => 'ppc_header_footer'];
85
+
86
+ return $elements_item;
87
+ }
88
+
89
+ /**
90
+ * Get the list of dashboard widgets.
91
+ *
92
+ * @return array dashboard widgets.
93
+ */
94
+ public static function dashboardWidgets()
95
+ {
96
+ global $wp_meta_boxes;
97
+
98
+ $screen = is_network_admin() ? 'dashboard-network' : 'dashboard';
99
+ $action = is_network_admin() ? 'wp_network_dashboard_setup' : 'wp_dashboard_setup';
100
+ $current_screen = get_current_screen();
101
+
102
+ //set current screen as dashboard to get widgets
103
+ if (!isset($wp_meta_boxes[$screen]) || !is_array($wp_meta_boxes[$screen])) {
104
+ require_once ABSPATH . '/wp-admin/includes/dashboard.php';
105
+ set_current_screen($screen);
106
+ remove_action( $action, [ __CLASS__, 'disableDashboardWidgets' ], 99 );
107
+ wp_dashboard_setup();
108
+ add_action( $action, [ __CLASS__, 'disableDashboardWidgets' ], 99 );
109
+ }
110
+
111
+ $widgets = [];
112
+ if (isset($wp_meta_boxes[$screen])) {
113
+ $widgets = $wp_meta_boxes[$screen];
114
+ }
115
+
116
+ //set current screen to it original stage
117
+ set_current_screen($current_screen);
118
+
119
+ return $widgets;
120
+ }
121
+
122
+ /**
123
+ * Format dashboard widgets.
124
+ *
125
+ * @return array Elements layout item.
126
+ */
127
+ public static function formatDashboardWidgets()
128
+ {
129
+ $widgets = self::dashboardWidgets();
130
+
131
+ $elements_widget = [];
132
+ //add widget that may not be part of wp_meta_boxes
133
+ $elements_widget['dashboard_welcome_panel'] = ['label' => esc_html__('Welcome panel', 'capsman-enhanced'), 'context' => 'normal', 'action' => 'ppc_dashboard_widget'];
134
+ //loop other widgets
135
+ foreach ($widgets as $context => $priority) {
136
+ foreach ($priority as $data) {
137
+ foreach ($data as $id => $widget) {
138
+ if ($widget) {
139
+ $widget_title = isset($widget['title']) ? wp_strip_all_tags($widget['title']) : '';
140
+ $elements_widget[$id] = ['label' => $widget_title, 'context' => $context, 'action' => 'ppc_dashboard_widget'];
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ return $elements_widget;
147
+ }
148
+
149
+ /**
150
+ * Format admin toolbar.
151
+ *
152
+ * @return array Elements layout item.
153
+ */
154
+ public static function formatAdminToolbar()
155
+ {
156
+ global $toolbar_items;
157
+
158
+ $toolbars = (array)$GLOBALS['ppcAdminBar'];
159
+ $toolbarTree = self::formatAdminToolbarTree($toolbars);
160
+ //set toolbar element with steps
161
+ self::setAdminToolbarElement($toolbarTree);
162
+
163
+ return $toolbar_items;
164
+ }
165
+
166
+ /**
167
+ * Build multidimensional array for admin toolbar.
168
+ *
169
+ * @return array.
170
+ */
171
+ public static function formatAdminToolbarTree(array $items, $parentId = '')
172
+ {
173
+ $branch = [];
174
+
175
+ foreach ($items as $item) {
176
+ if ($item['parent'] == $parentId) {
177
+ $children = self::formatAdminToolbarTree($items, $item['id']);
178
+ if ($children) {
179
+ $item['children'] = $children;
180
+ }
181
+ $branch[] = $item;
182
+ }
183
+ }
184
+
185
+ return $branch;
186
+ }
187
+
188
+ /**
189
+ * Set admin toolbar element.
190
+ *
191
+ */
192
+ public static function setAdminToolbarElement(array $toolbarTrees, $steps = 1, $step_list = [])
193
+ {
194
+ global $toolbar_items;
195
+
196
+ $position = 0;
197
+ foreach ($toolbarTrees as $toolbarTree) {
198
+ $position++;
199
+ $id = $toolbarTree['id'];
200
+ $itemTitle = self::cleanTitleText($toolbarTree['title']);
201
+
202
+ //let fall back to known title/id if title still empty
203
+ if (empty(trim($itemTitle))) {
204
+ $itemTitle = self::elementToolbarTitleFallback($id);
205
+ }
206
+
207
+ $toolbar_items[$id] = ['label' => $itemTitle,
208
+ 'parent' => $toolbarTree['parent'],
209
+ 'step' => $steps,
210
+ 'position' => $position,
211
+ 'action' => 'ppc_adminbar'
212
+ ];
213
+ foreach ($toolbarTree as $key => $value) {
214
+ if (is_array($value)) {
215
+ self::setAdminToolbarElement($value, $steps + 1, $step_list);
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Process admin features title.
223
+ *
224
+ */
225
+ public static function cleanTitleText($title)
226
+ {
227
+ //strip span and div content
228
+ $title = preg_replace('#(<span.*?>).*?(</span>)#', '', $title);
229
+ $title = preg_replace('#(<img.*?>)#', '', $title);
230
+
231
+ //strip other html tags
232
+ $title = wp_strip_all_tags($title);
233
+
234
+ return $title;
235
+ }
236
+
237
+ /**
238
+ * Get array elements that starts with a specific word
239
+ *
240
+ * @param array $restricted_features All restricted elements to check agains.
241
+ * @param string $start_with The word to look for in array.
242
+ *
243
+ * @return array Filtered array.
244
+ */
245
+ public static function adminFeaturesRestrictedElements($restricted_elements, $start_with = 'ppc_adminbar')
246
+ {
247
+ //get all items of the array starting with the specified string.
248
+ $new_elements = array_filter(
249
+ $restricted_elements,
250
+ function($value, $key) use ($start_with) {return strpos($value, $start_with) === 0;}, ARRAY_FILTER_USE_BOTH
251
+ );
252
+
253
+ return $new_elements;
254
+ }
255
+
256
+
257
+ /**
258
+ * Apply admin feature restrictions
259
+ */
260
+ public static function adminFeaturedRestriction()
261
+ {
262
+ global $ppc_disabled_toolbar, $ppc_disabled_widget;
263
+
264
+ if (is_multisite() && is_super_admin() && !defined('PP_CAPABILITIES_RESTRICT_SUPER_ADMIN')) {
265
+ return;
266
+ }
267
+
268
+ // Get all user roles.
269
+ $user_roles = wp_get_current_user()->roles;
270
+ $disabled_features = get_option("capsman_disabled_admin_features", []);
271
+
272
+ $all_disabled_elements = [];
273
+
274
+ foreach ($user_roles as $role) {
275
+ if (!empty($disabled_features[$role])) {
276
+ $all_disabled_elements[] = $disabled_features[$role];
277
+ }
278
+ }
279
+
280
+ //merge all array values incase it's more than role
281
+ //$all_disabled_elements = array_merge(...$all_disabled_elements); // This is a PHP 7.4 operator
282
+ $all_disabled_elements = (is_array($all_disabled_elements) && isset($all_disabled_elements[0])) ? array_merge($all_disabled_elements[0]) : [];
283
+
284
+ do_action('ppc_admin_feature_restriction', $all_disabled_elements);
285
+
286
+ //disable toolbar
287
+ $ppc_disabled_toolbar = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_adminbar');
288
+ if(count($ppc_disabled_toolbar) > 0){
289
+ if(in_array('ppc_adminbar||admintoolbar', $ppc_disabled_toolbar)){//whole admin bar disabled
290
+ //frontend admin tool bar
291
+ add_filter('show_admin_bar', '__return_false');
292
+ //backend admin tool bar
293
+ add_action('admin_head', [__CLASS__, 'disableDashboardBarBackend']);
294
+ } else {
295
+ add_action( 'wp_before_admin_bar_render', [ __CLASS__, 'disableDashboardBar' ], 99 );
296
+ }
297
+ }
298
+
299
+ if(is_admin()){
300
+ $ppc_disabled_widget = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_dashboard_widget');
301
+ $ppc_header_footer = self::adminFeaturesRestrictedElements($all_disabled_elements, 'ppc_header_footer');
302
+
303
+ //disable widget
304
+ if(count($ppc_disabled_widget) > 0){
305
+ add_action( 'wp_dashboard_setup', [ __CLASS__, 'disableDashboardWidgets' ], 99 );
306
+ add_action( 'wp_network_dashboard_setup', [ __CLASS__, 'disableDashboardWidgets' ], 99 );
307
+ }
308
+
309
+ //admin header and footer item
310
+ if(count($ppc_header_footer) > 0){
311
+ self::disableHeaderFooterElement($ppc_header_footer);
312
+ }
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Disable header and footer item
318
+ *
319
+ */
320
+ public static function disableHeaderFooterElement($ppc_header_footer) {
321
+ if(in_array('ppc_header_footer||screen_options', $ppc_header_footer)){
322
+ add_filter( 'screen_options_show_screen', '__return_false', 999 );
323
+ }
324
+ if(in_array('ppc_header_footer||screen_help', $ppc_header_footer)){
325
+ add_action('admin_head', [__CLASS__, 'contextual_help_list_remove'], 999);
326
+ }
327
+ if(in_array('ppc_header_footer||footer_thankyou', $ppc_header_footer)){
328
+ add_filter( 'admin_footer_text', '__return_false', 999 );
329
+ }
330
+ if(in_array('ppc_header_footer||footer_upgrade', $ppc_header_footer)){
331
+ add_filter( 'update_footer', '__return_false', 999 );
332
+ }
333
+ }
334
+
335
+ /**
336
+ * Remove help tab
337
+ *
338
+ */
339
+ public static function contextual_help_list_remove(){
340
+ $screen = get_current_screen();
341
+ $screen->remove_help_tabs();
342
+ }
343
+
344
+ /**
345
+ * Disable backend admin bar.
346
+ *
347
+ */
348
+ public static function disableDashboardBarBackend()
349
+ {
350
+ //add inline styles
351
+ ppc_add_inline_style('html.wp-toolbar { padding-top:0!important; } #wpadminbar {display:none !important;}');
352
+ }
353
+
354
+ /**
355
+ * Disable admin bar.
356
+ *
357
+ */
358
+ public static function disableDashboardBar() {
359
+ global $wp_admin_bar, $ppc_disabled_toolbar;
360
+ $admin_bar_options = (array)$ppc_disabled_toolbar;
361
+ $admin_bar_items = (array)$GLOBALS['ppcAdminBar'];
362
+
363
+ if (count($admin_bar_options) > 0 && ( is_array($admin_bar_items) || is_object($admin_bar_items) ) ) {
364
+ foreach ($admin_bar_items as $barItem) {
365
+ $id = $barItem['id'];
366
+ $item_id = 'ppc_adminbar||'.$id;
367
+ if ($id && in_array($item_id, $admin_bar_options)) {
368
+ $wp_admin_bar->remove_menu($id);
369
+ }
370
+ }
371
+ }
372
+
373
+ }
374
+
375
+ /**
376
+ * Disable dashboard widgets.
377
+ *
378
+ */
379
+ public static function disableDashboardWidgets() {
380
+ global $ppc_disabled_widget;
381
+
382
+ $widgets = (array)$ppc_disabled_widget;
383
+
384
+ if ( count($widgets) === 0 ) {
385
+ return;
386
+ }
387
+
388
+ foreach ( $widgets as $widget) {
389
+ $widget_data = explode("||", $widget);
390
+ $widget_id = $widget_data[1];
391
+ $widget_content = $widget_data[2];
392
+
393
+ if ( $widget_id === 'dashboard_welcome_panel' ) {
394
+ remove_action( 'welcome_panel', 'wp_welcome_panel' );
395
+ }else{
396
+ remove_meta_box( $widget_id, get_current_screen()->base, $widget_content );
397
+ }
398
+ }
399
+ }
400
+
401
+ }
includes/features/restrict-editor-features.php CHANGED
@@ -1,353 +1,353 @@
1
- <?php
2
-
3
- class PP_Capabilities_Post_Features {
4
-
5
- /**
6
- * Recursive search in array.
7
- *
8
- * @param string $needle
9
- * @param array $haystack
10
- *
11
- * @return bool
12
- */
13
- private static function recursiveInArray($needle, $haystack)
14
- {
15
- if ('' === $haystack) {
16
- return false;
17
- }
18
-
19
- if (!$haystack) {
20
- return false;
21
- }
22
-
23
- foreach ($haystack as $stalk) {
24
- if ($needle === $stalk
25
- || (is_array($stalk)
26
- && self::recursiveInArray($needle, $stalk)
27
- )
28
- ) {
29
- return true;
30
- }
31
- }
32
-
33
- return false;
34
- }
35
-
36
- public static function elementsLayoutClassic()
37
- {
38
- $elements = [];
39
-
40
- $elements[esc_html__('Top Tabs', 'capsman-enhanced')] = [
41
- '#contextual-help-link-wrap' => ['label' => esc_html__('Help', 'capsman-enhanced')],
42
- '#screen-options-link-wrap' => ['label' => esc_html__('Screen Options', 'capsman-enhanced')],
43
- ];
44
-
45
- $elements[esc_html__('Editor', 'capsman-enhanced')] = [
46
- '.page-title-action' => ['label' => esc_html__('Add New', 'capsman-enhanced')],
47
- '#title' => ['label' => esc_html__('Title', 'capsman-enhanced'), 'elements' => '#titlediv, #title, #titlewrap'],
48
- '#postdivrich' => ['label' => esc_html__('Editor', 'capsman-enhanced')],
49
- '#pageslugdiv' => ['label' => esc_html__('Permalink', 'capsman-enhanced')],
50
- '#media_buttons' => ['label' => esc_html__('Media Buttons (all)', 'capsman-enhanced'), 'elements' => '#media-buttons, #wp-content-media-buttons'],
51
- '#html_editor_button' => ['label' => esc_html__('HTML Editor Button', 'capsman-enhanced'),'elements' => '#editor-toolbar #edButtonHTML, #quicktags, #content-html, .wp-switch-editor.switch-html'],
52
- '#wp-word-count' => ['label' => esc_html__('Word count', 'capsman-enhanced')],
53
- ];
54
-
55
- $elements[esc_html__('Publish Box', 'capsman-enhanced')] = [
56
- '#submitdiv' => ['label' => esc_html__('Publish Box', 'capsman-enhanced')],
57
- '#save-post' => ['label' => esc_html__('Save Draft', 'capsman-enhanced')],
58
- '#post-preview' => ['label' => esc_html__('Preview', 'capsman-enhanced')],
59
- '.misc-pub-post-status' => ['label' => esc_html__('Publish Status ', 'capsman-enhanced')],
60
- '.misc-pub-visibility' => ['label' => esc_html__('Publish Visibility', 'capsman-enhanced')],
61
- '#passworddiv' => ['label' => esc_html__('Password Protect This Post', 'capsman-enhanced')],
62
- '#misc-publishing-actions' => ['label' => esc_html__('Publish Actions', 'capsman-enhanced')],
63
- '.misc-pub-curtime' => ['label' => esc_html__('Publish Schedule', 'capsman-enhanced')],
64
- '#date' => ['label' => esc_html__('Date', 'capsman-enhanced'), 'elements' => '#date, #datediv, th.column-date, td.date, div.curtime'],
65
- '#publish' => ['label' => esc_html__('Publish', 'capsman-enhanced')],
66
- ];
67
-
68
- $elements[esc_html__('Taxonomy Boxes', 'capsman-enhanced')] = [
69
- '#category' => ['label' => esc_html__('Categories', 'capsman-enhanced'), 'elements' => '#categories, #categorydiv, #categorydivsb, th.column-categories, td.categories'],
70
- '#category-add-toggle' => ['label' => esc_html__('Add New Category', 'capsman-enhanced')],
71
- '#post_tag' => ['label' => esc_html__('Tags', 'capsman-enhanced'), 'elements' => '#tags, #tagsdiv,#tagsdivsb,#tagsdiv-post_tag, th.column-tags, td.tags'],
72
- ];
73
-
74
- end($elements);
75
- $k = key($elements);
76
-
77
- foreach (get_taxonomies(['show_ui' => true], 'object') as $taxonomy => $tx_obj) {
78
- if (!in_array($taxonomy, ['category', 'post_tag', 'link_category'])) {
79
- $elements[$k]["#{$tx_obj->name}div"] = ['label' => $tx_obj->label,'elements'=>"#{$tx_obj->name}, #{$tx_obj->name}div,#{$tx_obj->name}divsb,#tagsdiv-{$tx_obj->name}, th.column-{$tx_obj->name}, td.{$tx_obj->name}"];
80
- }
81
- }
82
-
83
- $elements[esc_html__('Page Boxes', 'capsman-enhanced')] = [
84
- '#pageparentdiv' => ['label' => esc_html__('Page Attributes', 'capsman-enhanced')],
85
- '#parent_id' => ['label' => esc_html__('Parent', 'capsman-enhanced'), 'elements' => 'p.parent-id-label-wrapper, #parent_id'],
86
- '#page_template' => ['label' => esc_html__('Page Template', 'capsman-enhanced')],
87
- 'p.menu-order-label-wrapper' => ['label' => esc_html__('Order', 'capsman-enhanced')],
88
- ];
89
-
90
- $elements[esc_html__('Other Boxes', 'capsman-enhanced')] = [
91
- '#postimagediv' => ['label' => esc_html__('Featured Image', 'capsman-enhanced')],
92
- '#slug' => ['label' => esc_html__('Post Slug', 'capsman-enhanced'), 'elements' => '#slugdiv,#edit-slug-box'],
93
- '#commentstatusdiv' => ['label' => esc_html__('Discussion', 'capsman-enhanced')],
94
- ];
95
-
96
- end($elements);
97
- $k = key($elements);
98
-
99
- $post_type_supports = [];
100
-
101
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
102
-
103
- foreach($def_post_types as $post_type) {
104
- $post_type_supports = array_merge($post_type_supports, get_all_post_type_supports($post_type));
105
- }
106
-
107
- foreach (array_keys($post_type_supports) as $feature) {
108
- $label = ucfirst(str_replace(['-', '_'], ' ', $feature));
109
-
110
- switch ($feature) {
111
- case 'excerpt' :
112
- $id = 'postexcerpt';
113
- break;
114
-
115
- case 'custom-fields' :
116
- $id = 'postcustom';
117
- break;
118
-
119
- case 'post-formats' :
120
- $id = 'format';
121
- break;
122
-
123
- case 'author':
124
- case 'excerpt':
125
- case 'trackbacks':
126
- case 'comments':
127
- case 'revisions':
128
- //default:
129
- $id = $feature;
130
- break;
131
-
132
- default:
133
- continue 2;
134
- }
135
-
136
- $elements[$k][$feature] = [
137
- 'label' => $label,
138
- 'elements' => '#' . $id
139
- . ', #' . $id . 'div'
140
- . ', th.column-' . $id
141
- . ', td.' . $id
142
- ]; //th and td for raw in edit screen
143
- }
144
-
145
- return apply_filters('pp_capabilities_post_feature_elements_classic', $elements);
146
- }
147
-
148
-
149
- /**
150
- * Classic Editor screen: Output Styles to Hide UI elements for Editor Features configured as restricted
151
- */
152
- public static function applyRestrictionsClassic()
153
- {
154
- $restrict_elements = [];
155
-
156
- if (!$post_type = pp_capabilities_get_post_type()) {
157
- return;
158
- }
159
-
160
- // Only restrictions associated with this user's role(s) will be applied
161
- $role_restrictions = array_intersect_key(
162
- get_option("capsman_feature_restrict_classic_{$post_type}", []),
163
- array_fill_keys(wp_get_current_user()->roles, true)
164
- );
165
-
166
- foreach($role_restrictions as $features) {
167
- $restrict_elements = array_merge($restrict_elements, self::getElements($features, ['editor_type' => 'classic']));
168
- }
169
-
170
- // apply the stored restrictions by css
171
- if ($restrict_elements = array_unique($restrict_elements)) {
172
- //add inline styles
173
- ppc_add_inline_style('' . implode(',', array_map('esc_attr', $restrict_elements)) . ' {display:none !important;}');
174
- }
175
- }
176
-
177
- /**
178
- * Classic Editor: Apply / Queue editor feature restrictions
179
- */
180
- public static function adminInitClassic($post_type)
181
- {
182
- // Get all user roles.
183
- $user_roles = wp_get_current_user()->roles;
184
- $ce_post_disabled = get_option("capsman_feature_restrict_classic_{$post_type}", []);
185
-
186
- $disabled_elements_post_ = [];
187
- $disabled_elements_post_all = [];
188
-
189
- foreach ($user_roles as $role) {
190
- if (!empty($ce_post_disabled[$role])) {
191
- $disabled_elements_post_[$role] = (array)$ce_post_disabled[$role];
192
- }
193
-
194
- if (!empty($disabled_elements_post_[$role])) {
195
- $disabled_elements_post_all[] = $disabled_elements_post_[$role];
196
- }
197
- }
198
-
199
- // Set default editor tinymce
200
- if (self::recursiveInArray(
201
- '#editor-toolbar #edButtonHTML, #quicktags, #content-html',
202
- $disabled_elements_post_all
203
- )
204
- ) {
205
- add_filter('wp_default_editor', function($default) {
206
- return 'tinymce';
207
- });
208
- }
209
-
210
- // Remove media buttons
211
- if (self::recursiveInArray('media_buttons', $disabled_elements_post_all)
212
- ) {
213
- remove_action('media_buttons', 'media_buttons');
214
- }
215
-
216
- // set meta-box post option
217
- add_action('admin_head', ['PP_Capabilities_Post_Features', 'applyRestrictionsClassic'], 1);
218
- }
219
-
220
- /**
221
- * Gutenberg Editor: Hide UI elements for editor features configured as restricted
222
- */
223
- public static function applyRestrictions($post_type)
224
- {
225
- $restrict_elements = [];
226
-
227
- // Only restrictions associated with this user's role(s) will be applied
228
- $role_restrictions = array_intersect_key(
229
- get_option("capsman_feature_restrict_{$post_type}", []),
230
- array_fill_keys(wp_get_current_user()->roles, true)
231
- );
232
-
233
- foreach($role_restrictions as $features) {
234
- $restrict_elements = array_merge($restrict_elements, self::getElements($features));
235
- }
236
-
237
- // apply the stored restrictions by js and css
238
- if ($restrict_elements = array_unique($restrict_elements)) {
239
-
240
- // script file
241
- wp_register_script(
242
- 'ppc-features-block-script',
243
- plugin_dir_url(CME_FILE) . 'includes/features/features-block-script.js',
244
- ['wp-blocks', 'wp-edit-post']
245
- );
246
-
247
- //localize script
248
- wp_localize_script(
249
- 'ppc-features-block-script',
250
- 'ppc_features',
251
- [
252
- 'disabled_panel' => implode(',', $restrict_elements),
253
- 'taxonomies' => implode(",", get_taxonomies())
254
- ]
255
- );
256
-
257
- // register block editor script
258
- register_block_type(
259
- 'ppc/features-block-script',
260
- ['editor_script' => 'ppc-features-block-script']
261
- );
262
-
263
- //add inline styles
264
- ppc_add_inline_style('' . implode(',', array_map('esc_attr', $restrict_elements)) . ' {display:none !important;}');
265
- }
266
- }
267
-
268
- private static function getElements($feature_names, $args = []) {
269
- $is_classic = (!empty($args['editor_type']) && ('classic' == $args['editor_type']));
270
-
271
- $feature_names = (array) $feature_names;
272
-
273
- $arr = ($is_classic) ? self::elementsLayoutClassic() : self::elementsLayout();
274
-
275
- $elements = [];
276
-
277
- foreach($arr as $section_features) {
278
- foreach($section_features as $_feature_name => $feature_info) {
279
- if (in_array($_feature_name, $feature_names)) {
280
- if (!empty($feature_info['elements'])) {
281
- $elements = array_merge($elements, explode(',', $feature_info['elements']));
282
- } else {
283
- $elements[]= $_feature_name;
284
- }
285
- }
286
- }
287
- }
288
-
289
- return $elements;
290
- }
291
-
292
- public static function elementsLayout()
293
- {
294
- $elements = [
295
- esc_html__('Top Bar - Left', 'capabilities-pro') => [
296
- 'add_block' => ['label' => esc_html__('Add block', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .edit-post-header-toolbar__inserter-toggle.has-icon'],
297
- 'modes' => ['label' => esc_html__('Modes', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .components-dropdown:first-of-type'],
298
- 'undo' => ['label' => esc_html__('Undo', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .editor-history__undo'],
299
- 'redo' => ['label' => esc_html__('Redo', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .editor-history__redo'],
300
- 'details' => ['label' => esc_html__('Details', 'capsman-enhanced'), 'elements' => '.edit-post-header__toolbar .table-of-contents'],
301
- 'outline' => ['label' => esc_html__('Outline', 'capsman-enhanced'), 'elements' => '.edit-post-header__toolbar .edit-post-header-toolbar__list-view-toggle'],
302
- ],
303
-
304
- esc_html__('Top Bar - Right', 'capabilities-pro') => [
305
- 'save_draft' => ['label' => esc_html__('Save Draft', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .components-button.editor-post-save-draft'],
306
- 'switch_to_draft' => ['label' => esc_html__('Switch to draft', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .components-button.editor-post-switch-to-draft'],
307
- 'preview' => ['label' => esc_html__('Preview', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .block-editor-post-preview__dropdown'],
308
- 'publish' => ['label' => esc_html__('Publish / Update', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .editor-post-publish-button__button'],
309
- 'settings' => ['label' => esc_html__('Settings', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .interface-pinned-items button'],
310
- 'options' => ['label' => esc_html__('Options', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .edit-post-more-menu .components-button'],
311
- ],
312
-
313
- esc_html__('Body', 'capabilities-pro') => [
314
- 'edit_title' => ['label' => esc_html__('Edit title', 'capsman-enhanced'), 'elements' => '.wp-block.editor-post-title__block'],
315
- 'content' => ['label' => esc_html__('Content', 'capsman-enhanced'), 'elements' => '.block-editor-block-list__layout'],
316
- ],
317
-
318
- esc_html__('Document Panel', 'capabilities-pro') => [
319
- 'status_visibility' => ['label' => esc_html__('Status & visibility', 'capsman-enhanced'), 'elements' => 'post-status'],
320
- 'template' => ['label' => esc_html__('Template', 'capsman-enhanced'), 'elements' => 'template'],
321
- 'permalink' => ['label' => esc_html__('Permalink', 'capsman-enhanced'), 'elements' => 'post-link'],
322
- 'categories' => ['label' => esc_html__('Categories', 'capsman-enhanced'), 'elements' => 'taxonomy-panel-category'],
323
- 'tags' => ['label' => esc_html__('Tags', 'capsman-enhanced'), 'elements' => 'taxonomy-panel-post_tag'],
324
- ]
325
- ];
326
-
327
- end($elements);
328
- $k = key($elements);
329
-
330
- foreach (get_taxonomies(['show_ui' => true], 'object') as $taxonomy => $tx_obj) {
331
- if (!in_array($taxonomy, ['category', 'post_tag', 'link_category'])) {
332
- $elements[$k][$tx_obj->name] = ['label' => $tx_obj->label, 'elements' => "taxonomy-panel-$taxonomy"];
333
- }
334
- }
335
-
336
- $elements[$k] = array_merge($elements[$k], [
337
- 'featured_image' => ['label' => esc_html__('Featured image', 'capsman-enhanced'), 'elements' => 'featured-image'],
338
- 'excerpt' => ['label' => esc_html__('Excerpt', 'capsman-enhanced'), 'elements' => 'post-excerpt'],
339
- 'discussion' => ['label' => esc_html__('Discussion', 'capsman-enhanced'), 'elements' => 'discussion-panel'],
340
- 'post_attributes' => ['label' => esc_html__('Post Attributes', 'capsman-enhanced'), 'elements' => 'page-attributes'],
341
- ]);
342
-
343
- $elements[esc_html__('Block Panel', 'capabilities-pro')] = [
344
- 'block_panel' => ['label' => esc_html__('Block Panel', 'capsman-enhanced'), 'elements' => '.block-editor-block-inspector'],
345
- 'paragraph' => ['label' => esc_html__('Paragraph', 'capsman-enhanced'), 'elements' => '.block-editor-block-card'],
346
- 'typography' => ['label' => esc_html__('Typography', 'capsman-enhanced'), 'elements' => '.block-editor-block-inspector .components-panel__body:first-of-type'],
347
- 'color' => ['label' => esc_html__('Color settings', 'capsman-enhanced'), 'elements' => '.block-editor-panel-color-gradient-settings'],
348
- 'text_settings' => ['label' => esc_html__('Text settings', 'capsman-enhanced'), 'elements' => '.block-editor-panel-color-gradient-settings + .components-panel__body'],
349
- ];
350
-
351
- return apply_filters('pp_capabilities_post_feature_elements', $elements);
352
- }
353
- }
1
+ <?php
2
+
3
+ class PP_Capabilities_Post_Features {
4
+
5
+ /**
6
+ * Recursive search in array.
7
+ *
8
+ * @param string $needle
9
+ * @param array $haystack
10
+ *
11
+ * @return bool
12
+ */
13
+ private static function recursiveInArray($needle, $haystack)
14
+ {
15
+ if ('' === $haystack) {
16
+ return false;
17
+ }
18
+
19
+ if (!$haystack) {
20
+ return false;
21
+ }
22
+
23
+ foreach ($haystack as $stalk) {
24
+ if ($needle === $stalk
25
+ || (is_array($stalk)
26
+ && self::recursiveInArray($needle, $stalk)
27
+ )
28
+ ) {
29
+ return true;
30
+ }
31
+ }
32
+
33
+ return false;
34
+ }
35
+
36
+ public static function elementsLayoutClassic()
37
+ {
38
+ $elements = [];
39
+
40
+ $elements[esc_html__('Top Tabs', 'capsman-enhanced')] = [
41
+ '#contextual-help-link-wrap' => ['label' => esc_html__('Help', 'capsman-enhanced')],
42
+ '#screen-options-link-wrap' => ['label' => esc_html__('Screen Options', 'capsman-enhanced')],
43
+ ];
44
+
45
+ $elements[esc_html__('Editor', 'capsman-enhanced')] = [
46
+ '.page-title-action' => ['label' => esc_html__('Add New', 'capsman-enhanced')],
47
+ '#title' => ['label' => esc_html__('Title', 'capsman-enhanced'), 'elements' => '#titlediv, #title, #titlewrap'],
48
+ '#postdivrich' => ['label' => esc_html__('Editor', 'capsman-enhanced')],
49
+ '#pageslugdiv' => ['label' => esc_html__('Permalink', 'capsman-enhanced')],
50
+ '#media_buttons' => ['label' => esc_html__('Media Buttons (all)', 'capsman-enhanced'), 'elements' => '#media-buttons, #wp-content-media-buttons'],
51
+ '#html_editor_button' => ['label' => esc_html__('HTML Editor Button', 'capsman-enhanced'),'elements' => '#editor-toolbar #edButtonHTML, #quicktags, #content-html, .wp-switch-editor.switch-html'],
52
+ '#wp-word-count' => ['label' => esc_html__('Word count', 'capsman-enhanced')],
53
+ ];
54
+
55
+ $elements[esc_html__('Publish Box', 'capsman-enhanced')] = [
56
+ '#submitdiv' => ['label' => esc_html__('Publish Box', 'capsman-enhanced')],
57
+ '#save-post' => ['label' => esc_html__('Save Draft', 'capsman-enhanced')],
58
+ '#post-preview' => ['label' => esc_html__('Preview', 'capsman-enhanced')],
59
+ '.misc-pub-post-status' => ['label' => esc_html__('Publish Status ', 'capsman-enhanced')],
60
+ '.misc-pub-visibility' => ['label' => esc_html__('Publish Visibility', 'capsman-enhanced')],
61
+ '#passworddiv' => ['label' => esc_html__('Password Protect This Post', 'capsman-enhanced')],
62
+ '#misc-publishing-actions' => ['label' => esc_html__('Publish Actions', 'capsman-enhanced')],
63
+ '.misc-pub-curtime' => ['label' => esc_html__('Publish Schedule', 'capsman-enhanced')],
64
+ '#date' => ['label' => esc_html__('Date', 'capsman-enhanced'), 'elements' => '#date, #datediv, th.column-date, td.date, div.curtime'],
65
+ '#publish' => ['label' => esc_html__('Publish', 'capsman-enhanced')],
66
+ ];
67
+
68
+ $elements[esc_html__('Taxonomy Boxes', 'capsman-enhanced')] = [
69
+ '#category' => ['label' => esc_html__('Categories', 'capsman-enhanced'), 'elements' => '#categories, #categorydiv, #categorydivsb, th.column-categories, td.categories'],
70
+ '#category-add-toggle' => ['label' => esc_html__('Add New Category', 'capsman-enhanced')],
71
+ '#post_tag' => ['label' => esc_html__('Tags', 'capsman-enhanced'), 'elements' => '#tags, #tagsdiv,#tagsdivsb,#tagsdiv-post_tag, th.column-tags, td.tags'],
72
+ ];
73
+
74
+ end($elements);
75
+ $k = key($elements);
76
+
77
+ foreach (get_taxonomies(['show_ui' => true], 'object') as $taxonomy => $tx_obj) {
78
+ if (!in_array($taxonomy, ['category', 'post_tag', 'link_category'])) {
79
+ $elements[$k]["#{$tx_obj->name}div"] = ['label' => $tx_obj->label,'elements'=>"#{$tx_obj->name}, #{$tx_obj->name}div,#{$tx_obj->name}divsb,#tagsdiv-{$tx_obj->name}, th.column-{$tx_obj->name}, td.{$tx_obj->name}"];
80
+ }
81
+ }
82
+
83
+ $elements[esc_html__('Page Boxes', 'capsman-enhanced')] = [
84
+ '#pageparentdiv' => ['label' => esc_html__('Page Attributes', 'capsman-enhanced')],
85
+ '#parent_id' => ['label' => esc_html__('Parent', 'capsman-enhanced'), 'elements' => 'p.parent-id-label-wrapper, #parent_id'],
86
+ '#page_template' => ['label' => esc_html__('Page Template', 'capsman-enhanced')],
87
+ 'p.menu-order-label-wrapper' => ['label' => esc_html__('Order', 'capsman-enhanced')],
88
+ ];
89
+
90
+ $elements[esc_html__('Other Boxes', 'capsman-enhanced')] = [
91
+ '#postimagediv' => ['label' => esc_html__('Featured Image', 'capsman-enhanced')],
92
+ '#slug' => ['label' => esc_html__('Post Slug', 'capsman-enhanced'), 'elements' => '#slugdiv,#edit-slug-box'],
93
+ '#commentstatusdiv' => ['label' => esc_html__('Discussion', 'capsman-enhanced')],
94
+ ];
95
+
96
+ end($elements);
97
+ $k = key($elements);
98
+
99
+ $post_type_supports = [];
100
+
101
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
102
+
103
+ foreach($def_post_types as $post_type) {
104
+ $post_type_supports = array_merge($post_type_supports, get_all_post_type_supports($post_type));
105
+ }
106
+
107
+ foreach (array_keys($post_type_supports) as $feature) {
108
+ $label = ucfirst(str_replace(['-', '_'], ' ', $feature));
109
+
110
+ switch ($feature) {
111
+ case 'excerpt' :
112
+ $id = 'postexcerpt';
113
+ break;
114
+
115
+ case 'custom-fields' :
116
+ $id = 'postcustom';
117
+ break;
118
+
119
+ case 'post-formats' :
120
+ $id = 'format';
121
+ break;
122
+
123
+ case 'author':
124
+ case 'excerpt':
125
+ case 'trackbacks':
126
+ case 'comments':
127
+ case 'revisions':
128
+ //default:
129
+ $id = $feature;
130
+ break;
131
+
132
+ default:
133
+ continue 2;
134
+ }
135
+
136
+ $elements[$k][$feature] = [
137
+ 'label' => $label,
138
+ 'elements' => '#' . $id
139
+ . ', #' . $id . 'div'
140
+ . ', th.column-' . $id
141
+ . ', td.' . $id
142
+ ]; //th and td for raw in edit screen
143
+ }
144
+
145
+ return apply_filters('pp_capabilities_post_feature_elements_classic', $elements);
146
+ }
147
+
148
+
149
+ /**
150
+ * Classic Editor screen: Output Styles to Hide UI elements for Editor Features configured as restricted
151
+ */
152
+ public static function applyRestrictionsClassic()
153
+ {
154
+ $restrict_elements = [];
155
+
156
+ if (!$post_type = pp_capabilities_get_post_type()) {
157
+ return;
158
+ }
159
+
160
+ // Only restrictions associated with this user's role(s) will be applied
161
+ $role_restrictions = array_intersect_key(
162
+ get_option("capsman_feature_restrict_classic_{$post_type}", []),
163
+ array_fill_keys(wp_get_current_user()->roles, true)
164
+ );
165
+
166
+ foreach($role_restrictions as $features) {
167
+ $restrict_elements = array_merge($restrict_elements, self::getElements($features, ['editor_type' => 'classic']));
168
+ }
169
+
170
+ // apply the stored restrictions by css
171
+ if ($restrict_elements = array_unique($restrict_elements)) {
172
+ //add inline styles
173
+ ppc_add_inline_style('' . implode(',', array_map('esc_attr', $restrict_elements)) . ' {display:none !important;}');
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Classic Editor: Apply / Queue editor feature restrictions
179
+ */
180
+ public static function adminInitClassic($post_type)
181
+ {
182
+ // Get all user roles.
183
+ $user_roles = wp_get_current_user()->roles;
184
+ $ce_post_disabled = get_option("capsman_feature_restrict_classic_{$post_type}", []);
185
+
186
+ $disabled_elements_post_ = [];
187
+ $disabled_elements_post_all = [];
188
+
189
+ foreach ($user_roles as $role) {
190
+ if (!empty($ce_post_disabled[$role])) {
191
+ $disabled_elements_post_[$role] = (array)$ce_post_disabled[$role];
192
+ }
193
+
194
+ if (!empty($disabled_elements_post_[$role])) {
195
+ $disabled_elements_post_all[] = $disabled_elements_post_[$role];
196
+ }
197
+ }
198
+
199
+ // Set default editor tinymce
200
+ if (self::recursiveInArray(
201
+ '#editor-toolbar #edButtonHTML, #quicktags, #content-html',
202
+ $disabled_elements_post_all
203
+ )
204
+ ) {
205
+ add_filter('wp_default_editor', function($default) {
206
+ return 'tinymce';
207
+ });
208
+ }
209
+
210
+ // Remove media buttons
211
+ if (self::recursiveInArray('media_buttons', $disabled_elements_post_all)
212
+ ) {
213
+ remove_action('media_buttons', 'media_buttons');
214
+ }
215
+
216
+ // set meta-box post option
217
+ add_action('admin_head', ['PP_Capabilities_Post_Features', 'applyRestrictionsClassic'], 1);
218
+ }
219
+
220
+ /**
221
+ * Gutenberg Editor: Hide UI elements for editor features configured as restricted
222
+ */
223
+ public static function applyRestrictions($post_type)
224
+ {
225
+ $restrict_elements = [];
226
+
227
+ // Only restrictions associated with this user's role(s) will be applied
228
+ $role_restrictions = array_intersect_key(
229
+ get_option("capsman_feature_restrict_{$post_type}", []),
230
+ array_fill_keys(wp_get_current_user()->roles, true)
231
+ );
232
+
233
+ foreach($role_restrictions as $features) {
234
+ $restrict_elements = array_merge($restrict_elements, self::getElements($features));
235
+ }
236
+
237
+ // apply the stored restrictions by js and css
238
+ if ($restrict_elements = array_unique($restrict_elements)) {
239
+
240
+ // script file
241
+ wp_register_script(
242
+ 'ppc-features-block-script',
243
+ plugin_dir_url(CME_FILE) . 'includes/features/features-block-script.js',
244
+ ['wp-blocks', 'wp-edit-post']
245
+ );
246
+
247
+ //localize script
248
+ wp_localize_script(
249
+ 'ppc-features-block-script',
250
+ 'ppc_features',
251
+ [
252
+ 'disabled_panel' => implode(',', $restrict_elements),
253
+ 'taxonomies' => implode(",", get_taxonomies())
254
+ ]
255
+ );
256
+
257
+ // register block editor script
258
+ register_block_type(
259
+ 'ppc/features-block-script',
260
+ ['editor_script' => 'ppc-features-block-script']
261
+ );
262
+
263
+ //add inline styles
264
+ ppc_add_inline_style('' . implode(',', array_map('esc_attr', $restrict_elements)) . ' {display:none !important;}');
265
+ }
266
+ }
267
+
268
+ private static function getElements($feature_names, $args = []) {
269
+ $is_classic = (!empty($args['editor_type']) && ('classic' == $args['editor_type']));
270
+
271
+ $feature_names = (array) $feature_names;
272
+
273
+ $arr = ($is_classic) ? self::elementsLayoutClassic() : self::elementsLayout();
274
+
275
+ $elements = [];
276
+
277
+ foreach($arr as $section_features) {
278
+ foreach($section_features as $_feature_name => $feature_info) {
279
+ if (in_array($_feature_name, $feature_names)) {
280
+ if (!empty($feature_info['elements'])) {
281
+ $elements = array_merge($elements, explode(',', $feature_info['elements']));
282
+ } else {
283
+ $elements[]= $_feature_name;
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ return $elements;
290
+ }
291
+
292
+ public static function elementsLayout()
293
+ {
294
+ $elements = [
295
+ esc_html__('Top Bar - Left', 'capabilities-pro') => [
296
+ 'add_block' => ['label' => esc_html__('Add block', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .edit-post-header-toolbar__inserter-toggle.has-icon'],
297
+ 'modes' => ['label' => esc_html__('Modes', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .components-dropdown:first-of-type'],
298
+ 'undo' => ['label' => esc_html__('Undo', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .editor-history__undo'],
299
+ 'redo' => ['label' => esc_html__('Redo', 'capsman-enhanced'), 'elements' => '.edit-post-header-toolbar .editor-history__redo'],
300
+ 'details' => ['label' => esc_html__('Details', 'capsman-enhanced'), 'elements' => '.edit-post-header__toolbar .table-of-contents'],
301
+ 'outline' => ['label' => esc_html__('Outline', 'capsman-enhanced'), 'elements' => '.edit-post-header__toolbar .edit-post-header-toolbar__list-view-toggle'],
302
+ ],
303
+
304
+ esc_html__('Top Bar - Right', 'capabilities-pro') => [
305
+ 'save_draft' => ['label' => esc_html__('Save Draft', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .components-button.editor-post-save-draft'],
306
+ 'switch_to_draft' => ['label' => esc_html__('Switch to draft', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .components-button.editor-post-switch-to-draft'],
307
+ 'preview' => ['label' => esc_html__('Preview', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .block-editor-post-preview__dropdown'],
308
+ 'publish' => ['label' => esc_html__('Publish / Update', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .editor-post-publish-button__button'],
309
+ 'settings' => ['label' => esc_html__('Settings', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .interface-pinned-items button'],
310
+ 'options' => ['label' => esc_html__('Options', 'capsman-enhanced'), 'elements' => '.edit-post-header__settings .edit-post-more-menu .components-button'],
311
+ ],
312
+
313
+ esc_html__('Body', 'capabilities-pro') => [
314
+ 'edit_title' => ['label' => esc_html__('Edit title', 'capsman-enhanced'), 'elements' => '.wp-block.editor-post-title__block, .wp-block.editor-post-title'],
315
+ 'content' => ['label' => esc_html__('Content', 'capsman-enhanced'), 'elements' => '.block-editor-block-list__layout'],
316
+ ],
317
+
318
+ esc_html__('Document Panel', 'capabilities-pro') => [
319
+ 'status_visibility' => ['label' => esc_html__('Status & visibility', 'capsman-enhanced'), 'elements' => 'post-status'],
320
+ 'template' => ['label' => esc_html__('Template', 'capsman-enhanced'), 'elements' => 'template'],
321
+ 'permalink' => ['label' => esc_html__('Permalink', 'capsman-enhanced'), 'elements' => 'post-link'],
322
+ 'categories' => ['label' => esc_html__('Categories', 'capsman-enhanced'), 'elements' => 'taxonomy-panel-category'],
323
+ 'tags' => ['label' => esc_html__('Tags', 'capsman-enhanced'), 'elements' => 'taxonomy-panel-post_tag'],
324
+ ]
325
+ ];
326
+
327
+ end($elements);
328
+ $k = key($elements);
329
+
330
+ foreach (get_taxonomies(['show_ui' => true], 'object') as $taxonomy => $tx_obj) {
331
+ if (!in_array($taxonomy, ['category', 'post_tag', 'link_category'])) {
332
+ $elements[$k][$tx_obj->name] = ['label' => $tx_obj->label, 'elements' => "taxonomy-panel-$taxonomy"];
333
+ }
334
+ }
335
+
336
+ $elements[$k] = array_merge($elements[$k], [
337
+ 'featured_image' => ['label' => esc_html__('Featured image', 'capsman-enhanced'), 'elements' => 'featured-image'],
338
+ 'excerpt' => ['label' => esc_html__('Excerpt', 'capsman-enhanced'), 'elements' => 'post-excerpt'],
339
+ 'discussion' => ['label' => esc_html__('Discussion', 'capsman-enhanced'), 'elements' => 'discussion-panel'],
340
+ 'post_attributes' => ['label' => esc_html__('Post Attributes', 'capsman-enhanced'), 'elements' => 'page-attributes'],
341
+ ]);
342
+
343
+ $elements[esc_html__('Block Panel', 'capabilities-pro')] = [
344
+ 'block_panel' => ['label' => esc_html__('Block Panel', 'capsman-enhanced'), 'elements' => '.block-editor-block-inspector'],
345
+ 'paragraph' => ['label' => esc_html__('Paragraph', 'capsman-enhanced'), 'elements' => '.block-editor-block-card'],
346
+ 'typography' => ['label' => esc_html__('Typography', 'capsman-enhanced'), 'elements' => '.block-editor-block-inspector .components-panel__body:first-of-type'],
347
+ 'color' => ['label' => esc_html__('Color settings', 'capsman-enhanced'), 'elements' => '.block-editor-panel-color-gradient-settings'],
348
+ 'text_settings' => ['label' => esc_html__('Text settings', 'capsman-enhanced'), 'elements' => '.block-editor-panel-color-gradient-settings + .components-panel__body'],
349
+ ];
350
+
351
+ return apply_filters('pp_capabilities_post_feature_elements', $elements);
352
+ }
353
+ }
includes/filters-admin.php CHANGED
@@ -1,44 +1,44 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Filters which are loaded for certain admin URLs
6
- *
7
- */
8
- class CME_AdminMenuNoPrivWorkaround {
9
- var $create_posts_cap = '';
10
-
11
- function __construct() {
12
- global $pagenow;
13
-
14
- if ( 'edit.php' == $pagenow ) {
15
- // Prevent lack of create_posts capability from completely blocking admin menu access to a post type.
16
- // The "Add New" page is already successfully blocked by other means.
17
- add_action( '_admin_menu', array( $this, 'menu_nopriv_workaround_enable' ), PHP_INT_MAX );
18
- add_action( 'admin_menu', array( $this, 'menu_nopriv_workaround_disable' ), - PHP_INT_MAX );
19
- }
20
- }
21
-
22
- function menu_nopriv_workaround_enable() {
23
- global $typenow;
24
-
25
- if ( $post_type_obj = get_post_type_object( $typenow ) ) {
26
- $this->create_posts_cap = $post_type_obj->cap->create_posts;
27
- add_filter( 'user_has_cap', array( $this, 'admin_menu_caps' ), PHP_INT_MAX, 3 );
28
- }
29
- }
30
-
31
- function menu_nopriv_workaround_disable() {
32
- if ( $this->create_posts_cap ) {
33
- remove_filter( 'user_has_cap', array( $this, 'admin_menu_caps' ), PHP_INT_MAX, 3 );
34
- }
35
- }
36
-
37
- function admin_menu_caps( $wp_sitecaps, $reqd_caps, $args ) {
38
- if ( is_array($args) && isset($args[0]) && ( $this->create_posts_cap == $args[0] ) ) {
39
- $wp_sitecaps[ $args[0] ] = true;
40
- }
41
-
42
- return $wp_sitecaps;
43
- }
44
- } // end class
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Filters which are loaded for certain admin URLs
6
+ *
7
+ */
8
+ class CME_AdminMenuNoPrivWorkaround {
9
+ var $create_posts_cap = '';
10
+
11
+ function __construct() {
12
+ global $pagenow;
13
+
14
+ if ( 'edit.php' == $pagenow ) {
15
+ // Prevent lack of create_posts capability from completely blocking admin menu access to a post type.
16
+ // The "Add New" page is already successfully blocked by other means.
17
+ add_action( '_admin_menu', array( $this, 'menu_nopriv_workaround_enable' ), PHP_INT_MAX );
18
+ add_action( 'admin_menu', array( $this, 'menu_nopriv_workaround_disable' ), - PHP_INT_MAX );
19
+ }
20
+ }
21
+
22
+ function menu_nopriv_workaround_enable() {
23
+ global $typenow;
24
+
25
+ if ( $post_type_obj = get_post_type_object( $typenow ) ) {
26
+ $this->create_posts_cap = $post_type_obj->cap->create_posts;
27
+ add_filter( 'user_has_cap', array( $this, 'admin_menu_caps' ), PHP_INT_MAX, 3 );
28
+ }
29
+ }
30
+
31
+ function menu_nopriv_workaround_disable() {
32
+ if ( $this->create_posts_cap ) {
33
+ remove_filter( 'user_has_cap', array( $this, 'admin_menu_caps' ), PHP_INT_MAX, 3 );
34
+ }
35
+ }
36
+
37
+ function admin_menu_caps( $wp_sitecaps, $reqd_caps, $args ) {
38
+ if ( is_array($args) && isset($args[0]) && ( $this->create_posts_cap == $args[0] ) ) {
39
+ $wp_sitecaps[ $args[0] ] = true;
40
+ }
41
+
42
+ return $wp_sitecaps;
43
+ }
44
+ } // end class
includes/filters-woocommerce.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
- /**
3
- * class CME_WooCommerce
4
- *
5
- * Uses WordPress or Woo API to adjust WooCommerce permissions
6
- */
7
- class CME_WooCommerce {
8
- function __construct() {
9
- // Implement duplicate_product capability automatically if current user has it in role.
10
- global $current_user;
11
- if ( ! empty( $current_user->allcaps['duplicate_products'] ) ) {
12
- add_filter( 'woocommerce_duplicate_product_capability', array( &$this, 'implement_duplicate_product_cap' ) );
13
- }
14
-
15
- // Ensure orders can be edited or added based the edit_orders / create_orders capability
16
- add_action( '_admin_menu', array( &$this, 'support_order_caps' ), 1 );
17
- }
18
-
19
- function implement_duplicate_product_cap( $cap ) {
20
- return 'duplicate_products';
21
- }
22
-
23
- function support_order_caps() {
24
- global $submenu;
25
-
26
- if ( $type_obj = get_post_type_object( 'shop_order' ) ) {
27
- $key = 'edit.php?post_type=shop_order';
28
- if ( ! isset( $submenu[$key] ) ) {
29
- $submenu[$key] = array();
30
- }
31
-
32
- $submenu[$key][5] = array( 0 => sprintf( esc_html__( 'All %s' ), $type_obj->labels->name ), 1 => $type_obj->cap->edit_posts, 2 => 'edit.php?post_type=shop_order' );
33
- $submenu[$key][10] = array( esc_html__('Add New'), 1 => $type_obj->cap->create_posts, 2 => 'post-new.php?post_type=shop_order' );
34
- }
35
- }
36
  }
1
+ <?php
2
+ /**
3
+ * class CME_WooCommerce
4
+ *
5
+ * Uses WordPress or Woo API to adjust WooCommerce permissions
6
+ */
7
+ class CME_WooCommerce {
8
+ function __construct() {
9
+ // Implement duplicate_product capability automatically if current user has it in role.
10
+ global $current_user;
11
+ if ( ! empty( $current_user->allcaps['duplicate_products'] ) ) {
12
+ add_filter( 'woocommerce_duplicate_product_capability', array( &$this, 'implement_duplicate_product_cap' ) );
13
+ }
14
+
15
+ // Ensure orders can be edited or added based the edit_orders / create_orders capability
16
+ add_action( '_admin_menu', array( &$this, 'support_order_caps' ), 1 );
17
+ }
18
+
19
+ function implement_duplicate_product_cap( $cap ) {
20
+ return 'duplicate_products';
21
+ }
22
+
23
+ function support_order_caps() {
24
+ global $submenu;
25
+
26
+ if ( $type_obj = get_post_type_object( 'shop_order' ) ) {
27
+ $key = 'edit.php?post_type=shop_order';
28
+ if ( ! isset( $submenu[$key] ) ) {
29
+ $submenu[$key] = array();
30
+ }
31
+
32
+ $submenu[$key][5] = array( 0 => sprintf( esc_html__( 'All %s' ), $type_obj->labels->name ), 1 => $type_obj->cap->edit_posts, 2 => 'edit.php?post_type=shop_order' );
33
+ $submenu[$key][10] = array( esc_html__('Add New'), 1 => $type_obj->cap->create_posts, 2 => 'post-new.php?post_type=shop_order' );
34
+ }
35
+ }
36
  }
includes/filters-wp_rest_workarounds.php CHANGED
@@ -1,269 +1,269 @@
1
- <?php
2
- namespace PublishPress\Capabilities;
3
-
4
- /**
5
- * PublishPress\Capabilities\WP_REST_Workarounds class
6
- *
7
- * @author Kevin Behrens
8
- * @copyright Copyright (c) 2020, PublishPress
9
- * @link https://publishpress.com/
10
- *
11
- */
12
- class WP_REST_Workarounds
13
- {
14
- private $post_id = 0;
15
- private $is_posts_request = false;
16
- private $is_view_method = false;
17
- private $params = [];
18
- private $skip_filtering = false;
19
-
20
- public function __construct() {
21
- add_filter('rest_pre_dispatch', [$this, 'fltRestPreDispatch'], 10, 3);
22
- add_filter('user_has_cap', [$this, 'fltPublishCapReplacement'], 5, 3);
23
-
24
- add_filter('wp_insert_post_data', [$this, 'fltInsertPostData'], 10, 2);
25
- add_filter('edit_post_status', [$this, 'fltPostStatus'], 10, 2);
26
- add_filter('user_has_cap', [$this, 'fltRegulateUnpublish'], 5, 3);
27
-
28
- add_action('admin_print_styles-post.php', [$this, 'actAdminPrintScripts']);
29
- }
30
-
31
- /**
32
- * Work around Gutenberg editor enforcing publish_posts capability instead of edit_published_posts.
33
- *
34
- * Allow edit_published capability to satisfy publish capability requirement if:
35
- * - The query pertains to a specific post
36
- * - The post type and its capabilities are defined and match the current publish capability requirement
37
- * - The post is already published with a public status, or scheduled
38
- *
39
- * Filter hook: 'user_has_cap'
40
- *
41
- * @author Kevin Behrens
42
- * @link https://core.trac.wordpress.org/ticket/47443
43
- * @link https://github.com/WordPress/gutenberg/issues/13342
44
- * @param array $wp_sitecaps Array of user capabilities acknowledged for this request.
45
- * @param array $reqd_caps Capability requirements
46
- * @param array $args Additional arguments passed into user_has_cap filter
47
- */
48
- public function fltPublishCapReplacement($wp_sitecaps, $reqd_caps, $args)
49
- {
50
- global $pagenow;
51
-
52
- if ($this->skip_filtering || (!in_array($pagenow, ['post.php', 'post-new.php']) && (!defined('REST_REQUEST') || !constant('REST_REQUEST')))) {
53
- return $wp_sitecaps;
54
- }
55
-
56
- $reqd_caps = (array) $reqd_caps;
57
-
58
- if ($reqd_cap = reset($reqd_caps)) {
59
- // slight compromise for perf: apply this workaround only when cap->publish_posts property for post type follows typical pattern (publish_*)
60
- if (0 === strpos($reqd_cap, 'publish_')) {
61
- if (!empty($wp_sitecaps[$reqd_cap])) {
62
- return $wp_sitecaps;
63
- }
64
-
65
- if (!$_post = get_post($this->getPostID())) {
66
- return $wp_sitecaps;
67
- }
68
-
69
- $type_obj = get_post_type_object($_post->post_type);
70
- $status_obj = get_post_status_object($_post->post_status);
71
-
72
- if ($type_obj && !empty($type_obj->cap)
73
- && !empty($type_obj->cap->publish_posts) && !empty($type_obj->cap->edit_published_posts)
74
- && $type_obj->cap->publish_posts == $reqd_cap
75
- && $status_obj && (!empty($status_obj->public) || 'future' == $_post->post_status)
76
- ) {
77
- if (!empty($wp_sitecaps[$type_obj->cap->edit_published_posts])) {
78
- $wp_sitecaps[$reqd_cap] = true;
79
- }
80
- }
81
- }
82
- }
83
-
84
- return $wp_sitecaps;
85
- }
86
-
87
- /**
88
- * Work around WordPress allowing user who can "edit_published_posts" but not "publish_posts" to unpublish a post.
89
- *
90
- * This is hooked to the edit_post_status filter and also called internally from REST update_item capability check (for Gutenberg)
91
- * and wp_insert_post_data (for Classic Editor and Quick Edit)
92
- *
93
- * Filter hook: 'edit_post_status'
94
- *
95
- * @author Kevin Behrens
96
- * @param int $post_status Post status being set
97
- * @param int $post_id ID of post being modified
98
- */
99
- public function fltPostStatus($post_status, $post_id) {
100
- global $current_user;
101
-
102
- $new_status_obj = get_post_status_object($post_status);
103
- if (!$new_status_obj || !empty($new_status_obj->internal)) {
104
- return $post_status;
105
- }
106
-
107
- if (!$_post = get_post($post_id)) {
108
- return $post_status;
109
- }
110
-
111
- $type_obj = get_post_type_object($_post->post_type);
112
- $status_obj = get_post_status_object($_post->post_status);
113
-
114
- if ($type_obj && $status_obj && (!empty($status_obj->public) || !empty($status_obj->private) || 'future' == $_post->post_status)) {
115
- // Apply this workaround only if current user has $type_obj->cap->edit_published_posts
116
- if (isset($type_obj->cap->edit_published_posts) && !empty($current_user->allcaps[$type_obj->cap->edit_published_posts])) {
117
- $this->skip_filtering = true;
118
-
119
- if (!current_user_can($type_obj->cap->publish_posts)) {
120
- $post_status = $_post->post_status;
121
- }
122
-
123
- $this->skip_filtering = false;
124
- }
125
- }
126
-
127
- return $post_status;
128
- }
129
-
130
- /**
131
- * Regulate post unpublishing on Classic Editor and Quick Edit updates:
132
- * If a user can't publish a post, don't let them unpublish it either.
133
- *
134
- * Filter hook: 'wp_insert_post_data'
135
- *
136
- * @param array $data Parsed array of Post data being set
137
- * @param array $postarr ARray of current post data
138
- */
139
- public function fltInsertPostData($data, $postarr) {
140
- if (!empty($data['post_status']) && !empty($postarr['post_ID'])) {
141
- $data['post_status'] = $this->fltPostStatus($data['post_status'], $postarr['post_ID']);
142
- }
143
-
144
- return $data;
145
- }
146
-
147
- /**
148
- * Regulate post unpublishing on Gutenberg "Switch to Draft"
149
- * If a user can't publish a post, don't let them unpublish it either.
150
- *
151
- * Filter hook: user_has_cap
152
- *
153
- * @param array $wp_sitecaps Array of user capabilities acknowledged for this request.
154
- * @param array $reqd_caps Capability requirements
155
- * @param array $args Additional arguments passed into user_has_cap filter
156
- */
157
- public function fltRegulateUnpublish($wp_sitecaps, $reqd_caps, $args)
158
- {
159
- if (!defined('REST_REQUEST') || !REST_REQUEST || !$this->is_posts_request || !$this->post_id || $this->skip_filtering) {
160
- return $wp_sitecaps;
161
- }
162
-
163
- if ($reqd_cap = reset($reqd_caps)) {
164
- // slight compromise for perf: apply this workaround only when cap->edit_published_posts property for post type follows typical pattern (edit_published_*)
165
- if (0 === strpos($reqd_cap, 'edit_published_')) {
166
- if ($this->params && !empty($this->params['status'])) {
167
- $set_status = $this->fltPostStatus($this->params['status'], $this->post_id);
168
- if ($set_status != $this->params['status']) {
169
- unset($wp_sitecaps[$reqd_cap]);
170
- }
171
- }
172
- }
173
- }
174
-
175
- return $wp_sitecaps;
176
- }
177
-
178
- /**
179
- * If we are blocking Gutenberg "Switch to Draft" by capability filtering, also hide the button
180
- *
181
- * Action hook: 'admin_print_styles-post.php'
182
- */
183
- public function actAdminPrintScripts() {
184
- global $current_user, $post;
185
-
186
- if (empty($post) || !did_action('enqueue_block_editor_assets')) {
187
- return;
188
- }
189
-
190
- $status_obj = get_post_status_object($post->post_status);
191
-
192
- if (!$status_obj || (empty($status_obj->public) && empty($status_obj->private))) {
193
- return;
194
- }
195
-
196
- $type_obj = get_post_type_object($post->post_type);
197
- $this->skip_filtering = true;
198
-
199
- if ($type_obj && !current_user_can($type_obj->cap->publish_posts) && current_user_can($type_obj->cap->edit_published_posts)): ?>
200
- <style type="text/css">button.editor-post-switch-to-draft {display:none;}</style>
201
- <?php endif;
202
-
203
- $this->skip_filtering = false;
204
- }
205
-
206
- /**
207
- * Log REST query parameters for possible use by subsequent filters
208
- *
209
- * Action hook: 'rest_pre_dispatch'
210
- */
211
- public function fltRestPreDispatch($rest_response, $rest_server, $request)
212
- {
213
- $method = $request->get_method();
214
- $path = $request->get_route();
215
-
216
- foreach ($rest_server->get_routes() as $route => $handlers) {
217
- if (!$match = preg_match( '@^' . $route . '$@i', $path, $matches )) {
218
- continue;
219
- }
220
-
221
- $args = [];
222
- foreach ($matches as $param => $value) {
223
- if (!is_int($param)) {
224
- $args[ $param ] = $value;
225
- }
226
- }
227
-
228
- foreach ($handlers as $handler) {
229
- if (is_array($handler['callback']) && isset($handler['callback'][0]) && is_object($handler['callback'][0])
230
- && 'WP_REST_Posts_Controller' == get_class($handler['callback'][0])
231
- ) {
232
- if ( ! $this->post_id = (!empty($args['id'])) ? $args['id'] : 0) {
233
- $this->post_id = (!empty($this->params['id'])) ? $this->params['id'] : 0;
234
- }
235
-
236
- $this->is_posts_request = true;
237
- $this->is_view_method = in_array($method, [\WP_REST_Server::READABLE, 'GET']);
238
- $this->params = $request->get_params();
239
-
240
- break 2;
241
- }
242
- }
243
- }
244
-
245
- return $rest_response;
246
- }
247
-
248
- /**
249
- * Determine the Post ID, if any, which this query pertains to
250
- */
251
- private function getPostID()
252
- {
253
- global $post;
254
-
255
- if (defined('REST_REQUEST') && REST_REQUEST && $this->is_posts_request) {
256
- return $this->post_id;
257
- }
258
-
259
- if (!empty($post) && is_object($post)) {
260
- return ('auto-draft' == $post->post_status) ? 0 : $post->ID;
261
- } elseif (isset($_REQUEST['post'])) {
262
- return (int)$_REQUEST['post'];
263
- } elseif (isset($_REQUEST['post_ID'])) {
264
- return (int)$_REQUEST['post_ID'];
265
- } elseif (isset($_REQUEST['post_id'])) {
266
- return (int)$_REQUEST['post_id'];
267
- }
268
- }
269
- }
1
+ <?php
2
+ namespace PublishPress\Capabilities;
3
+
4
+ /**
5
+ * PublishPress\Capabilities\WP_REST_Workarounds class
6
+ *
7
+ * @author Kevin Behrens
8
+ * @copyright Copyright (c) 2020, PublishPress
9
+ * @link https://publishpress.com/
10
+ *
11
+ */
12
+ class WP_REST_Workarounds
13
+ {
14
+ private $post_id = 0;
15
+ private $is_posts_request = false;
16
+ private $is_view_method = false;
17
+ private $params = [];
18
+ private $skip_filtering = false;
19
+
20
+ public function __construct() {
21
+ add_filter('rest_pre_dispatch', [$this, 'fltRestPreDispatch'], 10, 3);
22
+ add_filter('user_has_cap', [$this, 'fltPublishCapReplacement'], 5, 3);
23
+
24
+ add_filter('wp_insert_post_data', [$this, 'fltInsertPostData'], 10, 2);
25
+ add_filter('edit_post_status', [$this, 'fltPostStatus'], 10, 2);
26
+ add_filter('user_has_cap', [$this, 'fltRegulateUnpublish'], 5, 3);
27
+
28
+ add_action('admin_print_styles-post.php', [$this, 'actAdminPrintScripts']);
29
+ }
30
+
31
+ /**
32
+ * Work around Gutenberg editor enforcing publish_posts capability instead of edit_published_posts.
33
+ *
34
+ * Allow edit_published capability to satisfy publish capability requirement if:
35
+ * - The query pertains to a specific post
36
+ * - The post type and its capabilities are defined and match the current publish capability requirement
37
+ * - The post is already published with a public status, or scheduled
38
+ *
39
+ * Filter hook: 'user_has_cap'
40
+ *
41
+ * @author Kevin Behrens
42
+ * @link https://core.trac.wordpress.org/ticket/47443
43
+ * @link https://github.com/WordPress/gutenberg/issues/13342
44
+ * @param array $wp_sitecaps Array of user capabilities acknowledged for this request.
45
+ * @param array $reqd_caps Capability requirements
46
+ * @param array $args Additional arguments passed into user_has_cap filter
47
+ */
48
+ public function fltPublishCapReplacement($wp_sitecaps, $reqd_caps, $args)
49
+ {
50
+ global $pagenow;
51
+
52
+ if ($this->skip_filtering || (!in_array($pagenow, ['post.php', 'post-new.php']) && (!defined('REST_REQUEST') || !constant('REST_REQUEST')))) {
53
+ return $wp_sitecaps;
54
+ }
55
+
56
+ $reqd_caps = (array) $reqd_caps;
57
+
58
+ if ($reqd_cap = reset($reqd_caps)) {
59
+ // slight compromise for perf: apply this workaround only when cap->publish_posts property for post type follows typical pattern (publish_*)
60
+ if (0 === strpos($reqd_cap, 'publish_')) {
61
+ if (!empty($wp_sitecaps[$reqd_cap])) {
62
+ return $wp_sitecaps;
63
+ }
64
+
65
+ if (!$_post = get_post($this->getPostID())) {
66
+ return $wp_sitecaps;
67
+ }
68
+
69
+ $type_obj = get_post_type_object($_post->post_type);
70
+ $status_obj = get_post_status_object($_post->post_status);
71
+
72
+ if ($type_obj && !empty($type_obj->cap)
73
+ && !empty($type_obj->cap->publish_posts) && !empty($type_obj->cap->edit_published_posts)
74
+ && $type_obj->cap->publish_posts == $reqd_cap
75
+ && $status_obj && (!empty($status_obj->public) || 'future' == $_post->post_status)
76
+ ) {
77
+ if (!empty($wp_sitecaps[$type_obj->cap->edit_published_posts])) {
78
+ $wp_sitecaps[$reqd_cap] = true;
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ return $wp_sitecaps;
85
+ }
86
+
87
+ /**
88
+ * Work around WordPress allowing user who can "edit_published_posts" but not "publish_posts" to unpublish a post.
89
+ *
90
+ * This is hooked to the edit_post_status filter and also called internally from REST update_item capability check (for Gutenberg)
91
+ * and wp_insert_post_data (for Classic Editor and Quick Edit)
92
+ *
93
+ * Filter hook: 'edit_post_status'
94
+ *
95
+ * @author Kevin Behrens
96
+ * @param int $post_status Post status being set
97
+ * @param int $post_id ID of post being modified
98
+ */
99
+ public function fltPostStatus($post_status, $post_id) {
100
+ global $current_user;
101
+
102
+ $new_status_obj = get_post_status_object($post_status);
103
+ if (!$new_status_obj || !empty($new_status_obj->internal)) {
104
+ return $post_status;
105
+ }
106
+
107
+ if (!$_post = get_post($post_id)) {
108
+ return $post_status;
109
+ }
110
+
111
+ $type_obj = get_post_type_object($_post->post_type);
112
+ $status_obj = get_post_status_object($_post->post_status);
113
+
114
+ if ($type_obj && $status_obj && (!empty($status_obj->public) || !empty($status_obj->private) || 'future' == $_post->post_status)) {
115
+ // Apply this workaround only if current user has $type_obj->cap->edit_published_posts
116
+ if (isset($type_obj->cap->edit_published_posts) && !empty($current_user->allcaps[$type_obj->cap->edit_published_posts])) {
117
+ $this->skip_filtering = true;
118
+
119
+ if (!current_user_can($type_obj->cap->publish_posts)) {
120
+ $post_status = $_post->post_status;
121
+ }
122
+
123
+ $this->skip_filtering = false;
124
+ }
125
+ }
126
+
127
+ return $post_status;
128
+ }
129
+
130
+ /**
131
+ * Regulate post unpublishing on Classic Editor and Quick Edit updates:
132
+ * If a user can't publish a post, don't let them unpublish it either.
133
+ *
134
+ * Filter hook: 'wp_insert_post_data'
135
+ *
136
+ * @param array $data Parsed array of Post data being set
137
+ * @param array $postarr ARray of current post data
138
+ */
139
+ public function fltInsertPostData($data, $postarr) {
140
+ if (!empty($data['post_status']) && !empty($postarr['post_ID'])) {
141
+ $data['post_status'] = $this->fltPostStatus($data['post_status'], $postarr['post_ID']);
142
+ }
143
+
144
+ return $data;
145
+ }
146
+
147
+ /**
148
+ * Regulate post unpublishing on Gutenberg "Switch to Draft"
149
+ * If a user can't publish a post, don't let them unpublish it either.
150
+ *
151
+ * Filter hook: user_has_cap
152
+ *
153
+ * @param array $wp_sitecaps Array of user capabilities acknowledged for this request.
154
+ * @param array $reqd_caps Capability requirements
155
+ * @param array $args Additional arguments passed into user_has_cap filter
156
+ */
157
+ public function fltRegulateUnpublish($wp_sitecaps, $reqd_caps, $args)
158
+ {
159
+ if (!defined('REST_REQUEST') || !REST_REQUEST || !$this->is_posts_request || !$this->post_id || $this->skip_filtering) {
160
+ return $wp_sitecaps;
161
+ }
162
+
163
+ if ($reqd_cap = reset($reqd_caps)) {
164
+ // slight compromise for perf: apply this workaround only when cap->edit_published_posts property for post type follows typical pattern (edit_published_*)
165
+ if (0 === strpos($reqd_cap, 'edit_published_')) {
166
+ if ($this->params && !empty($this->params['status'])) {
167
+ $set_status = $this->fltPostStatus($this->params['status'], $this->post_id);
168
+ if ($set_status != $this->params['status']) {
169
+ unset($wp_sitecaps[$reqd_cap]);
170
+ }
171
+ }
172
+ }
173
+ }
174
+
175
+ return $wp_sitecaps;
176
+ }
177
+
178
+ /**
179
+ * If we are blocking Gutenberg "Switch to Draft" by capability filtering, also hide the button
180
+ *
181
+ * Action hook: 'admin_print_styles-post.php'
182
+ */
183
+ public function actAdminPrintScripts() {
184
+ global $current_user, $post;
185
+
186
+ if (empty($post) || !did_action('enqueue_block_editor_assets')) {
187
+ return;
188
+ }
189
+
190
+ $status_obj = get_post_status_object($post->post_status);
191
+
192
+ if (!$status_obj || (empty($status_obj->public) && empty($status_obj->private))) {
193
+ return;
194
+ }
195
+
196
+ $type_obj = get_post_type_object($post->post_type);
197
+ $this->skip_filtering = true;
198
+
199
+ if ($type_obj && !current_user_can($type_obj->cap->publish_posts) && current_user_can($type_obj->cap->edit_published_posts)): ?>
200
+ <style type="text/css">button.editor-post-switch-to-draft {display:none;}</style>
201
+ <?php endif;
202
+
203
+ $this->skip_filtering = false;
204
+ }
205
+
206
+ /**
207
+ * Log REST query parameters for possible use by subsequent filters
208
+ *
209
+ * Action hook: 'rest_pre_dispatch'
210
+ */
211
+ public function fltRestPreDispatch($rest_response, $rest_server, $request)
212
+ {
213
+ $method = $request->get_method();
214
+ $path = $request->get_route();
215
+
216
+ foreach ($rest_server->get_routes() as $route => $handlers) {
217
+ if (!$match = preg_match( '@^' . $route . '$@i', $path, $matches )) {
218
+ continue;
219
+ }
220
+
221
+ $args = [];
222
+ foreach ($matches as $param => $value) {
223
+ if (!is_int($param)) {
224
+ $args[ $param ] = $value;
225
+ }
226
+ }
227
+
228
+ foreach ($handlers as $handler) {
229
+ if (is_array($handler['callback']) && isset($handler['callback'][0]) && is_object($handler['callback'][0])
230
+ && 'WP_REST_Posts_Controller' == get_class($handler['callback'][0])
231
+ ) {
232
+ if ( ! $this->post_id = (!empty($args['id'])) ? $args['id'] : 0) {
233
+ $this->post_id = (!empty($this->params['id'])) ? $this->params['id'] : 0;
234
+ }
235
+
236
+ $this->is_posts_request = true;
237
+ $this->is_view_method = in_array($method, [\WP_REST_Server::READABLE, 'GET']);
238
+ $this->params = $request->get_params();
239
+
240
+ break 2;
241
+ }
242
+ }
243
+ }
244
+
245
+ return $rest_response;
246
+ }
247
+
248
+ /**
249
+ * Determine the Post ID, if any, which this query pertains to
250
+ */
251
+ private function getPostID()
252
+ {
253
+ global $post;
254
+
255
+ if (defined('REST_REQUEST') && REST_REQUEST && $this->is_posts_request) {
256
+ return $this->post_id;
257
+ }
258
+
259
+ if (!empty($post) && is_object($post)) {
260
+ return ('auto-draft' == $post->post_status) ? 0 : $post->ID;
261
+ } elseif (isset($_REQUEST['post'])) {
262
+ return (int)$_REQUEST['post'];
263
+ } elseif (isset($_REQUEST['post_ID'])) {
264
+ return (int)$_REQUEST['post_ID'];
265
+ } elseif (isset($_REQUEST['post_id'])) {
266
+ return (int)$_REQUEST['post_id'];
267
+ }
268
+ }
269
+ }
includes/filters.php CHANGED
@@ -1,259 +1,259 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) exit;
3
-
4
- /*
5
- * PublishPress Capabilities [Free]
6
- *
7
- * Load general purpose filters which need to execute for any URL, even front end
8
- *
9
- */
10
-
11
- /**
12
- * class CME_Extensions
13
- *
14
- * Load filters and actions for integration with third party plugins
15
- */
16
- class CME_Extensions {
17
- var $extensions = array();
18
-
19
- function add( $object ) {
20
- if ( ! is_object( $object ) ) return;
21
-
22
- $this->extensions[ get_class( $object ) ] = $object;
23
- }
24
- }
25
-
26
- global $cme_extensions;
27
- $cme_extensions = new CME_Extensions();
28
-
29
- add_filter( 'map_meta_cap', '_cme_remap_term_meta_cap', 5, 4 );
30
-
31
- add_action( 'admin_head', '_cme_publishpress_roles_js');
32
-
33
- if ( defined( 'WC_PLUGIN_FILE' ) ) {
34
- require_once ( dirname(__FILE__) . '/filters-woocommerce.php' );
35
- $cme_extensions->add( new CME_WooCommerce() );
36
- }
37
-
38
- if (!defined('CME_DISABLE_WP_EDIT_PUBLISHED_WORKAROUND')) {
39
- global $wp_version;
40
- if (version_compare($wp_version, '4.9.7', '>=')) { // avoid any issues with old REST API implementations
41
- require_once (dirname(__FILE__) . '/filters-wp_rest_workarounds.php');
42
- new PublishPress\Capabilities\WP_REST_Workarounds();
43
- }
44
- }
45
-
46
- if ( is_admin() ) {
47
- global $pagenow;
48
- if ( 'edit.php' == $pagenow ) {
49
- require_once ( dirname(__FILE__) . '/filters-admin.php' );
50
- new CME_AdminMenuNoPrivWorkaround();
51
- }
52
- }
53
-
54
- add_filter('plugin_action_links_' . plugin_basename(CME_FILE), '_cme_fltPluginActionLinks', 10, 2);
55
-
56
- add_action('plugins_loaded', '_cme_migrate_pp_options');
57
-
58
-
59
- function _cme_publishpress_roles_js() {
60
- if (defined('PUBLISHPRESS_VERSION') && !empty($_SERVER['REQUEST_URI']) && strpos(sanitize_text_field($_SERVER['REQUEST_URI']), 'page=pp-manage-roles')) {
61
- require_once(dirname(__FILE__) . '/publishpress-roles.php');
62
- CME_PublishPressRoles::scripts(); // @todo: .js
63
- }
64
- }
65
-
66
- // Capabilities previously stored, retrieved settings from 'pp_' option names. Now using 'presspermit_' option names unless PressPermit 2.6.x or older is activated, but need to migrate previous settings
67
- function _cme_migrate_pp_options() {
68
- if (!get_option('cme_pp_options_migrated') && get_option('cme_enabled_post_types')) {
69
- foreach(['enabled_post_types', 'enabled_taxonomies', 'define_create_posts_cap'] as $option_basename) {
70
- $presspermit_options = get_option("presspermit_{$option_basename}");
71
-
72
- if (!$presspermit_options) {
73
- $prefix = ('enabled_post_types' == $option_basename) ? 'cme_' : 'pp_';
74
-
75
- if ($option_val = get_option("{$prefix}_{$option_basename}")) {
76
- update_option("presspermit_{$option_basename}", $option_val);
77
- }
78
- }
79
- }
80
-
81
- update_option('cme_pp_options_migrated', true);
82
- }
83
- }
84
-
85
-
86
- // allow edit_terms, delete_terms, assign_terms capabilities to function separately from manage_terms
87
- function _cme_remap_term_meta_cap ( $caps, $cap, $user_id, $args ) {
88
- global $current_user, $cme_cap_helper;
89
-
90
- if ( ! empty( $cme_cap_helper ) ) {
91
- $cap_helper = $cme_cap_helper;
92
- } else {
93
- global $ppce_cap_helper;
94
- if ( ! empty( $ppce_cap_helper ) ) {
95
- $cap_helper = $ppce_cap_helper;
96
- }
97
- }
98
-
99
- if ( empty($cap_helper) || empty( $cap_helper->all_taxonomy_caps[$cap] ) ) {
100
- return $caps;
101
- }
102
-
103
- if ( ! $enabled_taxonomies = array_intersect( cme_get_assisted_taxonomies(), cme_get_detailed_taxonomies() ) ) {
104
- return $caps;
105
- }
106
-
107
- // meta caps
108
- switch ( $cap ) {
109
- // If detailed taxonomy capabilities are enabled for categories or tags, don't also require default capability for term assignment / deletion
110
- case 'assign_categories':
111
- if (in_array('category', $enabled_taxonomies)) {
112
- $caps = array_diff($caps, ['edit_posts']);
113
- }
114
- break;
115
-
116
- case 'assign_post_tags':
117
- if (in_array('post_tag', $enabled_taxonomies)) {
118
- $caps = array_diff($caps, ['edit_posts']);
119
- }
120
- break;
121
-
122
- case 'delete_categories':
123
- if (in_array('category', $enabled_taxonomies)) {
124
- $caps = array_diff($caps, ['manage_categories']);
125
- }
126
- break;
127
-
128
- case 'delete_post_tags':
129
- if (in_array('post_tag', $enabled_taxonomies)) {
130
- $caps = array_diff($caps, ['manage_categories']);
131
- }
132
- break;
133
-
134
- case 'edit_term':
135
- case 'delete_term':
136
- case 'assign_term':
137
- $tx_cap = $cap . 's';
138
-
139
- if ( ! is_array($args) || empty($args[0]) ) {
140
- return $caps;
141
- }
142
-
143
- if ( $term = get_term( $args[0] ) ) {
144
- if ( in_array( $term->taxonomy, $enabled_taxonomies ) ) {
145
- if ( $tx_obj = get_taxonomy( $term->taxonomy ) ) {
146
-
147
- // If this taxonomy is set for distinct capabilities, we don't want manage_terms capability to be implicitly assigned.
148
- if ( empty( $current_user->allcaps[$tx_obj->cap->manage_terms] ) ) {
149
- $caps = array_diff( $caps, (array) $tx_obj->cap->manage_terms );
150
- }
151
- $caps[]= $tx_obj->cap->$tx_cap;
152
- }
153
- }
154
- }
155
- break;
156
- default:
157
- }
158
-
159
- // primitive caps
160
- foreach( $enabled_taxonomies as $taxonomy ) {
161
- if ( ! $tx_obj = get_taxonomy( $taxonomy ) ) {
162
- continue;
163
- }
164
-
165
- foreach( array( 'edit_terms', 'delete_terms', 'assign_terms' ) as $cap_prop ) {
166
- if ( $cap == $tx_obj->cap->$cap_prop ) {
167
-
168
- // If this taxonomy is set for distinct capabilities, we don't want manage_terms capability to be implicitly assigned.
169
- if ( empty( $current_user->allcaps[$tx_obj->cap->manage_terms] ) ) {
170
- $caps = array_diff( $caps, (array) $tx_obj->cap->manage_terms );
171
- }
172
-
173
- $caps[]= $tx_obj->cap->$cap_prop;
174
- return $caps;
175
- }
176
- }
177
- }
178
-
179
- return $caps;
180
- }
181
-
182
- // Note: this intentionally shares "presspermit_enabled_post_types" option with PublishPress Permissions
183
- function cme_get_assisted_post_types() {
184
- $type_args = array( 'public' => true, 'show_ui' => true );
185
-
186
- $post_types = get_post_types( $type_args, 'names', 'or' );
187
-
188
- $omit_types = apply_filters('presspermit_unfiltered_post_types', ['forum', 'topic', 'reply', 'wp_block', 'customize_changeset']);
189
- $omit_types = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $omit_types : apply_filters('pp_unfiltered_post_types', $omit_types);
190
-
191
- if ($omit_types) {
192
- $post_types = array_diff_key( $post_types, array_fill_keys( (array) $omit_types, true ) );
193
- }
194
-
195
- $option_name = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp_enabled_post_types' : 'presspermit_enabled_post_types';
196
- $enabled = (array) get_option( $option_name, array( 'post' => true, 'page' => true ) );
197
-
198
- $post_types = array_intersect( $post_types, array_keys( array_filter( $enabled ) ) );
199
-
200
- return apply_filters( 'cme_assisted_post_types', $post_types, $type_args );
201
- }
202
-
203
- // Note: this intentionally does NOT share Press Permit' option name, for back compat reasons
204
- // Enabling filtered taxonomies in PP previously did not cause the edit_terms, delete_terms, assign_terms capabilities to be enforced
205
- function cme_get_assisted_taxonomies() {
206
- $tx_args = ['public' => true, 'show_ui' => true];
207
- $taxonomies = apply_filters('cme_filterable_taxonomies', get_taxonomies($tx_args, 'object', 'or'));
208
- $taxonomies = array_combine(array_keys($taxonomies), array_keys($taxonomies));
209
-
210
- if ($omit_taxonomies = apply_filters('pp_unfiltered_taxonomies', [])) {
211
- $taxonomies = array_diff($taxonomies, (array) $omit_taxonomies);
212
- }
213
-
214
- $option_name = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp_enabled_taxonomies' : 'presspermit_enabled_taxonomies';
215
- $enabled = (array) get_option( $option_name, []);
216
- $taxonomies = array_intersect( $taxonomies, array_keys( array_filter( $enabled ) ) );
217
-
218
- return apply_filters( 'cme_assisted_taxonomies', $taxonomies, $tx_args );
219
- }
220
-
221
- function cme_get_detailed_taxonomies() {
222
- $tx_args = ['public' => true, 'show_ui' => true];
223
- $taxonomies = apply_filters('cme_filterable_taxonomies', get_taxonomies($tx_args, 'object', 'or'));
224
- $taxonomies = array_combine(array_keys($taxonomies), array_keys($taxonomies));
225
-
226
- if ($omit_taxonomies = apply_filters('pp_unfiltered_taxonomies', [])) {
227
- $taxonomies = array_diff($taxonomies, (array) $omit_taxonomies);
228
- }
229
-
230
- $enabled = (array) get_option('cme_detailed_taxonomies', []);
231
- $taxonomies = array_intersect( $taxonomies, array_keys( array_filter( $enabled ) ) );
232
-
233
- return apply_filters( 'cme_detailed_taxonomies', $taxonomies, $tx_args );
234
- }
235
-
236
- function _cme_get_plural( $slug, $type_obj = false ) {
237
- if ( $type_obj && ! empty( $type_obj->rest_base ) && ( $type_obj->rest_base != $slug ) && ( $type_obj->rest_base != "{$slug}s" ) ) {
238
- // Use plural form from rest_base
239
- if ( $pos = strpos( $type_obj->rest_base, '/' ) ) {
240
- return sanitize_key( substr( $type_obj->rest_base, 0, $pos + 1 ) );
241
- } else {
242
- return sanitize_key( $type_obj->rest_base );
243
- }
244
- } else {
245
- require_once ( dirname(__FILE__) . '/inflect-cme.php' );
246
- return sanitize_key( CME_Inflect::pluralize( $slug ) );
247
- }
248
- }
249
-
250
- function _cme_fltPluginActionLinks($links, $file)
251
- {
252
- if ($file == plugin_basename(CME_FILE)) {
253
- if (!is_network_admin()) {
254
- $links[] = "<a href='" . admin_url("admin.php?page=pp-capabilities") . "'>" . esc_html__('Edit Roles', 'capsman-enhanced') . "</a>";
255
- }
256
- }
257
-
258
- return $links;
259
- }
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit;
3
+
4
+ /*
5
+ * PublishPress Capabilities [Free]
6
+ *
7
+ * Load general purpose filters which need to execute for any URL, even front end
8
+ *
9
+ */
10
+
11
+ /**
12
+ * class CME_Extensions
13
+ *
14
+ * Load filters and actions for integration with third party plugins
15
+ */
16
+ class CME_Extensions {
17
+ var $extensions = array();
18
+
19
+ function add( $object ) {
20
+ if ( ! is_object( $object ) ) return;
21
+
22
+ $this->extensions[ get_class( $object ) ] = $object;
23
+ }
24
+ }
25
+
26
+ global $cme_extensions;
27
+ $cme_extensions = new CME_Extensions();
28
+
29
+ add_filter( 'map_meta_cap', '_cme_remap_term_meta_cap', 5, 4 );
30
+
31
+ add_action( 'admin_head', '_cme_publishpress_roles_js');
32
+
33
+ if ( defined( 'WC_PLUGIN_FILE' ) ) {
34
+ require_once ( dirname(__FILE__) . '/filters-woocommerce.php' );
35
+ $cme_extensions->add( new CME_WooCommerce() );
36
+ }
37
+
38
+ if (!defined('CME_DISABLE_WP_EDIT_PUBLISHED_WORKAROUND')) {
39
+ global $wp_version;
40
+ if (version_compare($wp_version, '4.9.7', '>=')) { // avoid any issues with old REST API implementations
41
+ require_once (dirname(__FILE__) . '/filters-wp_rest_workarounds.php');
42
+ new PublishPress\Capabilities\WP_REST_Workarounds();
43
+ }
44
+ }
45
+
46
+ if ( is_admin() ) {
47
+ global $pagenow;
48
+ if ( 'edit.php' == $pagenow ) {
49
+ require_once ( dirname(__FILE__) . '/filters-admin.php' );
50
+ new CME_AdminMenuNoPrivWorkaround();
51
+ }
52
+ }
53
+
54
+ add_filter('plugin_action_links_' . plugin_basename(CME_FILE), '_cme_fltPluginActionLinks', 10, 2);
55
+
56
+ add_action('plugins_loaded', '_cme_migrate_pp_options');
57
+
58
+
59
+ function _cme_publishpress_roles_js() {
60
+ if (defined('PUBLISHPRESS_VERSION') && !empty($_SERVER['REQUEST_URI']) && strpos(sanitize_text_field($_SERVER['REQUEST_URI']), 'page=pp-manage-roles')) {
61
+ require_once(dirname(__FILE__) . '/publishpress-roles.php');
62
+ CME_PublishPressRoles::scripts(); // @todo: .js
63
+ }
64
+ }
65
+
66
+ // Capabilities previously stored, retrieved settings from 'pp_' option names. Now using 'presspermit_' option names unless PressPermit 2.6.x or older is activated, but need to migrate previous settings
67
+ function _cme_migrate_pp_options() {
68
+ if (!get_option('cme_pp_options_migrated') && get_option('cme_enabled_post_types')) {
69
+ foreach(['enabled_post_types', 'enabled_taxonomies', 'define_create_posts_cap'] as $option_basename) {
70
+ $presspermit_options = get_option("presspermit_{$option_basename}");
71
+
72
+ if (!$presspermit_options) {
73
+ $prefix = ('enabled_post_types' == $option_basename) ? 'cme_' : 'pp_';
74
+
75
+ if ($option_val = get_option("{$prefix}_{$option_basename}")) {
76
+ update_option("presspermit_{$option_basename}", $option_val);
77
+ }
78
+ }
79
+ }
80
+
81
+ update_option('cme_pp_options_migrated', true);
82
+ }
83
+ }
84
+
85
+
86
+ // allow edit_terms, delete_terms, assign_terms capabilities to function separately from manage_terms
87
+ function _cme_remap_term_meta_cap ( $caps, $cap, $user_id, $args ) {
88
+ global $current_user, $cme_cap_helper;
89
+
90
+ if ( ! empty( $cme_cap_helper ) ) {
91
+ $cap_helper = $cme_cap_helper;
92
+ } else {
93
+ global $ppce_cap_helper;
94
+ if ( ! empty( $ppce_cap_helper ) ) {
95
+ $cap_helper = $ppce_cap_helper;
96
+ }
97
+ }
98
+
99
+ if ( empty($cap_helper) || empty( $cap_helper->all_taxonomy_caps[$cap] ) ) {
100
+ return $caps;
101
+ }
102
+
103
+ if ( ! $enabled_taxonomies = array_intersect( cme_get_assisted_taxonomies(), cme_get_detailed_taxonomies() ) ) {
104
+ return $caps;
105
+ }
106
+
107
+ // meta caps
108
+ switch ( $cap ) {
109
+ // If detailed taxonomy capabilities are enabled for categories or tags, don't also require default capability for term assignment / deletion
110
+ case 'assign_categories':
111
+ if (in_array('category', $enabled_taxonomies)) {
112
+ $caps = array_diff($caps, ['edit_posts']);
113
+ }
114
+ break;
115
+
116
+ case 'assign_post_tags':
117
+ if (in_array('post_tag', $enabled_taxonomies)) {
118
+ $caps = array_diff($caps, ['edit_posts']);
119
+ }
120
+ break;
121
+
122
+ case 'delete_categories':
123
+ if (in_array('category', $enabled_taxonomies)) {
124
+ $caps = array_diff($caps, ['manage_categories']);
125
+ }
126
+ break;
127
+
128
+ case 'delete_post_tags':
129
+ if (in_array('post_tag', $enabled_taxonomies)) {
130
+ $caps = array_diff($caps, ['manage_categories']);
131
+ }
132
+ break;
133
+
134
+ case 'edit_term':
135
+ case 'delete_term':
136
+ case 'assign_term':
137
+ $tx_cap = $cap . 's';
138
+
139
+ if ( ! is_array($args) || empty($args[0]) ) {
140
+ return $caps;
141
+ }
142
+
143
+ if ( $term = get_term( $args[0] ) ) {
144
+ if ( in_array( $term->taxonomy, $enabled_taxonomies ) ) {
145
+ if ( $tx_obj = get_taxonomy( $term->taxonomy ) ) {
146
+
147
+ // If this taxonomy is set for distinct capabilities, we don't want manage_terms capability to be implicitly assigned.
148
+ if ( empty( $current_user->allcaps[$tx_obj->cap->manage_terms] ) ) {
149
+ $caps = array_diff( $caps, (array) $tx_obj->cap->manage_terms );
150
+ }
151
+ $caps[]= $tx_obj->cap->$tx_cap;
152
+ }
153
+ }
154
+ }
155
+ break;
156
+ default:
157
+ }
158
+
159
+ // primitive caps
160
+ foreach( $enabled_taxonomies as $taxonomy ) {
161
+ if ( ! $tx_obj = get_taxonomy( $taxonomy ) ) {
162
+ continue;
163
+ }
164
+
165
+ foreach( array( 'edit_terms', 'delete_terms', 'assign_terms' ) as $cap_prop ) {
166
+ if ( $cap == $tx_obj->cap->$cap_prop ) {
167
+
168
+ // If this taxonomy is set for distinct capabilities, we don't want manage_terms capability to be implicitly assigned.
169
+ if ( empty( $current_user->allcaps[$tx_obj->cap->manage_terms] ) ) {
170
+ $caps = array_diff( $caps, (array) $tx_obj->cap->manage_terms );
171
+ }
172
+
173
+ $caps[]= $tx_obj->cap->$cap_prop;
174
+ return $caps;
175
+ }
176
+ }
177
+ }
178
+
179
+ return $caps;
180
+ }
181
+
182
+ // Note: this intentionally shares "presspermit_enabled_post_types" option with PublishPress Permissions
183
+ function cme_get_assisted_post_types() {
184
+ $type_args = array( 'public' => true, 'show_ui' => true );
185
+
186
+ $post_types = get_post_types( $type_args, 'names', 'or' );
187
+
188
+ $omit_types = apply_filters('presspermit_unfiltered_post_types', ['forum', 'topic', 'reply', 'wp_block', 'customize_changeset']);
189
+ $omit_types = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $omit_types : apply_filters('pp_unfiltered_post_types', $omit_types);
190
+
191
+ if ($omit_types) {
192
+ $post_types = array_diff_key( $post_types, array_fill_keys( (array) $omit_types, true ) );
193
+ }
194
+
195
+ $option_name = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp_enabled_post_types' : 'presspermit_enabled_post_types';
196
+ $enabled = (array) get_option( $option_name, array( 'post' => true, 'page' => true ) );
197
+
198
+ $post_types = array_intersect( $post_types, array_keys( array_filter( $enabled ) ) );
199
+
200
+ return apply_filters( 'cme_assisted_post_types', $post_types, $type_args );
201
+ }
202
+
203
+ // Note: this intentionally does NOT share Press Permit' option name, for back compat reasons
204
+ // Enabling filtered taxonomies in PP previously did not cause the edit_terms, delete_terms, assign_terms capabilities to be enforced
205
+ function cme_get_assisted_taxonomies() {
206
+ $tx_args = ['public' => true, 'show_ui' => true];
207
+ $taxonomies = apply_filters('cme_filterable_taxonomies', get_taxonomies($tx_args, 'object', 'or'));
208
+ $taxonomies = array_combine(array_keys($taxonomies), array_keys($taxonomies));
209
+
210
+ if ($omit_taxonomies = apply_filters('pp_unfiltered_taxonomies', [])) {
211
+ $taxonomies = array_diff($taxonomies, (array) $omit_taxonomies);
212
+ }
213
+
214
+ $option_name = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp_enabled_taxonomies' : 'presspermit_enabled_taxonomies';
215
+ $enabled = (array) get_option( $option_name, []);
216
+ $taxonomies = array_intersect( $taxonomies, array_keys( array_filter( $enabled ) ) );
217
+
218
+ return apply_filters( 'cme_assisted_taxonomies', $taxonomies, $tx_args );
219
+ }
220
+
221
+ function cme_get_detailed_taxonomies() {
222
+ $tx_args = ['public' => true, 'show_ui' => true];
223
+ $taxonomies = apply_filters('cme_filterable_taxonomies', get_taxonomies($tx_args, 'object', 'or'));
224
+ $taxonomies = array_combine(array_keys($taxonomies), array_keys($taxonomies));
225
+
226
+ if ($omit_taxonomies = apply_filters('pp_unfiltered_taxonomies', [])) {
227
+ $taxonomies = array_diff($taxonomies, (array) $omit_taxonomies);
228
+ }
229
+
230
+ $enabled = (array) get_option('cme_detailed_taxonomies', []);
231
+ $taxonomies = array_intersect( $taxonomies, array_keys( array_filter( $enabled ) ) );
232
+
233
+ return apply_filters( 'cme_detailed_taxonomies', $taxonomies, $tx_args );
234
+ }
235
+
236
+ function _cme_get_plural( $slug, $type_obj = false ) {
237
+ if ( $type_obj && ! empty( $type_obj->rest_base ) && ( $type_obj->rest_base != $slug ) && ( $type_obj->rest_base != "{$slug}s" ) ) {
238
+ // Use plural form from rest_base
239
+ if ( $pos = strpos( $type_obj->rest_base, '/' ) ) {
240
+ return sanitize_key( substr( $type_obj->rest_base, 0, $pos + 1 ) );
241
+ } else {
242
+ return sanitize_key( $type_obj->rest_base );
243
+ }
244
+ } else {
245
+ require_once ( dirname(__FILE__) . '/inflect-cme.php' );
246
+ return sanitize_key( CME_Inflect::pluralize( $slug ) );
247
+ }
248
+ }
249
+
250
+ function _cme_fltPluginActionLinks($links, $file)
251
+ {
252
+ if ($file == plugin_basename(CME_FILE)) {
253
+ if (!is_network_admin()) {
254
+ $links[] = "<a href='" . admin_url("admin.php?page=pp-capabilities") . "'>" . esc_html__('Edit Roles', 'capsman-enhanced') . "</a>";
255
+ }
256
+ }
257
+
258
+ return $links;
259
+ }
includes/functions-admin.php CHANGED
@@ -1,233 +1,250 @@
1
- <?php
2
-
3
- /*
4
- * PublishPress Capabilities [Free]
5
- *
6
- * Functions available to wp-admin requests, which are not contained within a class
7
- *
8
- */
9
-
10
- function cme_fakefunc() {
11
- }
12
-
13
- function pp_capabilities_get_post_id()
14
- {
15
- global $post;
16
-
17
- if (defined('REST_REQUEST') && REST_REQUEST) {
18
- if ($_post_id = apply_filters('presspermit_rest_post_id', 0)) {
19
- return $_post_id;
20
- }
21
- }
22
-
23
- if (!empty($post) && is_object($post)) {
24
- if ('auto-draft' == $post->post_status) {
25
- return 0;
26
- } else {
27
- return $post->ID;
28
- }
29
-
30
- } elseif (isset($_REQUEST['post'])) {
31
- return (int)$_REQUEST['post'];
32
-
33
- } elseif (isset($_REQUEST['post_ID'])) {
34
- return (int)$_REQUEST['post_ID'];
35
-
36
- } elseif (isset($_REQUEST['post_id'])) {
37
- return (int)$_REQUEST['post_id'];
38
-
39
- } elseif (defined('WOOCOMMERCE_VERSION') && !empty($_REQUEST['product_id'])) {
40
- return (int)$_REQUEST['product_id'];
41
- }
42
- }
43
-
44
- /**
45
- * Based on Edit Flow's \Block_Editor_Compatible::should_apply_compat method.
46
- *
47
- * @return bool
48
- */
49
- function _pp_capabilities_is_block_editor_active($post_type = '', $args = [])
50
- {
51
- global $current_user, $wp_version;
52
-
53
- $defaults = ['suppress_filter' => false, 'force_refresh' => false];
54
- $args = array_merge($defaults, $args);
55
- $suppress_filter = $args['suppress_filter'];
56
-
57
- // Check if Revisionary lower than v1.3 is installed. It disables Gutenberg.
58
- if (defined('REVISIONARY_VERSION') && version_compare(REVISIONARY_VERSION, '1.3-beta', '<')) {
59
- return false;
60
- }
61
-
62
- static $buffer;
63
- if (!isset($buffer)) {
64
- $buffer = [];
65
- }
66
-
67
- if (!$post_type = pp_capabilities_get_post_type()) {
68
- return true;
69
- }
70
-
71
- if ($post_type_obj = get_post_type_object($post_type)) {
72
- if (!$post_type_obj->show_in_rest) {
73
- return false;
74
- }
75
- }
76
-
77
- if (isset($buffer[$post_type]) && empty($args['force_refresh']) && !$suppress_filter) {
78
- return $buffer[$post_type];
79
- }
80
-
81
- if (class_exists('Classic_Editor')) {
82
- if (isset($_REQUEST['classic-editor__forget']) && (isset($_REQUEST['classic']) || isset($_REQUEST['classic-editor']))) {
83
- return false;
84
- } elseif (isset($_REQUEST['classic-editor__forget']) && !isset($_REQUEST['classic']) && !isset($_REQUEST['classic-editor'])) {
85
- return true;
86
- } elseif (get_option('classic-editor-allow-users') === 'allow') {
87
- if ($post_id = pp_capabilities_get_post_id()) {
88
- $which = get_post_meta( $post_id, 'classic-editor-remember', true );
89
-
90
- if ('block-editor' == $which) {
91
- return true;
92
- } elseif ('classic-editor' == $which) {
93
- return false;
94
- }
95
- } else {
96
- $use_block = ('block' == get_user_meta($current_user->ID, 'wp_classic-editor-settings'));
97
-
98
- if (version_compare($wp_version, '5.9-beta', '>=')) {
99
- remove_action('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
100
- remove_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
101
- }
102
-
103
- $use_block = $use_block && apply_filters('use_block_editor_for_post_type', $use_block, $post_type, PHP_INT_MAX);
104
-
105
- if (defined('PP_CAPABILITIES_RESTORE_NAV_TYPE_BLOCK_EDITOR_DISABLE') && version_compare($wp_version, '5.9-beta', '>=')) {
106
- add_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
107
- }
108
-
109
- return $use_block;
110
- }
111
- }
112
- }
113
-
114
- $pluginsState = array(
115
- 'classic-editor' => class_exists( 'Classic_Editor' ),
116
- 'gutenberg' => function_exists( 'the_gutenberg_project' ),
117
- 'gutenberg-ramp' => class_exists('Gutenberg_Ramp'),
118
- );
119
-
120
- $conditions = [];
121
-
122
- if ($suppress_filter) remove_filter('use_block_editor_for_post_type', $suppress_filter, 10, 2);
123
-
124
- /**
125
- * 5.0:
126
- *
127
- * Classic editor either disabled or enabled (either via an option or with GET argument).
128
- * It's a hairy conditional :(
129
- */
130
-
131
- if (version_compare($wp_version, '5.9-beta', '>=')) {
132
- remove_action('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
133
- remove_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
134
- }
135
-
136
- // phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected, WordPress.Security.NonceVerification.NoNonceVerification
137
- $conditions[] = (version_compare($wp_version, '5.0', '>=') || $pluginsState['gutenberg'])
138
- && ! $pluginsState['classic-editor']
139
- && ! $pluginsState['gutenberg-ramp']
140
- && apply_filters('use_block_editor_for_post_type', true, $post_type, PHP_INT_MAX);
141
-
142
- $conditions[] = version_compare($wp_version, '5.0', '>=')
143
- && $pluginsState['classic-editor']
144
- && (get_option('classic-editor-replace') === 'block'
145
- && ! isset($_GET['classic-editor__forget']));
146
-
147
- $conditions[] = version_compare($wp_version, '5.0', '>=')
148
- && $pluginsState['classic-editor']
149
- && (get_option('classic-editor-replace') === 'classic'
150
- && isset($_GET['classic-editor__forget']));
151
-
152
- $conditions[] = $pluginsState['gutenberg-ramp']
153
- && apply_filters('use_block_editor_for_post', true, get_post(pp_capabilities_get_post_id()), PHP_INT_MAX);
154
-
155
- if (defined('PP_CAPABILITIES_RESTORE_NAV_TYPE_BLOCK_EDITOR_DISABLE') && version_compare($wp_version, '5.9-beta', '>=')) {
156
- add_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
157
- }
158
-
159
- // Returns true if at least one condition is true.
160
- $result = count(
161
- array_filter($conditions,
162
- function ($c) {
163
- return (bool)$c;
164
- }
165
- )
166
- ) > 0;
167
-
168
- if (!$suppress_filter) {
169
- $buffer[$post_type] = $result;
170
- }
171
-
172
- // Returns true if at least one condition is true.
173
- return $result;
174
- }
175
-
176
- /**
177
- * Remove all non-alphanumeric and space characters from a string.
178
- *
179
- * @param string $string .
180
- *
181
- * @return string
182
- *
183
- * @since 2.1.1
184
- */
185
- function ppc_remove_non_alphanumeric_space_characters($string)
186
- {
187
- return preg_replace("/(\W)+/", "", $string);
188
- }
189
-
190
- /**
191
- * Get all capabilities backup section.
192
- *
193
- * @return array $backup_sections
194
- */
195
- function pp_capabilities_backup_sections()
196
- {
197
- $cms_id = 'capsman';
198
- $backup_sections = [];
199
-
200
- //Editor Features
201
- $backup_sections[$cms_id . '_editor_features_backup']['label'] = esc_html__('Editor Feature', 'capsman-enhanced');
202
- $classic_editor = pp_capabilities_is_classic_editor_available();
203
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
204
- foreach ($def_post_types as $post_type) {
205
- if ($classic_editor) {
206
- $backup_sections[$cms_id . '_editor_features_backup']['options'][] = "capsman_feature_restrict_classic_{$post_type}";
207
- }
208
- $backup_sections[$cms_id . '_editor_features_backup']['options'][] = "capsman_feature_restrict_{$post_type}";
209
- }
210
-
211
- //Admin Features
212
- $backup_sections[$cms_id . '_admin_features_backup']['label'] = esc_html__('Admin Feature', 'capsman-enhanced');
213
- $backup_sections[$cms_id . '_admin_features_backup']['options'][] = "capsman_disabled_admin_features";
214
-
215
- return apply_filters('pp_capabilities_backup_sections', $backup_sections);
216
- }
217
-
218
- /**
219
- * Register and add inline styles.
220
- *
221
- * @param string $custom_css
222
- * @param string $handle
223
- *
224
- * @return string
225
- *
226
- * @since 2.3.5
227
- */
228
- function ppc_add_inline_style($custom_css, $handle = 'ppc-dummy-css-handle')
229
- {
230
- wp_register_style(esc_attr($handle), false);
231
- wp_enqueue_style(esc_attr($handle));
232
- wp_add_inline_style(esc_attr($handle), esc_attr($custom_css));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
1
+ <?php
2
+
3
+ /*
4
+ * PublishPress Capabilities [Free]
5
+ *
6
+ * Functions available to wp-admin requests, which are not contained within a class
7
+ *
8
+ */
9
+
10
+ function cme_fakefunc() {
11
+ }
12
+
13
+ function pp_capabilities_get_post_id()
14
+ {
15
+ global $post;
16
+
17
+ if (defined('REST_REQUEST') && REST_REQUEST) {
18
+ if ($_post_id = apply_filters('presspermit_rest_post_id', 0)) {
19
+ return $_post_id;
20
+ }
21
+ }
22
+
23
+ if (!empty($post) && is_object($post)) {
24
+ if ('auto-draft' == $post->post_status) {
25
+ return 0;
26
+ } else {
27
+ return $post->ID;
28
+ }
29
+
30
+ } elseif (isset($_REQUEST['post'])) {
31
+ return (int)$_REQUEST['post'];
32
+
33
+ } elseif (isset($_REQUEST['post_ID'])) {
34
+ return (int)$_REQUEST['post_ID'];
35
+
36
+ } elseif (isset($_REQUEST['post_id'])) {
37
+ return (int)$_REQUEST['post_id'];
38
+
39
+ } elseif (defined('WOOCOMMERCE_VERSION') && !empty($_REQUEST['product_id'])) {
40
+ return (int)$_REQUEST['product_id'];
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Based on Edit Flow's \Block_Editor_Compatible::should_apply_compat method.
46
+ *
47
+ * @return bool
48
+ */
49
+ function _pp_capabilities_is_block_editor_active($post_type = '', $args = [])
50
+ {
51
+ global $current_user, $wp_version;
52
+
53
+ $defaults = ['suppress_filter' => false, 'force_refresh' => false];
54
+ $args = array_merge($defaults, $args);
55
+ $suppress_filter = $args['suppress_filter'];
56
+
57
+ // Check if Revisionary lower than v1.3 is installed. It disables Gutenberg.
58
+ if (defined('REVISIONARY_VERSION') && version_compare(REVISIONARY_VERSION, '1.3-beta', '<')) {
59
+ return false;
60
+ }
61
+
62
+ static $buffer;
63
+ if (!isset($buffer)) {
64
+ $buffer = [];
65
+ }
66
+
67
+ if (!$post_type = pp_capabilities_get_post_type()) {
68
+ return true;
69
+ }
70
+
71
+ if ($post_type_obj = get_post_type_object($post_type)) {
72
+ if (!$post_type_obj->show_in_rest) {
73
+ return false;
74
+ }
75
+ }
76
+
77
+ if (isset($buffer[$post_type]) && empty($args['force_refresh']) && !$suppress_filter) {
78
+ return $buffer[$post_type];
79
+ }
80
+
81
+ if (class_exists('Classic_Editor')) {
82
+ if (isset($_REQUEST['classic-editor__forget']) && (isset($_REQUEST['classic']) || isset($_REQUEST['classic-editor']))) {
83
+ return false;
84
+ } elseif (isset($_REQUEST['classic-editor__forget']) && !isset($_REQUEST['classic']) && !isset($_REQUEST['classic-editor'])) {
85
+ return true;
86
+ } elseif (get_option('classic-editor-allow-users') === 'allow') {
87
+ if ($post_id = pp_capabilities_get_post_id()) {
88
+ $which = get_post_meta( $post_id, 'classic-editor-remember', true );
89
+
90
+ if ('block-editor' == $which) {
91
+ return true;
92
+ } elseif ('classic-editor' == $which) {
93
+ return false;
94
+ }
95
+ } else {
96
+ $use_block = ('block' == get_user_meta($current_user->ID, 'wp_classic-editor-settings'));
97
+
98
+ if (version_compare($wp_version, '5.9-beta', '>=')) {
99
+ remove_action('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
100
+ remove_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
101
+ }
102
+
103
+ $use_block = $use_block && apply_filters('use_block_editor_for_post_type', $use_block, $post_type, PHP_INT_MAX);
104
+
105
+ if (defined('PP_CAPABILITIES_RESTORE_NAV_TYPE_BLOCK_EDITOR_DISABLE') && version_compare($wp_version, '5.9-beta', '>=')) {
106
+ add_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
107
+ }
108
+
109
+ return $use_block;
110
+ }
111
+ }
112
+ }
113
+
114
+ $pluginsState = array(
115
+ 'classic-editor' => class_exists( 'Classic_Editor' ),
116
+ 'gutenberg' => function_exists( 'the_gutenberg_project' ),
117
+ 'gutenberg-ramp' => class_exists('Gutenberg_Ramp'),
118
+ );
119
+
120
+ $conditions = [];
121
+
122
+ if ($suppress_filter) remove_filter('use_block_editor_for_post_type', $suppress_filter, 10, 2);
123
+
124
+ /**
125
+ * 5.0:
126
+ *
127
+ * Classic editor either disabled or enabled (either via an option or with GET argument).
128
+ * It's a hairy conditional :(
129
+ */
130
+
131
+ if (version_compare($wp_version, '5.9-beta', '>=')) {
132
+ remove_action('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
133
+ remove_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2);
134
+ }
135
+
136
+ // phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected, WordPress.Security.NonceVerification.NoNonceVerification
137
+ $conditions[] = (version_compare($wp_version, '5.0', '>=') || $pluginsState['gutenberg'])
138
+ && ! $pluginsState['classic-editor']
139
+ && ! $pluginsState['gutenberg-ramp']
140
+ && apply_filters('use_block_editor_for_post_type', true, $post_type, PHP_INT_MAX);
141
+
142
+ $conditions[] = version_compare($wp_version, '5.0', '>=')
143
+ && $pluginsState['classic-editor']
144
+ && (get_option('classic-editor-replace') === 'block'
145
+ && ! isset($_GET['classic-editor__forget']));
146
+
147
+ $conditions[] = version_compare($wp_version, '5.0', '>=')
148
+ && $pluginsState['classic-editor']
149
+ && (get_option('classic-editor-replace') === 'classic'
150
+ && isset($_GET['classic-editor__forget']));
151
+
152
+ $conditions[] = $pluginsState['gutenberg-ramp']
153
+ && apply_filters('use_block_editor_for_post', true, get_post(pp_capabilities_get_post_id()), PHP_INT_MAX);
154
+
155
+ if (defined('PP_CAPABILITIES_RESTORE_NAV_TYPE_BLOCK_EDITOR_DISABLE') && version_compare($wp_version, '5.9-beta', '>=')) {
156
+ add_filter('use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
157
+ }
158
+
159
+ // Returns true if at least one condition is true.
160
+ $result = count(
161
+ array_filter($conditions,
162
+ function ($c) {
163
+ return (bool)$c;
164
+ }
165
+ )
166
+ ) > 0;
167
+
168
+ if (!$suppress_filter) {
169
+ $buffer[$post_type] = $result;
170
+ }
171
+
172
+ // Returns true if at least one condition is true.
173
+ return $result;
174
+ }
175
+
176
+ /**
177
+ * Remove all non-alphanumeric and space characters from a string.
178
+ *
179
+ * @param string $string .
180
+ *
181
+ * @return string
182
+ *
183
+ * @since 2.1.1
184
+ */
185
+ function ppc_remove_non_alphanumeric_space_characters($string)
186
+ {
187
+ return preg_replace("/(\W)+/", "", $string);
188
+ }
189
+
190
+ /**
191
+ * Get all capabilities backup section.
192
+ *
193
+ * @return array $backup_sections
194
+ */
195
+ function pp_capabilities_backup_sections()
196
+ {
197
+ $cms_id = 'capsman';
198
+ $backup_sections = [];
199
+
200
+ //Editor Features
201
+ $backup_sections[$cms_id . '_editor_features_backup']['label'] = esc_html__('Editor Features', 'capsman-enhanced');
202
+ $classic_editor = pp_capabilities_is_classic_editor_available();
203
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
204
+ foreach ($def_post_types as $post_type) {
205
+ if ($classic_editor) {
206
+ $backup_sections[$cms_id . '_editor_features_backup']['options'][] = "capsman_feature_restrict_classic_{$post_type}";
207
+ }
208
+ $backup_sections[$cms_id . '_editor_features_backup']['options'][] = "capsman_feature_restrict_{$post_type}";
209
+ }
210
+
211
+ //Admin Features
212
+ $backup_sections[$cms_id . '_admin_features_backup']['label'] = esc_html__('Admin Features', 'capsman-enhanced');
213
+ $backup_sections[$cms_id . '_admin_features_backup']['options'][] = "capsman_disabled_admin_features";
214
+
215
+ return apply_filters('pp_capabilities_backup_sections', $backup_sections);
216
+ }
217
+
218
+ /**
219
+ * Register and add inline styles.
220
+ *
221
+ * @param string $custom_css
222
+ * @param string $handle
223
+ *
224
+ * @return string
225
+ *
226
+ * @since 2.3.5
227
+ */
228
+ function ppc_add_inline_style($custom_css, $handle = 'ppc-dummy-css-handle')
229
+ {
230
+ wp_register_style(esc_attr($handle), false);
231
+ wp_enqueue_style(esc_attr($handle));
232
+ wp_add_inline_style(esc_attr($handle), $custom_css);
233
+ }
234
+
235
+ /**
236
+ * Register and add inline script.
237
+ *
238
+ * @param string $custom_script
239
+ * @param string $handle
240
+ *
241
+ * @return string
242
+ *
243
+ * @since 2.4.0
244
+ */
245
+ function ppc_add_inline_script($custom_script, $handle = 'ppc-dummy-script-handle')
246
+ {
247
+ wp_register_script(esc_attr($handle), false, ['jquery']);
248
+ wp_enqueue_script(esc_attr($handle), false, ['jquery']);
249
+ wp_add_inline_script(esc_attr($handle), $custom_script);
250
  }
includes/functions.php CHANGED
@@ -1,290 +1,290 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Functions available for any URL, which are not contained within a class
6
- *
7
- * For performance and code separation, do not include functions that are only needed for wp-admin requests
8
- *
9
- */
10
-
11
-
12
- /**
13
- * Sanitizes a string entry
14
- *
15
- * Keys are used as internal identifiers. Uppercase or lowercase alphanumeric characters,
16
- * spaces, periods, commas, plusses, asterisks, colons, pipes, parentheses, dashes and underscores are allowed.
17
- *
18
- * @param string $entry String entry
19
- * @return string Sanitized entry
20
- */
21
- function pp_capabilities_sanitize_entry( $entry ) {
22
- $entry = preg_replace( '/[^a-zA-Z0-9 \.\,\+\*\:\|\(\)_\-\=]/', '', $entry );
23
- return $entry;
24
- }
25
-
26
- function pp_capabilities_is_editable_role($role_name, $args = []) {
27
- static $editable_roles;
28
-
29
- if (!function_exists('wp_roles')) {
30
- return false;
31
- }
32
-
33
- if (!isset($editable_roles) || !empty($args['force_refresh'])) {
34
- $all_roles = wp_roles()->roles;
35
- $editable_roles = apply_filters('editable_roles', $all_roles, $args);
36
- }
37
-
38
- return apply_filters('pp_capabilities_editable_role', isset($editable_roles[$role_name]), $role_name);
39
- }
40
-
41
- function _cme_act_pp_active()
42
- {
43
- if (defined('PRESSPERMIT_VERSION') || (defined('PPC_VERSION') && function_exists('pp_init_cap_caster'))) {
44
- define('PRESSPERMIT_ACTIVE', true);
45
- } else {
46
- if (defined('SCOPER_VERSION') || (defined('PP_VERSION') && function_exists('pp_init_users_interceptor'))) {
47
- define('OLD_PRESSPERMIT_ACTIVE', true);
48
- }
49
- }
50
- }
51
-
52
- function _cme_cap_helper()
53
- {
54
- global $cme_cap_helper;
55
-
56
- require_once(dirname(__FILE__) . '/cap-helper.php');
57
- $cme_cap_helper = new CME_Cap_Helper();
58
-
59
- add_action('registered_post_type', '_cme_post_type_late_reg', 5, 2);
60
- add_action('registered_taxonomy', '_cme_taxonomy_late_reg', 5, 2);
61
- }
62
-
63
- function _cme_post_type_late_reg($post_type, $type_obj)
64
- {
65
- global $cme_cap_helper;
66
-
67
- if (!empty($type_obj->public) || !empty($type_obj->show_ui)) {
68
- $cme_cap_helper->refresh();
69
- }
70
- }
71
-
72
- function _cme_taxonomy_late_reg($taxonomy, $tx_obj)
73
- {
74
- global $cme_cap_helper;
75
-
76
- if (!empty($tx_obj->public)) {
77
- $cme_cap_helper->refresh();
78
- }
79
- }
80
-
81
- function _cme_init()
82
- {
83
- require_once(dirname(__FILE__) . '/filters.php');
84
-
85
- load_plugin_textdomain('capsman-enhanced', false, dirname(plugin_basename(__FILE__)) . '/languages');
86
- }
87
-
88
- function cme_is_plugin_active($check_plugin_file)
89
- {
90
- if (!$check_plugin_file)
91
- return false;
92
-
93
- $plugins = (array)get_option('active_plugins');
94
-
95
- foreach ($plugins as $plugin_file) {
96
- if (false !== strpos($plugin_file, $check_plugin_file))
97
- return $plugin_file;
98
- }
99
- }
100
-
101
- // if a role is marked as hidden, also default it for use by Press Permit as a Pattern Role (when PP Collaborative Editing is activated and Advanced Settings enabled)
102
- function _cme_pp_default_pattern_role($role)
103
- {
104
- if (!$pp_role_usage = get_option('pp_role_usage'))
105
- $pp_role_usage = array();
106
-
107
- if (empty($pp_role_usage[$role])) {
108
- $pp_role_usage[$role] = 'pattern';
109
- update_option('pp_role_usage', $pp_role_usage);
110
- }
111
- }
112
-
113
- // deprecated
114
- function capsman_get_pp_option($option_basename)
115
- {
116
- return pp_capabilities_get_permissions_option($option_basename);
117
- }
118
-
119
- function pp_capabilities_autobackup()
120
- {
121
- global $wpdb;
122
-
123
- $roles = get_option($wpdb->prefix . 'user_roles');
124
- update_option('cme_backup_auto_' . current_time('Y-m-d_g-i-s_a'), $roles, false);
125
-
126
- $max_auto_backups = (defined('CME_AUTOBACKUPS')) ? (int) CME_AUTOBACKUPS : 20;
127
-
128
- $current_options = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%' ORDER BY option_id DESC");
129
-
130
- if (count($current_options) >= $max_auto_backups) {
131
- $i = 0;
132
-
133
- foreach($current_options as $option_name) {
134
- $i++;
135
-
136
- if ($i > $max_auto_backups) {
137
- $wpdb->query(
138
- $wpdb->prepare(
139
- "DELETE FROM $wpdb->options WHERE option_name = %s",
140
- $option_name
141
- )
142
- );
143
-
144
- wp_cache_delete($option_name, 'options');
145
- }
146
- }
147
- }
148
- }
149
-
150
- function pp_capabilities_get_permissions_option($option_basename)
151
- {
152
- return (function_exists('presspermit')) ? presspermit()->getOption($option_basename) : pp_get_option($option_basename);
153
- }
154
-
155
- function pp_capabilities_update_permissions_option($option_basename, $option_val)
156
- {
157
- function_exists('presspermit') ? presspermit()->updateOption($option_basename, $option_val) : pp_update_option($option_basename, $option_val);
158
- }
159
-
160
- /**
161
- * Get post type.
162
- *
163
- * @return null|string String of the post type.
164
- */
165
- function pp_capabilities_get_post_type()
166
- {
167
- global $post, $typenow, $current_screen;
168
-
169
- // We have a post so we can just get the post type from that.
170
- if ($post && $post->post_type) {
171
- return $post->post_type;
172
- }
173
-
174
- // Check the global $typenow - set in admin.php
175
- if ($typenow) {
176
- return $typenow;
177
- }
178
-
179
- // Check the global $current_screen object - set in screen.php
180
- if ($current_screen && $current_screen->post_type) {
181
- return $current_screen->post_type;
182
- }
183
-
184
- if (isset($_GET['post']) && !is_array($_GET['post'])) {
185
- $post_id = (int) $_GET['post'];
186
-
187
- } elseif (isset($_POST['post_ID'])) {
188
- $post_id = (int) $_POST['post_ID'];
189
- }
190
-
191
- if (!empty($post_id)) {
192
- return get_post_type($post_id);
193
- }
194
-
195
- // lastly check the post_type querystring
196
- if (isset($_REQUEST['post_type'])) {
197
- return sanitize_key($_REQUEST['post_type']);
198
- }
199
-
200
- return 'post';
201
- }
202
-
203
- /**
204
- * Check if Classic Editor plugin is available.
205
- *
206
- * @return bool
207
- */
208
- function pp_capabilities_is_classic_editor_available()
209
- {
210
- global $wp_version;
211
-
212
- return class_exists('Classic_Editor')
213
- || function_exists( 'the_gutenberg_project' )
214
- || class_exists('Gutenberg_Ramp')
215
- || version_compare($wp_version, '5.0', '<')
216
- || class_exists('WooCommerce')
217
- || (defined('PP_CAPABILITIES_CONFIGURE_CLASSIC_EDITOR') && PP_CAPABILITIES_CONFIGURE_CLASSIC_EDITOR)
218
- || (function_exists('et_get_option') && 'on' === et_get_option('et_enable_classic_editor', 'off'));
219
- }
220
-
221
- /**
222
- * Get admin bar node and set as global for our usage.
223
- * Due to admin toolbar, this function need to run in frontend as well
224
- *
225
- * @return array||object $wp_admin_bar nodes.
226
- */
227
- function ppc_features_get_admin_bar_nodes($wp_admin_bar){
228
-
229
- $adminBarNode = is_object($wp_admin_bar) ? $wp_admin_bar->get_nodes() : '';
230
- $ppcAdminBar = [];
231
-
232
- if (is_array($adminBarNode) || is_object($adminBarNode)) {
233
- foreach ($adminBarNode as $adminBarnode) {
234
- $id = $adminBarnode->id;
235
- $title = $adminBarnode->title;
236
- $parent = $adminBarnode->parent;
237
- $ppcAdminBar[$id] = array('id' => $id, 'title' => $title, 'parent' => $parent);
238
- }
239
- }
240
-
241
- $GLOBALS['ppcAdminBar'] = $ppcAdminBar;
242
- }
243
- add_action('admin_bar_menu', 'ppc_features_get_admin_bar_nodes', 999);
244
-
245
- /**
246
- * Implement admin features restriction.
247
- * Due to admin toolbar, this function need to run in frontend as well
248
- *
249
- */
250
- function ppc_admin_feature_restrictions() {
251
- require_once ( dirname(CME_FILE) . '/includes/features/restrict-admin-features.php' );
252
- PP_Capabilities_Admin_Features::adminFeaturedRestriction();
253
- }
254
- add_action('plugins_loaded', 'ppc_admin_feature_restrictions');
255
-
256
- /**
257
- * List of capabilities admin pages
258
- *
259
- */
260
- function pp_capabilities_admin_pages(){
261
-
262
- $pp_capabilities_pages = [
263
- 'pp-capabilities',
264
- 'pp-capabilities-roles',
265
- 'pp-capabilities-admin-menus',
266
- 'pp-capabilities-nav-menus',
267
- 'pp-capabilities-editor-features',
268
- 'pp-capabilities-backup',
269
- 'pp-capabilities-settings',
270
- 'pp-capabilities-admin-features'
271
- ];
272
-
273
- return apply_filters('pp_capabilities_admin_pages', $pp_capabilities_pages);
274
- }
275
-
276
- /**
277
- * Check if user is in capabilities admin page
278
- *
279
- */
280
- function is_pp_capabilities_admin_page(){
281
-
282
- $pp_capabilities_pages = pp_capabilities_admin_pages();
283
-
284
- $is_pp_capabilities_page = false;
285
- if ( isset( $_GET['page'] ) && in_array( $_GET['page'], $pp_capabilities_pages )) {
286
- $is_pp_capabilities_page = true;
287
- }
288
-
289
- return apply_filters('is_pp_capabilities_admin_page', $is_pp_capabilities_page);
290
  }
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Functions available for any URL, which are not contained within a class
6
+ *
7
+ * For performance and code separation, do not include functions that are only needed for wp-admin requests
8
+ *
9
+ */
10
+
11
+
12
+ /**
13
+ * Sanitizes a string entry
14
+ *
15
+ * Keys are used as internal identifiers. Uppercase or lowercase alphanumeric characters,
16
+ * spaces, periods, commas, plusses, asterisks, colons, pipes, parentheses, dashes and underscores are allowed.
17
+ *
18
+ * @param string $entry String entry
19
+ * @return string Sanitized entry
20
+ */
21
+ function pp_capabilities_sanitize_entry( $entry ) {
22
+ $entry = preg_replace( '/[^a-zA-Z0-9 \.\,\+\*\:\|\(\)_\-\=]/', '', $entry );
23
+ return $entry;
24
+ }
25
+
26
+ function pp_capabilities_is_editable_role($role_name, $args = []) {
27
+ static $editable_roles;
28
+
29
+ if (!function_exists('wp_roles')) {
30
+ return false;
31
+ }
32
+
33
+ if (!isset($editable_roles) || !empty($args['force_refresh'])) {
34
+ $all_roles = wp_roles()->roles;
35
+ $editable_roles = apply_filters('editable_roles', $all_roles, $args);
36
+ }
37
+
38
+ return apply_filters('pp_capabilities_editable_role', isset($editable_roles[$role_name]), $role_name);
39
+ }
40
+
41
+ function _cme_act_pp_active()
42
+ {
43
+ if (defined('PRESSPERMIT_VERSION') || (defined('PPC_VERSION') && function_exists('pp_init_cap_caster'))) {
44
+ define('PRESSPERMIT_ACTIVE', true);
45
+ } else {
46
+ if (defined('SCOPER_VERSION') || (defined('PP_VERSION') && function_exists('pp_init_users_interceptor'))) {
47
+ define('OLD_PRESSPERMIT_ACTIVE', true);
48
+ }
49
+ }
50
+ }
51
+
52
+ function _cme_cap_helper()
53
+ {
54
+ global $cme_cap_helper;
55
+
56
+ require_once(dirname(__FILE__) . '/cap-helper.php');
57
+ $cme_cap_helper = new CME_Cap_Helper();
58
+
59
+ add_action('registered_post_type', '_cme_post_type_late_reg', 5, 2);
60
+ add_action('registered_taxonomy', '_cme_taxonomy_late_reg', 5, 2);
61
+ }
62
+
63
+ function _cme_post_type_late_reg($post_type, $type_obj)
64
+ {
65
+ global $cme_cap_helper;
66
+
67
+ if (!empty($type_obj->public) || !empty($type_obj->show_ui)) {
68
+ $cme_cap_helper->refresh();
69
+ }
70
+ }
71
+
72
+ function _cme_taxonomy_late_reg($taxonomy, $tx_obj)
73
+ {
74
+ global $cme_cap_helper;
75
+
76
+ if (!empty($tx_obj->public)) {
77
+ $cme_cap_helper->refresh();
78
+ }
79
+ }
80
+
81
+ function _cme_init()
82
+ {
83
+ require_once(dirname(__FILE__) . '/filters.php');
84
+
85
+ load_plugin_textdomain('capsman-enhanced', false, dirname(plugin_basename(__FILE__)) . '/languages');
86
+ }
87
+
88
+ function cme_is_plugin_active($check_plugin_file)
89
+ {
90
+ if (!$check_plugin_file)
91
+ return false;
92
+
93
+ $plugins = (array)get_option('active_plugins');
94
+
95
+ foreach ($plugins as $plugin_file) {
96
+ if (false !== strpos($plugin_file, $check_plugin_file))
97
+ return $plugin_file;
98
+ }
99
+ }
100
+
101
+ // if a role is marked as hidden, also default it for use by Press Permit as a Pattern Role (when PP Collaborative Editing is activated and Advanced Settings enabled)
102
+ function _cme_pp_default_pattern_role($role)
103
+ {
104
+ if (!$pp_role_usage = get_option('pp_role_usage'))
105
+ $pp_role_usage = array();
106
+
107
+ if (empty($pp_role_usage[$role])) {
108
+ $pp_role_usage[$role] = 'pattern';
109
+ update_option('pp_role_usage', $pp_role_usage);
110
+ }
111
+ }
112
+
113
+ // deprecated
114
+ function capsman_get_pp_option($option_basename)
115
+ {
116
+ return pp_capabilities_get_permissions_option($option_basename);
117
+ }
118
+
119
+ function pp_capabilities_autobackup()
120
+ {
121
+ global $wpdb;
122
+
123
+ $roles = get_option($wpdb->prefix . 'user_roles');
124
+ update_option('cme_backup_auto_' . current_time('Y-m-d_g-i-s_a'), $roles, false);
125
+
126
+ $max_auto_backups = (defined('CME_AUTOBACKUPS')) ? (int) CME_AUTOBACKUPS : 20;
127
+
128
+ $current_options = $wpdb->get_col("SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%' ORDER BY option_id DESC");
129
+
130
+ if (count($current_options) >= $max_auto_backups) {
131
+ $i = 0;
132
+
133
+ foreach($current_options as $option_name) {
134
+ $i++;
135
+
136
+ if ($i > $max_auto_backups) {
137
+ $wpdb->query(
138
+ $wpdb->prepare(
139
+ "DELETE FROM $wpdb->options WHERE option_name = %s",
140
+ $option_name
141
+ )
142
+ );
143
+
144
+ wp_cache_delete($option_name, 'options');
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ function pp_capabilities_get_permissions_option($option_basename)
151
+ {
152
+ return (function_exists('presspermit')) ? presspermit()->getOption($option_basename) : pp_get_option($option_basename);
153
+ }
154
+
155
+ function pp_capabilities_update_permissions_option($option_basename, $option_val)
156
+ {
157
+ function_exists('presspermit') ? presspermit()->updateOption($option_basename, $option_val) : pp_update_option($option_basename, $option_val);
158
+ }
159
+
160
+ /**
161
+ * Get post type.
162
+ *
163
+ * @return null|string String of the post type.
164
+ */
165
+ function pp_capabilities_get_post_type()
166
+ {
167
+ global $post, $typenow, $current_screen;
168
+
169
+ // We have a post so we can just get the post type from that.
170
+ if ($post && $post->post_type) {
171
+ return $post->post_type;
172
+ }
173
+
174
+ // Check the global $typenow - set in admin.php
175
+ if ($typenow) {
176
+ return $typenow;
177
+ }
178
+
179
+ // Check the global $current_screen object - set in screen.php
180
+ if ($current_screen && $current_screen->post_type) {
181
+ return $current_screen->post_type;
182
+ }
183
+
184
+ if (isset($_GET['post']) && !is_array($_GET['post'])) {
185
+ $post_id = (int) $_GET['post'];
186
+
187
+ } elseif (isset($_POST['post_ID'])) {
188
+ $post_id = (int) $_POST['post_ID'];
189
+ }
190
+
191
+ if (!empty($post_id)) {
192
+ return get_post_type($post_id);
193
+ }
194
+
195
+ // lastly check the post_type querystring
196
+ if (isset($_REQUEST['post_type'])) {
197
+ return sanitize_key($_REQUEST['post_type']);
198
+ }
199
+
200
+ return 'post';
201
+ }
202
+
203
+ /**
204
+ * Check if Classic Editor plugin is available.
205
+ *
206
+ * @return bool
207
+ */
208
+ function pp_capabilities_is_classic_editor_available()
209
+ {
210
+ global $wp_version;
211
+
212
+ return class_exists('Classic_Editor')
213
+ || function_exists( 'the_gutenberg_project' )
214
+ || class_exists('Gutenberg_Ramp')
215
+ || version_compare($wp_version, '5.0', '<')
216
+ || class_exists('WooCommerce')
217
+ || (defined('PP_CAPABILITIES_CONFIGURE_CLASSIC_EDITOR') && PP_CAPABILITIES_CONFIGURE_CLASSIC_EDITOR)
218
+ || (function_exists('et_get_option') && 'on' === et_get_option('et_enable_classic_editor', 'off'));
219
+ }
220
+
221
+ /**
222
+ * Get admin bar node and set as global for our usage.
223
+ * Due to admin toolbar, this function need to run in frontend as well
224
+ *
225
+ * @return array||object $wp_admin_bar nodes.
226
+ */
227
+ function ppc_features_get_admin_bar_nodes($wp_admin_bar){
228
+
229
+ $adminBarNode = is_object($wp_admin_bar) ? $wp_admin_bar->get_nodes() : '';
230
+ $ppcAdminBar = [];
231
+
232
+ if (is_array($adminBarNode) || is_object($adminBarNode)) {
233
+ foreach ($adminBarNode as $adminBarnode) {
234
+ $id = $adminBarnode->id;
235
+ $title = $adminBarnode->title;
236
+ $parent = $adminBarnode->parent;
237
+ $ppcAdminBar[$id] = array('id' => $id, 'title' => $title, 'parent' => $parent);
238
+ }
239
+ }
240
+
241
+ $GLOBALS['ppcAdminBar'] = $ppcAdminBar;
242
+ }
243
+ add_action('admin_bar_menu', 'ppc_features_get_admin_bar_nodes', 999);
244
+
245
+ /**
246
+ * Implement admin features restriction.
247
+ * Due to admin toolbar, this function need to run in frontend as well
248
+ *
249
+ */
250
+ function ppc_admin_feature_restrictions() {
251
+ require_once ( dirname(CME_FILE) . '/includes/features/restrict-admin-features.php' );
252
+ PP_Capabilities_Admin_Features::adminFeaturedRestriction();
253
+ }
254
+ add_action('plugins_loaded', 'ppc_admin_feature_restrictions');
255
+
256
+ /**
257
+ * List of capabilities admin pages
258
+ *
259
+ */
260
+ function pp_capabilities_admin_pages(){
261
+
262
+ $pp_capabilities_pages = [
263
+ 'pp-capabilities',
264
+ 'pp-capabilities-roles',
265
+ 'pp-capabilities-admin-menus',
266
+ 'pp-capabilities-nav-menus',
267
+ 'pp-capabilities-editor-features',
268
+ 'pp-capabilities-backup',
269
+ 'pp-capabilities-settings',
270
+ 'pp-capabilities-admin-features'
271
+ ];
272
+
273
+ return apply_filters('pp_capabilities_admin_pages', $pp_capabilities_pages);
274
+ }
275
+
276
+ /**
277
+ * Check if user is in capabilities admin page
278
+ *
279
+ */
280
+ function is_pp_capabilities_admin_page(){
281
+
282
+ $pp_capabilities_pages = pp_capabilities_admin_pages();
283
+
284
+ $is_pp_capabilities_page = false;
285
+ if ( isset( $_GET['page'] ) && in_array( $_GET['page'], $pp_capabilities_pages )) {
286
+ $is_pp_capabilities_page = true;
287
+ }
288
+
289
+ return apply_filters('is_pp_capabilities_admin_page', $is_pp_capabilities_page);
290
  }
includes/handler.php CHANGED
@@ -1,379 +1,379 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Process update operations from the Capabilities screen
6
- *
7
- */
8
-
9
- class CapsmanHandler
10
- {
11
- var $cm;
12
-
13
- function __construct($manager_obj = false) {
14
- if ($manager_obj) {
15
- $this->cm = $manager_obj;
16
- } else {
17
- global $capsman;
18
- $this->cm = $capsman;
19
- }
20
-
21
- require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
22
- }
23
-
24
- function processAdminGeneral() {
25
- global $wpdb, $wp_roles;
26
-
27
- check_admin_referer('capsman-general-manager');
28
-
29
- if ( empty ($_POST['caps']) ) {
30
- $_POST['caps'] = array();
31
- }
32
-
33
- if (!empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page'])) {
34
- do_action('publishpress-caps_process_update');
35
- return;
36
- }
37
-
38
- // Create a new role.
39
- if ( ! empty($_POST['CreateRole']) ) {
40
- if (!empty($_POST['create-name'])) {
41
- $newrole = $this->createRole(sanitize_text_field($_POST['create-name']));
42
- }
43
-
44
- if (!empty($newrole)) {
45
- ak_admin_notify(__('New role created.', 'capsman-enhanced'));
46
- $this->cm->set_current_role($newrole);
47
- } else {
48
- if ( empty($_POST['create-name']) && in_array(get_locale(), ['en_EN', 'en_US']) )
49
- ak_admin_error('Error: No role name specified.');
50
- else
51
- ak_admin_error(__('Error: Failed creating the new role.', 'capsman-enhanced'));
52
- }
53
-
54
- // Save role changes. Already saved at start with self::saveRoleCapabilities()
55
- } elseif ( ! empty($_POST['SaveRole']) && !empty($_POST['current'])) {
56
- if ( MULTISITE ) {
57
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
58
- }
59
-
60
- if (!pp_capabilities_is_editable_role(sanitize_key($_POST['current']))) {
61
- ak_admin_error(__('The selected role is not editable.', 'capsman-enhanced'));
62
- return;
63
- }
64
-
65
- $level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0;
66
- $this->saveRoleCapabilities(sanitize_key($_POST['current']), array_map('boolval', $_POST['caps']), $level);
67
-
68
- if (defined( 'PRESSPERMIT_ACTIVE' ) && !empty($_POST['role'])) { // log customized role caps for subsequent restoration
69
- // for bbPress < 2.2, need to log customization of roles following bbPress activation
70
- $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
71
-
72
- if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
73
- $customized_roles = array();
74
-
75
- $_role = sanitize_key($_POST['role']);
76
-
77
- $customized_roles[$_role] = (object) array( 'caps' => array_map( 'boolval', $_POST['caps'] ), 'plugins' => $plugins );
78
- update_option( 'pp_customized_roles', $customized_roles );
79
-
80
- $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
81
- }
82
- // Create New Capability and adds it to current role.
83
- } elseif (!empty($_POST['AddCap']) && !empty($_POST['current']) && !empty($_POST['capability-name'])) {
84
- if ( MULTISITE ) {
85
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
86
- }
87
-
88
- if (empty($_POST['current']) || !pp_capabilities_is_editable_role(sanitize_key($_POST['current']))) {
89
- ak_admin_error(__('The selected role is not editable.', 'capsman-enhanced'));
90
- return;
91
- }
92
-
93
- $role = get_role(sanitize_key($_POST['current']));
94
- $role->name = sanitize_key($_POST['current']); // bbPress workaround
95
-
96
- $newname = $this->createNewName(sanitize_text_field($_POST['capability-name']), ['allow_dashes' => true]);
97
-
98
- if (empty($newname['error'])) {
99
- $role->add_cap($newname['name']);
100
-
101
- // for bbPress < 2.2, need to log customization of roles following bbPress activation
102
- $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
103
-
104
- if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
105
- $customized_roles = array();
106
-
107
- $customized_roles[sanitize_key($_POST['role'])] = (object) array( 'caps' => array_merge( $role->capabilities, array( $newname['name'] => 1 ) ), 'plugins' => $plugins );
108
- update_option( 'pp_customized_roles', $customized_roles );
109
-
110
- $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
111
-
112
- $redirect_role = (!empty($_POST['role'])) ? sanitize_key($_POST['role']) : '';
113
-
114
- $url = admin_url('admin.php?page=pp-capabilities&role=' . esc_attr($redirect_role) . '&added=1');
115
- wp_redirect($url);
116
- exit;
117
- } else {
118
- add_action('all_admin_notices', function() {
119
- ak_admin_notify(__('Incorrect capability name.', 'capsman-enhanced'));
120
- });
121
- }
122
-
123
- } elseif ( ! empty($_POST['update_filtered_types']) || ! empty($_POST['update_filtered_taxonomies']) || ! empty($_POST['update_detailed_taxonomies']) ) {
124
- ak_admin_notify(__('Type / Taxonomy settings saved.', 'capsman-enhanced'));
125
- } else {
126
- if (!apply_filters('publishpress-caps_submission_ok', false)) {
127
- ak_admin_error(__('Bad form received.', 'capsman-enhanced'));
128
- }
129
- }
130
-
131
- if ( ! empty($newrole) && defined('PRESSPERMIT_ACTIVE') ) {
132
- if ( ( ! empty($_POST['CreateRole']) && ! empty( $_REQUEST['new_role_pp_only'] ) ) || ( ! empty($_POST['CopyRole']) && ! empty( $_REQUEST['copy_role_pp_only'] ) ) ) {
133
- $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
134
- $pp_only[]= $newrole;
135
-
136
- pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
137
-
138
- _cme_pp_default_pattern_role( $newrole );
139
- pp_refresh_options();
140
- }
141
- }
142
- }
143
-
144
-
145
- /**
146
- * Creates a new role/capability name from user input name.
147
- * Name rules are:
148
- * - 2-40 charachers lenght.
149
- * - Only letters, digits, spaces and underscores.
150
- * - Must to start with a letter.
151
- *
152
- * @param string $name Name from user input.
153
- * @return array|false An array with the name and display_name, or false if not valid $name.
154
- */
155
- public function createNewName( $name, $args=[] ) {
156
- // Allow max 40 characters, letters, digits and spaces
157
- $name = trim(substr($name, 0, 40));
158
- $pattern = (!empty($args['allow_dashes'])) ? '/^[a-zA-Z][a-zA-Z0-9 _\-]+$/' : '/^[a-zA-Z][a-zA-Z0-9 _]+$/';
159
-
160
- if ( preg_match($pattern, $name) ) {
161
- $roles = ak_get_roles();
162
-
163
- $name = str_replace(' ', '_', $name);
164
- if ( in_array($name, $roles) || array_key_exists($name, $this->cm->capabilities) ) {
165
- return ['error' => 'role_exists', 'name' => $name]; // Already a role or capability with this name.
166
- }
167
-
168
- $display = explode('_', $name);
169
- $name = strtolower($name);
170
-
171
- // Apply ucfirst proper caps unless capitalization already provided
172
- foreach($display as $i => $word) {
173
- if ($word === strtolower($word)) {
174
- $display[$i] = ucfirst($word);
175
- }
176
- }
177
-
178
- $display = implode(' ', $display);
179
-
180
- return compact('name', 'display');
181
- } else {
182
- return ['error' => 'invalid_name', 'name' => $name];
183
- }
184
- }
185
-
186
- /**
187
- * Creates a new role.
188
- *
189
- * @param string $name Role name to create.
190
- * @param array $caps Role capabilities.
191
- * @return string|false Returns the name of the new role created or false if failed.
192
- */
193
- public function createRole( $name, $caps = [], $args = [] ) {
194
- if ( ! is_array($caps) )
195
- $caps = array();
196
-
197
- $role = $this->createNewName($name);
198
- if (!empty($role['error'])) {
199
- return false;
200
- }
201
-
202
- $new_role = add_role($role['name'], $role['display'], $caps);
203
- if ( is_object($new_role) ) {
204
- return $role['name'];
205
- } else {
206
- return false;
207
- }
208
- }
209
-
210
- /**
211
- * Saves capability changes to roles.
212
- *
213
- * @param string $role_name Role name to change its capabilities
214
- * @param array $caps New capabilities for the role.
215
- * @return void
216
- */
217
- private function saveRoleCapabilities( $role_name, $caps, $level ) {
218
- $this->cm->generateNames();
219
- $role = get_role($role_name);
220
-
221
- // workaround to ensure db storage of customizations to bbp dynamic roles
222
- $role->name = $role_name;
223
-
224
- $stored_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(true, 1) ) : array();
225
- $stored_negative_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(false) ) : array();
226
-
227
- $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
228
- $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
229
- $new_caps = array_merge($new_caps, ak_level2caps($level));
230
-
231
- // Find caps to add and remove
232
- $add_caps = array_diff_key($new_caps, $old_caps);
233
- $del_caps = array_diff_key(array_merge($old_caps, $stored_negative_role_caps), $new_caps);
234
-
235
- $changed_caps = array();
236
- foreach( array_intersect_key( $new_caps, $old_caps ) as $cap_name => $cap_val ) {
237
- if ( $new_caps[$cap_name] != $old_caps[$cap_name] )
238
- $changed_caps[$cap_name] = $cap_val;
239
- }
240
-
241
- $add_caps = array_merge( $add_caps, $changed_caps );
242
-
243
- if ( ! $is_administrator = current_user_can('administrator') ) {
244
- unset($add_caps['manage_capabilities']);
245
- unset($del_caps['manage_capabilities']);
246
- }
247
-
248
- if ( 'administrator' == $role_name && isset($del_caps['manage_capabilities']) ) {
249
- unset($del_caps['manage_capabilities']);
250
- ak_admin_error(__('You cannot remove Manage Capabilities from Administrators', 'capsman-enhanced'));
251
- }
252
-
253
- // additional safeguard against removal of read capability
254
- if ( isset( $del_caps['read'] ) && _cme_is_read_removal_blocked( $role_name ) ) {
255
- unset( $del_caps['read'] );
256
- }
257
-
258
- // Add new capabilities to role
259
- foreach ( $add_caps as $cap => $grant ) {
260
- if ( $is_administrator || current_user_can($cap) )
261
- $role->add_cap( $cap, $grant );
262
- }
263
-
264
- // Remove capabilities from role
265
- foreach ( $del_caps as $cap => $grant) {
266
- if ( $is_administrator || current_user_can($cap) )
267
- $role->remove_cap($cap);
268
- }
269
-
270
- $this->cm->log_db_roles();
271
-
272
- if (is_multisite() && is_super_admin() && is_main_site()) {
273
- if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) )
274
- $autocreate_roles = array();
275
-
276
- $this_role_autocreate = ! empty($_REQUEST['cme_autocreate_role']);
277
-
278
- if ( $this_role_autocreate && ! in_array( $role_name, $autocreate_roles ) ) {
279
- $autocreate_roles []= $role_name;
280
- update_site_option( 'cme_autocreate_roles', $autocreate_roles );
281
- }
282
-
283
- if ( ! $this_role_autocreate && in_array( $role_name, $autocreate_roles ) ) {
284
- $autocreate_roles = array_diff( $autocreate_roles, array( $role_name ) );
285
- update_site_option( 'cme_autocreate_roles', $autocreate_roles );
286
- }
287
-
288
- $do_role_sync = !empty($_REQUEST['cme_net_sync_role']);
289
- $do_option_sync = !empty($_REQUEST['cme_net_sync_options']);
290
-
291
- if ($do_role_sync || $do_option_sync) {
292
- // loop through all sites on network, creating or updating role def
293
-
294
- global $wpdb, $wp_roles, $blog_id;
295
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs ORDER BY blog_id" );
296
- $orig_blog_id = $blog_id;
297
-
298
- if ($do_role_sync) {
299
- $role_caption = $wp_roles->role_names[$role_name];
300
-
301
- $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
302
- $new_caps = array_merge($new_caps, ak_level2caps($level) );
303
-
304
- $admin_role = $wp_roles->get_role('administrator');
305
- $main_admin_caps = array_merge( $admin_role->capabilities, ak_level2caps(10) );
306
- }
307
-
308
- $sync_options = [];
309
-
310
- if ($do_option_sync) {
311
- // capability-related options
312
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
313
-
314
- foreach(['define_create_posts_cap', 'enabled_post_types', 'enabled_taxonomies'] as $option_name) {
315
- $sync_options["{$pp_prefix}_$option_name"] = get_option("{$pp_prefix}_$option_name");
316
- }
317
-
318
- $sync_options['cme_detailed_taxonomies'] = get_option('cme_detailed_taxonomies');
319
- $sync_options['cme_enabled_post_types'] = get_option('cme_enabled_post_types');
320
- $sync_options['presspermit_supplemental_role_defs'] = get_option('presspermit_supplemental_role_defs');
321
- }
322
-
323
- foreach ( $blog_ids as $id ) {
324
- if ( is_main_site($id) )
325
- continue;
326
-
327
- switch_to_blog( $id );
328
-
329
- if ($do_role_sync) {
330
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
331
-
332
- if ( $blog_role = $wp_roles->get_role( $role_name ) ) {
333
- $stored_role_caps = ( ! empty($blog_role->capabilities) && is_array($blog_role->capabilities) ) ? array_intersect( $blog_role->capabilities, array(true, 1) ) : array();
334
-
335
- $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
336
-
337
- // Find caps to add and remove
338
- $add_caps = array_diff_key($new_caps, $old_caps);
339
- $del_caps = array_intersect_key( array_diff_key($old_caps, $new_caps), $main_admin_caps ); // don't mess with caps that are totally unused on main site
340
-
341
- // Add new capabilities to role
342
- foreach ( $add_caps as $cap => $grant ) {
343
- $wp_roles->roles[$role_name]['capabilities'][$cap] = $grant;
344
-
345
- }
346
-
347
- // Remove capabilities from role
348
- foreach ( $del_caps as $cap => $grant) {
349
- unset($wp_roles->roles[$role_name]['capabilities'][$cap]);
350
- }
351
-
352
- if ($wp_roles->use_db) {
353
- update_option($wp_roles->role_key, $wp_roles->roles);
354
- }
355
- } else {
356
- $wp_roles->add_role( $role_name, $role_caption, $new_caps );
357
- }
358
- }
359
-
360
- foreach($sync_options as $option_name => $option_val) {
361
- update_option($option_name, $option_val);
362
- }
363
-
364
- restore_current_blog();
365
- }
366
-
367
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
368
- }
369
- } // endif multisite installation with super admin editing a main site role
370
-
371
- pp_capabilities_autobackup();
372
- }
373
- }
374
-
375
- if ( ! function_exists('boolval') ) {
376
- function boolval( $val ) {
377
- return (bool) $val;
378
- }
379
- }
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Process update operations from the Capabilities screen
6
+ *
7
+ */
8
+
9
+ class CapsmanHandler
10
+ {
11
+ var $cm;
12
+
13
+ function __construct($manager_obj = false) {
14
+ if ($manager_obj) {
15
+ $this->cm = $manager_obj;
16
+ } else {
17
+ global $capsman;
18
+ $this->cm = $capsman;
19
+ }
20
+
21
+ require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
22
+ }
23
+
24
+ function processAdminGeneral() {
25
+ global $wpdb, $wp_roles;
26
+
27
+ check_admin_referer('capsman-general-manager');
28
+
29
+ if ( empty ($_POST['caps']) ) {
30
+ $_POST['caps'] = array();
31
+ }
32
+
33
+ if (!empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page'])) {
34
+ do_action('publishpress-caps_process_update');
35
+ return;
36
+ }
37
+
38
+ // Create a new role.
39
+ if ( ! empty($_POST['CreateRole']) ) {
40
+ if (!empty($_POST['create-name'])) {
41
+ $newrole = $this->createRole(sanitize_text_field($_POST['create-name']));
42
+ }
43
+
44
+ if (!empty($newrole)) {
45
+ ak_admin_notify(__('New role created.', 'capsman-enhanced'));
46
+ $this->cm->set_current_role($newrole);
47
+ } else {
48
+ if ( empty($_POST['create-name']) && in_array(get_locale(), ['en_EN', 'en_US']) )
49
+ ak_admin_error('Error: No role name specified.');
50
+ else
51
+ ak_admin_error(__('Error: Failed creating the new role.', 'capsman-enhanced'));
52
+ }
53
+
54
+ // Save role changes. Already saved at start with self::saveRoleCapabilities()
55
+ } elseif ( ! empty($_POST['SaveRole']) && !empty($_POST['current'])) {
56
+ if ( MULTISITE ) {
57
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
58
+ }
59
+
60
+ if (!pp_capabilities_is_editable_role(sanitize_key($_POST['current']))) {
61
+ ak_admin_error(__('The selected role is not editable.', 'capsman-enhanced'));
62
+ return;
63
+ }
64
+
65
+ $level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0;
66
+ $this->saveRoleCapabilities(sanitize_key($_POST['current']), array_map('boolval', $_POST['caps']), $level);
67
+
68
+ if (defined( 'PRESSPERMIT_ACTIVE' ) && !empty($_POST['role'])) { // log customized role caps for subsequent restoration
69
+ // for bbPress < 2.2, need to log customization of roles following bbPress activation
70
+ $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
71
+
72
+ if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
73
+ $customized_roles = array();
74
+
75
+ $_role = sanitize_key($_POST['role']);
76
+
77
+ $customized_roles[$_role] = (object) array( 'caps' => array_map( 'boolval', $_POST['caps'] ), 'plugins' => $plugins );
78
+ update_option( 'pp_customized_roles', $customized_roles );
79
+
80
+ $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
81
+ }
82
+ // Create New Capability and adds it to current role.
83
+ } elseif (!empty($_POST['AddCap']) && !empty($_POST['current']) && !empty($_POST['capability-name'])) {
84
+ if ( MULTISITE ) {
85
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
86
+ }
87
+
88
+ if (empty($_POST['current']) || !pp_capabilities_is_editable_role(sanitize_key($_POST['current']))) {
89
+ ak_admin_error(__('The selected role is not editable.', 'capsman-enhanced'));
90
+ return;
91
+ }
92
+
93
+ $role = get_role(sanitize_key($_POST['current']));
94
+ $role->name = sanitize_key($_POST['current']); // bbPress workaround
95
+
96
+ $newname = $this->createNewName(sanitize_text_field($_POST['capability-name']), ['allow_dashes' => true]);
97
+
98
+ if (empty($newname['error'])) {
99
+ $role->add_cap($newname['name']);
100
+
101
+ // for bbPress < 2.2, need to log customization of roles following bbPress activation
102
+ $plugins = ( function_exists( 'bbp_get_version' ) && version_compare( bbp_get_version(), '2.2', '<' ) ) ? array( 'bbpress.php' ) : array(); // back compat
103
+
104
+ if ( ! $customized_roles = get_option( 'pp_customized_roles' ) )
105
+ $customized_roles = array();
106
+
107
+ $customized_roles[sanitize_key($_POST['role'])] = (object) array( 'caps' => array_merge( $role->capabilities, array( $newname['name'] => 1 ) ), 'plugins' => $plugins );
108
+ update_option( 'pp_customized_roles', $customized_roles );
109
+
110
+ $wpdb->query( "UPDATE $wpdb->options SET autoload = 'no' WHERE option_name = 'pp_customized_roles'" );
111
+
112
+ $redirect_role = (!empty($_POST['role'])) ? sanitize_key($_POST['role']) : '';
113
+
114
+ $url = admin_url('admin.php?page=pp-capabilities&role=' . esc_attr($redirect_role) . '&added=1');
115
+ wp_redirect($url);
116
+ exit;
117
+ } else {
118
+ add_action('all_admin_notices', function() {
119
+ ak_admin_notify(__('Incorrect capability name.', 'capsman-enhanced'));
120
+ });
121
+ }
122
+
123
+ } elseif ( ! empty($_POST['update_filtered_types']) || ! empty($_POST['update_filtered_taxonomies']) || ! empty($_POST['update_detailed_taxonomies']) ) {
124
+ ak_admin_notify(__('Type / Taxonomy settings saved.', 'capsman-enhanced'));
125
+ } else {
126
+ if (!apply_filters('publishpress-caps_submission_ok', false)) {
127
+ ak_admin_error(__('Bad form received.', 'capsman-enhanced'));
128
+ }
129
+ }
130
+
131
+ if ( ! empty($newrole) && defined('PRESSPERMIT_ACTIVE') ) {
132
+ if ( ( ! empty($_POST['CreateRole']) && ! empty( $_REQUEST['new_role_pp_only'] ) ) || ( ! empty($_POST['CopyRole']) && ! empty( $_REQUEST['copy_role_pp_only'] ) ) ) {
133
+ $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
134
+ $pp_only[]= $newrole;
135
+
136
+ pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
137
+
138
+ _cme_pp_default_pattern_role( $newrole );
139
+ pp_refresh_options();
140
+ }
141
+ }
142
+ }
143
+
144
+
145
+ /**
146
+ * Creates a new role/capability name from user input name.
147
+ * Name rules are:
148
+ * - 2-40 charachers lenght.
149
+ * - Only letters, digits, spaces and underscores.
150
+ * - Must to start with a letter.
151
+ *
152
+ * @param string $name Name from user input.
153
+ * @return array|false An array with the name and display_name, or false if not valid $name.
154
+ */
155
+ public function createNewName( $name, $args=[] ) {
156
+ // Allow max 40 characters, letters, digits and spaces
157
+ $name = trim(substr($name, 0, 40));
158
+ $pattern = (!empty($args['allow_dashes'])) ? '/^[a-zA-Z][a-zA-Z0-9 _\-]+$/' : '/^[a-zA-Z][a-zA-Z0-9 _]+$/';
159
+
160
+ if ( preg_match($pattern, $name) ) {
161
+ $roles = ak_get_roles();
162
+
163
+ $name = str_replace(' ', '_', $name);
164
+ if ( in_array($name, $roles) || array_key_exists($name, $this->cm->capabilities) ) {
165
+ return ['error' => 'role_exists', 'name' => $name]; // Already a role or capability with this name.
166
+ }
167
+
168
+ $display = explode('_', $name);
169
+ $name = strtolower($name);
170
+
171
+ // Apply ucfirst proper caps unless capitalization already provided
172
+ foreach($display as $i => $word) {
173
+ if ($word === strtolower($word)) {
174
+ $display[$i] = ucfirst($word);
175
+ }
176
+ }
177
+
178
+ $display = implode(' ', $display);
179
+
180
+ return compact('name', 'display');
181
+ } else {
182
+ return ['error' => 'invalid_name', 'name' => $name];
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Creates a new role.
188
+ *
189
+ * @param string $name Role name to create.
190
+ * @param array $caps Role capabilities.
191
+ * @return string|false Returns the name of the new role created or false if failed.
192
+ */
193
+ public function createRole( $name, $caps = [], $args = [] ) {
194
+ if ( ! is_array($caps) )
195
+ $caps = array();
196
+
197
+ $role = $this->createNewName($name);
198
+ if (!empty($role['error'])) {
199
+ return false;
200
+ }
201
+
202
+ $new_role = add_role($role['name'], $role['display'], $caps);
203
+ if ( is_object($new_role) ) {
204
+ return $role['name'];
205
+ } else {
206
+ return false;
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Saves capability changes to roles.
212
+ *
213
+ * @param string $role_name Role name to change its capabilities
214
+ * @param array $caps New capabilities for the role.
215
+ * @return void
216
+ */
217
+ private function saveRoleCapabilities( $role_name, $caps, $level ) {
218
+ $this->cm->generateNames();
219
+ $role = get_role($role_name);
220
+
221
+ // workaround to ensure db storage of customizations to bbp dynamic roles
222
+ $role->name = $role_name;
223
+
224
+ $stored_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(true, 1) ) : array();
225
+ $stored_negative_role_caps = ( ! empty($role->capabilities) && is_array($role->capabilities) ) ? array_intersect( $role->capabilities, array(false) ) : array();
226
+
227
+ $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
228
+ $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
229
+ $new_caps = array_merge($new_caps, ak_level2caps($level));
230
+
231
+ // Find caps to add and remove
232
+ $add_caps = array_diff_key($new_caps, $old_caps);
233
+ $del_caps = array_diff_key(array_merge($old_caps, $stored_negative_role_caps), $new_caps);
234
+
235
+ $changed_caps = array();
236
+ foreach( array_intersect_key( $new_caps, $old_caps ) as $cap_name => $cap_val ) {
237
+ if ( $new_caps[$cap_name] != $old_caps[$cap_name] )
238
+ $changed_caps[$cap_name] = $cap_val;
239
+ }
240
+
241
+ $add_caps = array_merge( $add_caps, $changed_caps );
242
+
243
+ if ( ! $is_administrator = current_user_can('administrator') ) {
244
+ unset($add_caps['manage_capabilities']);
245
+ unset($del_caps['manage_capabilities']);
246
+ }
247
+
248
+ if ( 'administrator' == $role_name && isset($del_caps['manage_capabilities']) ) {
249
+ unset($del_caps['manage_capabilities']);
250
+ ak_admin_error(__('You cannot remove Manage Capabilities from Administrators', 'capsman-enhanced'));
251
+ }
252
+
253
+ // additional safeguard against removal of read capability
254
+ if ( isset( $del_caps['read'] ) && _cme_is_read_removal_blocked( $role_name ) ) {
255
+ unset( $del_caps['read'] );
256
+ }
257
+
258
+ // Add new capabilities to role
259
+ foreach ( $add_caps as $cap => $grant ) {
260
+ if ( $is_administrator || current_user_can($cap) )
261
+ $role->add_cap( $cap, $grant );
262
+ }
263
+
264
+ // Remove capabilities from role
265
+ foreach ( $del_caps as $cap => $grant) {
266
+ if ( $is_administrator || current_user_can($cap) )
267
+ $role->remove_cap($cap);
268
+ }
269
+
270
+ $this->cm->log_db_roles();
271
+
272
+ if (is_multisite() && is_super_admin() && is_main_site()) {
273
+ if ( ! $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) )
274
+ $autocreate_roles = array();
275
+
276
+ $this_role_autocreate = ! empty($_REQUEST['cme_autocreate_role']);
277
+
278
+ if ( $this_role_autocreate && ! in_array( $role_name, $autocreate_roles ) ) {
279
+ $autocreate_roles []= $role_name;
280
+ update_site_option( 'cme_autocreate_roles', $autocreate_roles );
281
+ }
282
+
283
+ if ( ! $this_role_autocreate && in_array( $role_name, $autocreate_roles ) ) {
284
+ $autocreate_roles = array_diff( $autocreate_roles, array( $role_name ) );
285
+ update_site_option( 'cme_autocreate_roles', $autocreate_roles );
286
+ }
287
+
288
+ $do_role_sync = !empty($_REQUEST['cme_net_sync_role']);
289
+ $do_option_sync = !empty($_REQUEST['cme_net_sync_options']);
290
+
291
+ if ($do_role_sync || $do_option_sync) {
292
+ // loop through all sites on network, creating or updating role def
293
+
294
+ global $wpdb, $wp_roles, $blog_id;
295
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs ORDER BY blog_id" );
296
+ $orig_blog_id = $blog_id;
297
+
298
+ if ($do_role_sync) {
299
+ $role_caption = $wp_roles->role_names[$role_name];
300
+
301
+ $new_caps = ( is_array($caps) ) ? array_map('boolval', $caps) : array();
302
+ $new_caps = array_merge($new_caps, ak_level2caps($level) );
303
+
304
+ $admin_role = $wp_roles->get_role('administrator');
305
+ $main_admin_caps = array_merge( $admin_role->capabilities, ak_level2caps(10) );
306
+ }
307
+
308
+ $sync_options = [];
309
+
310
+ if ($do_option_sync) {
311
+ // capability-related options
312
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
313
+
314
+ foreach(['define_create_posts_cap', 'enabled_post_types', 'enabled_taxonomies'] as $option_name) {
315
+ $sync_options["{$pp_prefix}_$option_name"] = get_option("{$pp_prefix}_$option_name");
316
+ }
317
+
318
+ $sync_options['cme_detailed_taxonomies'] = get_option('cme_detailed_taxonomies');
319
+ $sync_options['cme_enabled_post_types'] = get_option('cme_enabled_post_types');
320
+ $sync_options['presspermit_supplemental_role_defs'] = get_option('presspermit_supplemental_role_defs');
321
+ }
322
+
323
+ foreach ( $blog_ids as $id ) {
324
+ if ( is_main_site($id) )
325
+ continue;
326
+
327
+ switch_to_blog( $id );
328
+
329
+ if ($do_role_sync) {
330
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
331
+
332
+ if ( $blog_role = $wp_roles->get_role( $role_name ) ) {
333
+ $stored_role_caps = ( ! empty($blog_role->capabilities) && is_array($blog_role->capabilities) ) ? array_intersect( $blog_role->capabilities, array(true, 1) ) : array();
334
+
335
+ $old_caps = array_intersect_key( $stored_role_caps, $this->cm->capabilities);
336
+
337
+ // Find caps to add and remove
338
+ $add_caps = array_diff_key($new_caps, $old_caps);
339
+ $del_caps = array_intersect_key( array_diff_key($old_caps, $new_caps), $main_admin_caps ); // don't mess with caps that are totally unused on main site
340
+
341
+ // Add new capabilities to role
342
+ foreach ( $add_caps as $cap => $grant ) {
343
+ $wp_roles->roles[$role_name]['capabilities'][$cap] = $grant;
344
+
345
+ }
346
+
347
+ // Remove capabilities from role
348
+ foreach ( $del_caps as $cap => $grant) {
349
+ unset($wp_roles->roles[$role_name]['capabilities'][$cap]);
350
+ }
351
+
352
+ if ($wp_roles->use_db) {
353
+ update_option($wp_roles->role_key, $wp_roles->roles);
354
+ }
355
+ } else {
356
+ $wp_roles->add_role( $role_name, $role_caption, $new_caps );
357
+ }
358
+ }
359
+
360
+ foreach($sync_options as $option_name => $option_val) {
361
+ update_option($option_name, $option_val);
362
+ }
363
+
364
+ restore_current_blog();
365
+ }
366
+
367
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
368
+ }
369
+ } // endif multisite installation with super admin editing a main site role
370
+
371
+ pp_capabilities_autobackup();
372
+ }
373
+ }
374
+
375
+ if ( ! function_exists('boolval') ) {
376
+ function boolval( $val ) {
377
+ return (bool) $val;
378
+ }
379
+ }
includes/inflect-cme.php CHANGED
@@ -1,136 +1,136 @@
1
- <?php
2
-
3
- /**
4
- /* Inflect class by T. Brian Jones
5
- /* https://gist.github.com/tbrianjones/ba0460cc1d55f357e00b
6
- /*
7
- /* original source: http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/
8
- */
9
-
10
- /*
11
- The MIT License (MIT)
12
-
13
- Copyright (c) 2015
14
-
15
- Permission is hereby granted, free of charge, to any person obtaining a copy
16
- of this software and associated documentation files (the "Software"), to deal
17
- in the Software without restriction, including without limitation the rights
18
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
- copies of the Software, and to permit persons to whom the Software is
20
- furnished to do so, subject to the following conditions:
21
-
22
- The above copyright notice and this permission notice shall be included in
23
- all copies or substantial portions of the Software.
24
-
25
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
- THE SOFTWARE.
32
- */
33
-
34
- // ORIGINAL NOTES
35
- //
36
- // Thanks to http://www.eval.ca/articles/php-pluralize (MIT license)
37
- // http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflections.rb (MIT license)
38
- // http://www.fortunecity.com/bally/durrus/153/gramch13.html
39
- // http://www2.gsu.edu/~wwwesl/egw/crump.htm
40
- //
41
- // Changes (12/17/07)
42
- // Major changes
43
- // --
44
- // Fixed irregular noun algorithm to use regular expressions just like the original Ruby source.
45
- // (this allows for things like fireman -> firemen
46
- // Fixed the order of the singular array, which was backwards.
47
- //
48
- // Minor changes
49
- // --
50
- // Removed incorrect pluralization rule for /([^aeiouy]|qu)ies$/ => $1y
51
- // Expanded on the list of exceptions for *o -> *oes, and removed rule for buffalo -> buffaloes
52
- // Removed dangerous singularization rule for /([^f])ves$/ => $1fe
53
- // Added more specific rules for singularizing lives, wives, knives, sheaves, loaves, and leaves and thieves
54
- // Added exception to /(us)es$/ => $1 rule for houses => house and blouses => blouse
55
- // Added excpetions for feet, geese and teeth
56
- // Added rule for deer -> deer
57
-
58
- // Changes:
59
- // Removed rule for virus -> viri
60
- // Added rule for potato -> potatoes
61
- // Added rule for *us -> *uses
62
-
63
- // Kevin Behrens : removed singularization code (not needed for CME)
64
- class CME_Inflect
65
- {
66
- static $plural = array(
67
- '/(quiz)$/i' => "$1zes",
68
- '/^(ox)$/i' => "$1en",
69
- '/([m|l])ouse$/i' => "$1ice",
70
- '/(matr|vert|ind)ix|ex$/i' => "$1ices",
71
- '/(x|ch|ss|sh)$/i' => "$1es",
72
- '/([^aeiouy]|qu)y$/i' => "$1ies",
73
- '/(hive)$/i' => "$1s",
74
- '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
75
- '/(shea|lea|loa|thie)f$/i' => "$1ves",
76
- '/sis$/i' => "ses",
77
- '/([ti])um$/i' => "$1a",
78
- '/(tomat|potat|ech|her|vet)o$/i'=> "$1oes",
79
- '/(bu)s$/i' => "$1ses",
80
- '/(alias)$/i' => "$1es",
81
- '/(octop)us$/i' => "$1i",
82
- '/(ax|test)is$/i' => "$1es",
83
- '/(us)$/i' => "$1es",
84
- '/s$/i' => "s",
85
- '/$/' => "s"
86
- );
87
-
88
- static $irregular = array(
89
- 'move' => 'moves',
90
- 'foot' => 'feet',
91
- 'goose' => 'geese',
92
- 'sex' => 'sexes',
93
- 'child' => 'children',
94
- 'man' => 'men',
95
- 'tooth' => 'teeth',
96
- 'person' => 'people',
97
- 'valve' => 'valves'
98
- );
99
-
100
- static $uncountable = array(
101
- 'sheep',
102
- 'fish',
103
- 'deer',
104
- 'series',
105
- 'species',
106
- 'money',
107
- 'rice',
108
- 'information',
109
- 'equipment'
110
- );
111
-
112
- public static function pluralize( $string ) {
113
- // save some time in the case that singular and plural are the same
114
- if ( in_array( strtolower( $string ), self::$uncountable ) ) {
115
- return $string;
116
- }
117
-
118
- // check for irregular singular forms
119
- foreach ( self::$irregular as $pattern => $result ) {
120
- $pattern = '/' . $pattern . '$/i';
121
-
122
- if ( preg_match( $pattern, $string ) ) {
123
- return preg_replace( $pattern, $result, $string);
124
- }
125
- }
126
-
127
- // check for matches using regular expressions
128
- foreach ( self::$plural as $pattern => $result ) {
129
- if ( preg_match( $pattern, $string ) ) {
130
- return preg_replace( $pattern, $result, $string );
131
- }
132
- }
133
-
134
- return $string;
135
- }
136
- }
1
+ <?php
2
+
3
+ /**
4
+ /* Inflect class by T. Brian Jones
5
+ /* https://gist.github.com/tbrianjones/ba0460cc1d55f357e00b
6
+ /*
7
+ /* original source: http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/
8
+ */
9
+
10
+ /*
11
+ The MIT License (MIT)
12
+
13
+ Copyright (c) 2015
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in
23
+ all copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
+ THE SOFTWARE.
32
+ */
33
+
34
+ // ORIGINAL NOTES
35
+ //
36
+ // Thanks to http://www.eval.ca/articles/php-pluralize (MIT license)
37
+ // http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/inflections.rb (MIT license)
38
+ // http://www.fortunecity.com/bally/durrus/153/gramch13.html
39
+ // http://www2.gsu.edu/~wwwesl/egw/crump.htm
40
+ //
41
+ // Changes (12/17/07)
42
+ // Major changes
43
+ // --
44
+ // Fixed irregular noun algorithm to use regular expressions just like the original Ruby source.
45
+ // (this allows for things like fireman -> firemen
46
+ // Fixed the order of the singular array, which was backwards.
47
+ //
48
+ // Minor changes
49
+ // --
50
+ // Removed incorrect pluralization rule for /([^aeiouy]|qu)ies$/ => $1y
51
+ // Expanded on the list of exceptions for *o -> *oes, and removed rule for buffalo -> buffaloes
52
+ // Removed dangerous singularization rule for /([^f])ves$/ => $1fe
53
+ // Added more specific rules for singularizing lives, wives, knives, sheaves, loaves, and leaves and thieves
54
+ // Added exception to /(us)es$/ => $1 rule for houses => house and blouses => blouse
55
+ // Added excpetions for feet, geese and teeth
56
+ // Added rule for deer -> deer
57
+
58
+ // Changes:
59
+ // Removed rule for virus -> viri
60
+ // Added rule for potato -> potatoes
61
+ // Added rule for *us -> *uses
62
+
63
+ // Kevin Behrens : removed singularization code (not needed for CME)
64
+ class CME_Inflect
65
+ {
66
+ static $plural = array(
67
+ '/(quiz)$/i' => "$1zes",
68
+ '/^(ox)$/i' => "$1en",
69
+ '/([m|l])ouse$/i' => "$1ice",
70
+ '/(matr|vert|ind)ix|ex$/i' => "$1ices",
71
+ '/(x|ch|ss|sh)$/i' => "$1es",
72
+ '/([^aeiouy]|qu)y$/i' => "$1ies",
73
+ '/(hive)$/i' => "$1s",
74
+ '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
75
+ '/(shea|lea|loa|thie)f$/i' => "$1ves",
76
+ '/sis$/i' => "ses",
77
+ '/([ti])um$/i' => "$1a",
78
+ '/(tomat|potat|ech|her|vet)o$/i'=> "$1oes",
79
+ '/(bu)s$/i' => "$1ses",
80
+ '/(alias)$/i' => "$1es",
81
+ '/(octop)us$/i' => "$1i",
82
+ '/(ax|test)is$/i' => "$1es",
83
+ '/(us)$/i' => "$1es",
84
+ '/s$/i' => "s",
85
+ '/$/' => "s"
86
+ );
87
+
88
+ static $irregular = array(
89
+ 'move' => 'moves',
90
+ 'foot' => 'feet',
91
+ 'goose' => 'geese',
92
+ 'sex' => 'sexes',
93
+ 'child' => 'children',
94
+ 'man' => 'men',
95
+ 'tooth' => 'teeth',
96
+ 'person' => 'people',
97
+ 'valve' => 'valves'
98
+ );
99
+
100
+ static $uncountable = array(
101
+ 'sheep',
102
+ 'fish',
103
+ 'deer',
104
+ 'series',
105
+ 'species',
106
+ 'money',
107
+ 'rice',
108
+ 'information',
109
+ 'equipment'
110
+ );
111
+
112
+ public static function pluralize( $string ) {
113
+ // save some time in the case that singular and plural are the same
114
+ if ( in_array( strtolower( $string ), self::$uncountable ) ) {
115
+ return $string;
116
+ }
117
+
118
+ // check for irregular singular forms
119
+ foreach ( self::$irregular as $pattern => $result ) {
120
+ $pattern = '/' . $pattern . '$/i';
121
+
122
+ if ( preg_match( $pattern, $string ) ) {
123
+ return preg_replace( $pattern, $result, $string);
124
+ }
125
+ }
126
+
127
+ // check for matches using regular expressions
128
+ foreach ( self::$plural as $pattern => $result ) {
129
+ if ( preg_match( $pattern, $string ) ) {
130
+ return preg_replace( $pattern, $result, $string );
131
+ }
132
+ }
133
+
134
+ return $string;
135
+ }
136
+ }
includes/manager.php CHANGED
@@ -1,1008 +1,1027 @@
1
- <?php
2
- /**
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Plugin to create and manage roles and capabilities.
6
- *
7
- * This is the plugin's original controller module, which is due for some refactoring.
8
- * It registers and handles menus, loads javascript, and processes or routes update operations from the Capabilities screen.
9
- *
10
- * Note: for lower overhead, this module is only loaded for Capabilities Pro URLs.
11
- * For all other wp-admin URLs, menus are registered by a separate skeleton module.
12
- *
13
- * @author Jordi Canals, Kevin Behrens
14
- * @copyright Copyright (C) 2009, 2010 Jordi Canals, (C) 2020 PublishPress
15
- * @license GNU General Public License version 2
16
- * @link https://publishpress.com/
17
- *
18
- *
19
- * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
20
- *
21
- * Modifications Copyright 2020, PublishPress <help@publishpress.com>
22
- *
23
- * This program is free software; you can redistribute it and/or
24
- * modify it under the terms of the GNU General Public License
25
- * version 2 as published by the Free Software Foundation.
26
- *
27
- * This program is distributed in the hope that it will be useful,
28
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
- * GNU General Public License for more details.
31
- *
32
- * You should have received a copy of the GNU General Public License
33
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
34
- */
35
-
36
- add_action( 'init', 'cme_update_pp_usage' ); // update early so resulting post type cap changes are applied for this request's UI construction
37
-
38
- function cme_update_pp_usage() {
39
- if ( ! empty($_REQUEST['update_filtered_types']) || ! empty($_REQUEST['update_filtered_taxonomies']) || ! empty($_REQUEST['update_detailed_taxonomies']) || ! empty($_REQUEST['SaveRole']) ) {
40
- check_admin_referer('capsman-general-manager');
41
-
42
- require_once( dirname(__FILE__).'/pp-handler.php' );
43
- return _cme_update_pp_usage();
44
- }
45
- }
46
-
47
- // Core WP roles to apply safeguard preventing accidental lockout from dashboard
48
- function _cme_core_roles() {
49
- return apply_filters( 'pp_caps_core_roles', array( 'administrator', 'editor', 'revisor', 'author', 'contributor', 'subscriber' ) );
50
- }
51
-
52
- function _cme_core_caps() {
53
- $core_caps = array_fill_keys( array( 'switch_themes', 'edit_themes', 'activate_plugins', 'edit_plugins', 'edit_users', 'edit_files', 'manage_options', 'moderate_comments',
54
- 'manage_links', 'upload_files', 'import', 'unfiltered_html', 'read', 'delete_users', 'create_users', 'unfiltered_upload', 'edit_dashboard',
55
- 'update_plugins', 'delete_plugins', 'install_plugins', 'update_themes', 'install_themes',
56
- 'update_core', 'list_users', 'remove_users', 'promote_users', 'edit_theme_options', 'delete_themes', 'export' ), true );
57
-
58
- ksort( $core_caps );
59
- return $core_caps;
60
- }
61
-
62
- function _cme_is_read_removal_blocked( $role_name ) {
63
- $role = get_role($role_name);
64
- $rcaps = $role->capabilities;
65
-
66
- $core_caps = array_diff_key( _cme_core_caps(), array_fill_keys( array( 'unfiltered_html', 'unfiltered_upload', 'upload_files', 'edit_files', 'read' ), true ) );
67
-
68
- if ( empty( $rcaps['dashboard_lockout_ok'] ) ) {
69
- $edit_caps = array();
70
- foreach ( get_post_types( array( 'public' => true ), 'object' ) as $type_obj ) {
71
- $edit_caps = array_merge( $edit_caps, array_values( array_diff_key( (array) $type_obj->cap, array( 'read_private_posts' => true ) ) ) );
72
- }
73
-
74
- $edit_caps = array_fill_keys( $edit_caps, true );
75
- unset( $edit_caps['read'] );
76
- unset( $edit_caps['upload_files'] );
77
- unset( $edit_caps['edit_files'] );
78
-
79
- if ( $role_has_admin_caps = in_array( $role_name, _cme_core_roles() ) && ( array_intersect_key( $rcaps, array_diff_key( $core_caps, array( 'read' => true ) ) ) || array_intersect_key( $rcaps, $edit_caps ) ) ) {
80
- return true;
81
- }
82
- }
83
-
84
- return false;
85
- }
86
-
87
- /**
88
- * Class CapabilityManager.
89
- * Sets the main environment for all Capability Manager components.
90
- *
91
- * @author Jordi Canals, Kevin Behrens
92
- * @link https://publishpress.com/
93
- */
94
- class CapabilityManager
95
- {
96
- /**
97
- * Array with all capabilities to be managed. (Depends on user caps).
98
- * The array keys are the capability, the value is its screen name.
99
- * @var array
100
- */
101
- var $capabilities = array();
102
-
103
- /**
104
- * Array with roles that can be managed. (Depends on user roles).
105
- * The array keys are the role name, the value is its translated name.
106
- * @var array
107
- */
108
- var $roles = array();
109
-
110
- /**
111
- * Current role we are managing
112
- * @var string
113
- */
114
- var $current;
115
-
116
- /**
117
- * Maximum level current manager can assign to a user.
118
- * @var int
119
- */
120
- private $max_level;
121
-
122
- private $log_db_role_objects = array();
123
-
124
- var $message;
125
-
126
- /**
127
- * Module ID. Is the module internal short name.
128
- *
129
- * @var string
130
- */
131
- public $ID;
132
-
133
- public function __construct()
134
- {
135
- $this->ID = 'capsman';
136
- $this->mod_url = plugins_url( '', CME_FILE );
137
-
138
- if (is_admin() && !empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page']) && (!empty($_POST['all_options']) || !empty($_POST['all_options_pro']))) {
139
- add_action('init', function() {
140
- if (isset($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'pp-capabilities-settings') && current_user_can('manage_capabilities')) {
141
- require_once (dirname(CME_FILE) . '/includes/settings-handler.php');
142
- }
143
- }, 1);
144
- }
145
-
146
- $this->moduleLoad();
147
-
148
- add_action('admin_menu', array($this, 'adminMenus'), 5); // execute prior to PP, to use menu hook
149
-
150
- // Load styles
151
- add_action('admin_print_styles', array($this, 'adminStyles'));
152
-
153
- if ( isset($_REQUEST['page']) && ( 'pp-capabilities' == $_REQUEST['page'] ) ) {
154
- add_action('admin_enqueue_scripts', array($this, 'adminScriptsPP'));
155
- }
156
-
157
- add_action('init', [$this, 'initRolesAdmin']);
158
-
159
- add_action('wp_ajax_pp-roles-add-role', [$this, 'handleRolesAjax']);
160
- add_action('wp_ajax_pp-roles-delete-role', [$this, 'handleRolesAjax']);
161
-
162
- if (defined('PRESSPERMIT_VERSION')) {
163
- add_action('wp_ajax_pp-roles-hide-role', [$this, 'handleRolesAjax']);
164
- add_action('wp_ajax_pp-roles-unhide-role', [$this, 'handleRolesAjax']);
165
- }
166
-
167
- //process export
168
- add_action( 'admin_init', [$this, 'processExport']);
169
- }
170
-
171
- /**
172
- * Enqueues administration styles.
173
- *
174
- * @hook action 'admin_print_styles'
175
- *
176
- * @return void
177
- */
178
- function adminStyles()
179
- {
180
- if (empty($_REQUEST['page'])
181
- || !in_array(
182
- $_REQUEST['page'],
183
- ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-nav-menus', 'pp-capabilities-editor-features', 'pp-capabilities-backup', 'pp-capabilities-settings', 'pp-capabilities-admin-features']
184
- )
185
- ) {
186
- return;
187
- }
188
-
189
- wp_enqueue_style('cme-admin-common', $this->mod_url . '/common/css/pressshack-admin.css', [], PUBLISHPRESS_CAPS_VERSION);
190
-
191
- wp_register_style( $this->ID . 'framework_admin', $this->mod_url . '/framework/styles/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
192
- wp_enqueue_style( $this->ID . 'framework_admin');
193
-
194
- wp_register_style( $this->ID . '_admin', $this->mod_url . '/common/css/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
195
- wp_enqueue_style( $this->ID . '_admin');
196
-
197
- $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : '';
198
- $url = $this->mod_url . "/common/js/admin{$suffix}.js";
199
- wp_enqueue_script( 'cme_admin', $url, array('jquery'), PUBLISHPRESS_CAPS_VERSION, true );
200
- wp_localize_script( 'cme_admin', 'cmeAdmin', [
201
- 'negationCaption' => __( 'Explicity negate this capability by storing as disabled', 'capsman-enhanced' ),
202
- 'typeCapsNegationCaption' => __( 'Explicitly negate these capabilities by storing as disabled', 'capsman-enhanced' ),
203
- 'typeCapUnregistered' => __( 'Post type registration does not define this capability distinctly', 'capsman-enhanced' ),
204
- 'capNegated' => __( 'This capability is explicitly negated. Click to add/remove normally.', 'capsman-enhanced' ),
205
- 'chkCaption' => __( 'Add or remove this capability from the WordPress role', 'capsman-enhanced' ),
206
- 'switchableCaption' => __( 'Add or remove capability from the role normally', 'capsman-enhanced' ),
207
- 'deleteWarning' => __( 'Are you sure you want to delete this item ?', 'capsman-enhanced' ),
208
- 'saveWarning' => __( 'Add or clear custom item entry before saving changes.', 'capsman-enhanced' )
209
- ]
210
- );
211
- }
212
-
213
- function adminScriptsPP() {
214
- wp_enqueue_style( 'plugin-install' );
215
- wp_enqueue_script( 'plugin-install' );
216
- add_thickbox();
217
- }
218
-
219
- /**
220
- * Creates some filters at module load time.
221
- *
222
- * @return void
223
- */
224
- protected function moduleLoad ()
225
- {
226
- $old_version = get_option($this->ID . '_version');
227
- if ( version_compare( $old_version, PUBLISHPRESS_CAPS_VERSION, 'ne') ) {
228
- update_option($this->ID . '_version', PUBLISHPRESS_CAPS_VERSION);
229
- $this->pluginUpdate();
230
- }
231
-
232
- // Only roles that a user can administer can be assigned to others.
233
- add_filter('editable_roles', array($this, 'filterEditRoles'));
234
-
235
- // Users with roles that cannot be managed, are not allowed to be edited.
236
- add_filter('map_meta_cap', array(&$this, 'filterUserEdit'), 10, 4);
237
-
238
- // ensure storage, retrieval of db-stored customizations to dynamic roles
239
- if ( isset($_REQUEST['page']) && in_array( $_REQUEST['page'], array( 'pp-capabilities', 'pp-capabilities-backup' ) ) ) {
240
- global $wpdb;
241
- $role_key = $wpdb->prefix . 'user_roles';
242
- $this->log_db_roles();
243
- add_filter( 'option_' . $role_key, array( &$this, 'reinstate_db_roles' ), PHP_INT_MAX );
244
- }
245
-
246
- $action = (defined('PP_CAPABILITIES_COMPAT_MODE')) ? 'init' : 'plugins_loaded';
247
- add_action( $action, array( &$this, 'processRoleUpdate' ) );
248
- }
249
-
250
- public function set_current_role($role_name) {
251
- global $current_user;
252
-
253
- if ($role_name && !empty($current_user) && !empty($current_user->ID)) {
254
- update_option("capsman_last_role_{$current_user->ID}", $role_name);
255
- }
256
- }
257
-
258
- public function get_last_role() {
259
- global $current_user;
260
-
261
- $role_name = get_option("capsman_last_role_{$current_user->ID}");
262
-
263
- if (!$role_name || !get_role($role_name)) {
264
- $role_name = get_option('default_role');
265
- }
266
-
267
- return $role_name;
268
- }
269
-
270
- // Direct query of stored role definitions
271
- function log_db_roles( $legacy_arg = '' ) {
272
- global $wpdb;
273
-
274
- $results = (array) maybe_unserialize( $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '{$wpdb->prefix}user_roles' LIMIT 1") );
275
- foreach( $results as $_role_name => $_role ) {
276
- $this->log_db_role_objects[$_role_name] = (object) $_role;
277
- }
278
-
279
- return $legacy_arg;
280
- }
281
-
282
- // note: this is only applied when accessing the cme role edit form
283
- function reinstate_db_roles( $passthru_roles = array() ) {
284
- global $wp_roles;
285
-
286
- if ( isset($wp_roles) && $this->log_db_role_objects ) {
287
- $intersect = array_intersect_key( $wp_roles->role_objects, $this->log_db_role_objects );
288
- foreach( array_keys( $intersect ) as $key ) {
289
- if ( ! empty( $this->log_db_role_objects[$key]->capabilities ) )
290
- $wp_roles->role_objects[$key]->capabilities = $this->log_db_role_objects[$key]->capabilities;
291
- }
292
- }
293
-
294
- return $passthru_roles;
295
- }
296
-
297
- /**
298
- * Updates Capability Manager to a new version
299
- *
300
- * @return void
301
- */
302
- protected function pluginUpdate ()
303
- {
304
- global $wpdb;
305
-
306
- $backup = get_option($this->ID . '_backup');
307
- if ( false === $backup ) { // No previous backup found. Save it!
308
- $roles = get_option($wpdb->prefix . 'user_roles');
309
- update_option( $this->ID . '_backup', $roles, false );
310
- update_option( $this->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
311
- }
312
-
313
- if (!$wpdb->get_var("SELECT COUNT(option_id) FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%'")) {
314
- pp_capabilities_autobackup();
315
- }
316
- }
317
-
318
- /**
319
- * Adds admin panel menus. (At plugins loading time. This is before plugins_loaded).
320
- * User needs to have 'manage_capabilities' to access this menus.
321
- * This is set as an action in the parent class constructor.
322
- *
323
- * @hook action admin_menu
324
- * @return void
325
- */
326
- public function adminMenus ()
327
- {
328
- // First we check if user is administrator and can 'manage_capabilities'.
329
- if ( current_user_can('administrator') && ! current_user_can('manage_capabilities') ) {
330
- $this->setAdminCapability();
331
- }
332
-
333
- add_action( 'admin_menu', array( &$this, 'cme_menu' ), 18 );
334
- }
335
-
336
- public function cme_menu() {
337
- $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
338
-
339
- $permissions_title = __('Capabilities', 'capsman-enhanced');
340
-
341
- $menu_order = 72;
342
-
343
- if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
344
- foreach ((array)get_option('active_plugins') as $plugin_file) {
345
- if ( false !== strpos($plugin_file, 'publishpress.php') ) {
346
- $menu_order = 27;
347
- }
348
- }
349
- }
350
-
351
- add_menu_page(
352
- $permissions_title,
353
- $permissions_title,
354
- $cap_name,
355
- 'pp-capabilities',
356
- array($this, 'generalManager'),
357
- 'dashicons-admin-network',
358
- $menu_order
359
- );
360
-
361
- $hook = add_submenu_page('pp-capabilities', __('Roles', 'capsman-enhanced'), __('Roles', 'capsman-enhanced'), $cap_name, 'pp-capabilities-roles', [$this, 'ManageRoles']);
362
-
363
- if (!empty($hook)) {
364
- add_action(
365
- "load-$hook",
366
- function() {
367
- require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
368
- admin_roles_page_load();
369
- }
370
- );
371
- }
372
-
373
- add_submenu_page('pp-capabilities', __('Editor Features', 'capsman-enhanced'), __('Editor Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-editor-features', [$this, 'ManageEditorFeatures']);
374
-
375
- add_submenu_page('pp-capabilities', __('Admin Features', 'capsman-enhanced'), __('Admin Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-features', [$this, 'ManageAdminFeatures']);
376
-
377
- do_action('pp-capabilities-admin-submenus');
378
-
379
- add_submenu_page('pp-capabilities', __('Backup', 'capsman-enhanced'), __('Backup', 'capsman-enhanced'), $cap_name, 'pp-capabilities-backup', array($this, 'backupTool'));
380
-
381
- if (defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
382
- add_submenu_page('pp-capabilities', __('Settings', 'capsman-enhanced'), __('Settings', 'capsman-enhanced'), $cap_name, 'pp-capabilities-settings', array($this, 'settingsPage'));
383
- }
384
-
385
- if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
386
- add_submenu_page(
387
- 'pp-capabilities',
388
- __('Upgrade to Pro', 'capsman-enhanced'),
389
- __('Upgrade to Pro', 'capsman-enhanced'),
390
- 'manage_capabilities',
391
- 'capsman-enhanced',
392
- array($this, 'generalManager')
393
- );
394
- }
395
- }
396
-
397
- function initRolesAdmin() {
398
- // @todo: solve order of execution issue so this column headers definition is not duplicated
399
- if (!empty($_REQUEST['page']) && ('pp-capabilities-roles' == $_REQUEST['page'])) {
400
- add_filter(
401
- "manage_capabilities_page_pp-capabilities-roles_columns",
402
-
403
- function($arr) {
404
- return [
405
- 'cb' => '<input type="checkbox"/>',
406
- 'name' => __('Name', 'capsman-enhanced'),
407
- 'role' => __('Role', 'capsman-enhanced'),
408
- 'count' => __('Users', 'capsman-enhanced'),
409
- ];
410
- }
411
- );
412
- }
413
- }
414
-
415
- function handleRolesAjax() {
416
- require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
417
-
418
- if (!class_exists('PP_Capabilities_Roles')) {
419
- require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
420
- }
421
-
422
- $roles = pp_capabilities_roles()->run();
423
- }
424
-
425
- /**
426
- * Manages roles
427
- *
428
- * @hook add_management_page
429
- * @return void
430
- */
431
- public function ManageRoles ()
432
- {
433
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
434
- // TODO: Implement exceptions.
435
- wp_die('<strong>' . esc_html__('You do not have permission to manage roles.', 'capsman-enhanced') . '</strong>');
436
- }
437
-
438
- require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
439
-
440
- if (!class_exists('PP_Capabilities_Roles')) {
441
- require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
442
- }
443
-
444
- $roles = pp_capabilities_roles()->run();
445
-
446
- require_once ( dirname(CME_FILE) . '/includes/roles/roles.php' );
447
- }
448
-
449
-
450
- /**
451
- * Manages Editor Features
452
- *
453
- * @return void
454
- */
455
- public function ManageEditorFeatures() {
456
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
457
- // TODO: Implement exceptions.
458
- wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capabilities-pro') . '</strong>');
459
- }
460
-
461
- $this->generateNames();
462
- $roles = array_keys($this->roles);
463
-
464
- if (!isset($this->current)) {
465
- if (empty($_POST) && !empty($_REQUEST['role'])) {
466
- $this->set_current_role(sanitize_key($_REQUEST['role']));
467
- }
468
- }
469
-
470
- if (!isset($this->current) || !get_role($this->current)) {
471
- $this->current = get_option('default_role');
472
- }
473
-
474
- if (!in_array($this->current, $roles)) {
475
- $this->current = array_shift($roles);
476
- }
477
-
478
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-editor-features-role']) && !empty($_REQUEST['_wpnonce'])) {
479
- if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-editor-features')) {
480
- wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capabilities-pro') . '</strong>');
481
- } else {
482
- $this->set_current_role(sanitize_key($_POST['ppc-editor-features-role']));
483
-
484
- $classic_editor = pp_capabilities_is_classic_editor_available();
485
-
486
- $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
487
-
488
- foreach ($def_post_types as $post_type) {
489
- if ($classic_editor) {
490
- $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_classic_{$post_type}"]) : [];
491
- $post_features_option = get_option("capsman_feature_restrict_classic_{$post_type}", []);
492
- $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
493
- update_option("capsman_feature_restrict_classic_{$post_type}", $post_features_option, false);
494
- }
495
-
496
- $posted_settings = (isset($_POST["capsman_feature_restrict_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_{$post_type}"]) : [];
497
- $post_features_option = get_option("capsman_feature_restrict_{$post_type}", []);
498
- $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
499
- update_option("capsman_feature_restrict_{$post_type}", $post_features_option, false);
500
- }
501
-
502
- ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
503
- }
504
- }
505
-
506
- do_action('pp_capabilities_editor_features');
507
- include(dirname(CME_FILE) . '/includes/features/editor-features.php');
508
- }
509
-
510
- /**
511
- * Manages Admin Features
512
- *
513
- * @return void
514
- */
515
- public function ManageAdminFeatures() {
516
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
517
- // TODO: Implement exceptions.
518
- wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capabilities-pro') . '</strong>');
519
- }
520
-
521
- $this->generateNames();
522
- $roles = array_keys($this->roles);
523
-
524
- if (!isset($this->current)) {
525
- if (empty($_POST) && !empty($_REQUEST['role'])) {
526
- $this->set_current_role(sanitize_key($_REQUEST['role']));
527
- }
528
- }
529
-
530
- if (!isset($this->current) || !get_role($this->current)) {
531
- $this->current = get_option('default_role');
532
- }
533
-
534
- if (!in_array($this->current, $roles)) {
535
- $this->current = array_shift($roles);
536
- }
537
-
538
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-admin-features-role']) && !empty($_REQUEST['_wpnonce'])) {
539
- if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-admin-features')) {
540
- wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capabilities-pro') . '</strong>');
541
- } else {
542
- $features_role = sanitize_key($_POST['ppc-admin-features-role']);
543
-
544
- $this->set_current_role($features_role);
545
-
546
- $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
547
- $disabled_admin_items[$features_role] = isset($_POST['capsman_disabled_admin_features']) ? array_map('sanitize_text_field', $_POST['capsman_disabled_admin_features']) : '';
548
-
549
- update_option('capsman_disabled_admin_features', $disabled_admin_items, false);
550
-
551
- //set reload option for instant reflection if user is updating own role
552
- if (in_array($features_role, wp_get_current_user()->roles)){
553
- $ppc_page_reload = '1';
554
- }
555
-
556
- ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
557
- }
558
- }
559
-
560
- include(dirname(CME_FILE) . '/includes/features/admin-features.php');
561
- }
562
-
563
- /**
564
- * Sets the 'manage_capabilities' cap to the administrator role.
565
- *
566
- * @return void
567
- */
568
- public function setAdminCapability ()
569
- {
570
- if ($admin = get_role('administrator')) {
571
- $admin->add_cap('manage_capabilities');
572
- }
573
- }
574
-
575
- /**
576
- * Filters roles that can be shown in roles list.
577
- * This is mainly used to prevent an user admin to create other users with
578
- * higher capabilities.
579
- *
580
- * @hook 'editable_roles' filter.
581
- *
582
- * @param $roles List of roles to check.
583
- * @return array Restircted roles list
584
- */
585
- function filterEditRoles ( $roles )
586
- {
587
- global $current_user;
588
-
589
- if (function_exists('wp_get_current_user') || defined('PP_CAPABILITIES_ROLES_FILTER_EARLY_EXECUTION')) { // Avoid downstream fatal error from premature current_user_can() call if get_editable_roles() is called too early
590
- $this->generateNames();
591
- $valid = array_keys($this->roles);
592
-
593
- foreach ( $roles as $role => $caps ) {
594
- if ( ! in_array($role, $valid) ) {
595
- unset($roles[$role]);
596
- }
597
- }
598
- }
599
-
600
- return $roles;
601
- }
602
-
603
- /**
604
- * Checks if a user can be edited or not by current administrator.
605
- * Returns array('do_not_allow') if user cannot be edited.
606
- *
607
- * @hook 'map_meta_cap' filter
608
- *
609
- * @param array $caps Current user capabilities
610
- * @param string $cap Capability to check
611
- * @param int $user_id Current user ID
612
- * @param array $args For our purpose, we receive edited user id at $args[0]
613
- * @return array Allowed capabilities.
614
- */
615
- function filterUserEdit ( $caps, $cap, $user_id, $args )
616
- {
617
- if ( ! in_array( $cap, array( 'edit_user', 'delete_user', 'promote_user', 'remove_user' ) ) || ( ! isset($args[0]) ) || $user_id == (int) $args[0] ) {
618
- return $caps;
619
- }
620
-
621
- $user = new WP_User( (int) $args[0] );
622
-
623
- $this->generateNames();
624
-
625
- if ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) {
626
- $valid = array_keys($this->roles);
627
-
628
- foreach ( $user->roles as $role ) {
629
- if ( ! in_array($role, $valid) ) {
630
- $caps = array('do_not_allow');
631
- break;
632
- }
633
- }
634
- } else {
635
- global $wp_roles;
636
-
637
- foreach ( $user->roles as $role ) {
638
- $r = get_role( $role );
639
- $level = ak_caps2level($r->capabilities);
640
-
641
- if ( ( ! $level ) && ( 'administrator' == $role ) )
642
- $level = 10;
643
-
644
- if ( $level > $this->max_level ) {
645
- $caps = array('do_not_allow');
646
- break;
647
- }
648
- }
649
-
650
- }
651
-
652
- return $caps;
653
- }
654
-
655
- function processRoleUpdate() {
656
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['SaveRole']) || ! empty($_REQUEST['AddCap']) ) ) {
657
- check_admin_referer('capsman-general-manager');
658
-
659
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
660
- // TODO: Implement exceptions.
661
- wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
662
- }
663
-
664
- if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
665
- $role = get_role(sanitize_key($_REQUEST['current']));
666
- $current_level = ($role) ? ak_caps2level($role->capabilities) : 0;
667
-
668
- $this->processAdminGeneral();
669
-
670
- $set_level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0;
671
-
672
- if ($set_level != $current_level) {
673
- global $wp_roles, $wp_version;
674
-
675
- if ( version_compare($wp_version, '4.9', '>=') ) {
676
- $wp_roles->for_site();
677
- } else {
678
- $wp_roles->reinit();
679
- }
680
-
681
- foreach( get_users(array('role' => sanitize_key($_REQUEST['current']), 'fields' => 'ID')) as $ID ) {
682
- $user = new WP_User($ID);
683
- $user->get_role_caps();
684
- $user->update_user_level_from_caps();
685
- }
686
- }
687
- }
688
- }
689
-
690
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['RenameRole']) ) ) {
691
- check_admin_referer('capsman-general-manager');
692
-
693
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
694
- // TODO: Implement exceptions.
695
- wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
696
- }
697
-
698
- if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
699
- $this->processAdminGeneral();
700
- }
701
- }
702
- }
703
-
704
- /**
705
- * Manages global settings admin.
706
- *
707
- * @hook add_submenu_page
708
- * @return void
709
- */
710
- function generalManager () {
711
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
712
- // TODO: Implement exceptions.
713
- wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
714
- }
715
-
716
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
717
- if ( empty($_REQUEST['SaveRole']) && empty($_REQUEST['AddCap']) && empty($_REQUEST['RenameRole']) ) {
718
- check_admin_referer('capsman-general-manager');
719
- $this->processAdminGeneral();
720
- } elseif ( ! empty($_REQUEST['SaveRole']) ) {
721
- ak_admin_notify( $this->message ); // moved update operation to earlier action to avoid UI refresh issues. But outputting notification there breaks styling.
722
- } elseif ( ! empty($_REQUEST['AddCap']) ) {
723
- ak_admin_notify( $this->message );
724
- }
725
- } else {
726
- if (!empty($_REQUEST['added'])) {
727
- ak_admin_notify(__('New capability added to role.', 'capsman-enhanced'));
728
- }
729
- }
730
-
731
- $this->generateNames();
732
- $roles = array_keys($this->roles);
733
-
734
- if ( ! isset($this->current) ) { // By default, we manage the default role
735
- if (empty($_POST) && !empty($_REQUEST['role'])) {
736
- $role = sanitize_key($_REQUEST['role']);
737
-
738
- if (!pp_capabilities_is_editable_role($role)) {
739
- wp_die(esc_html__('The selected role is not editable.', 'capsman-enhanced'));
740
- }
741
-
742
- $this->set_current_role($role);
743
- }
744
- }
745
-
746
- if (!isset($this->current) || !get_role($this->current)) {
747
- $this->current = $this->get_last_role();
748
- }
749
-
750
- if ( ! in_array($this->current, $roles) ) { // Current role has been deleted.
751
- $this->current = array_shift($roles);
752
- }
753
-
754
- include ( dirname(CME_FILE) . '/includes/admin.php' );
755
- }
756
-
757
- /**
758
- * Processes and saves the changes in the general capabilities form.
759
- *
760
- * @return void
761
- */
762
- private function processAdminGeneral ()
763
- {
764
- check_admin_referer('capsman-general-manager');
765
-
766
- if (! isset($_POST['action']) || 'update' != $_POST['action'] ) {
767
- // TODO: Implement exceptions. This must be a fatal error.
768
- ak_admin_error(__('Bad form Received', 'capsman-enhanced'));
769
- return;
770
- }
771
-
772
- // Select a new role.
773
- if ( ! empty($post['LoadRole']) && !empty($_POST['role']) ) {
774
- $this->set_current_role(sanitize_key($_POST['role']));
775
- } elseif (!empty($_POST['current'])) {
776
- $this->set_current_role(sanitize_key($_POST['current']));
777
-
778
- require_once( dirname(__FILE__).'/handler.php' );
779
- $capsman_modify = new CapsmanHandler( $this );
780
- $capsman_modify->processAdminGeneral();
781
- }
782
- }
783
-
784
- /**
785
- * Callback function to create names.
786
- * Replaces underscores by spaces and uppercases the first letter.
787
- *
788
- * @access private
789
- * @param string $cap Capability name.
790
- * @return string The generated name.
791
- */
792
- function _capNamesCB ( $cap )
793
- {
794
- $cap = str_replace('_', ' ', $cap);
795
-
796
- return $cap;
797
- }
798
-
799
- /**
800
- * Generates an array with the system capability names.
801
- * The key is the capability and the value the created screen name.
802
- *
803
- * @uses self::_capNamesCB()
804
- * @return void
805
- */
806
- function generateSysNames ()
807
- {
808
- $this->max_level = 10;
809
- $this->roles = ak_get_roles(true);
810
- $caps = array();
811
-
812
- foreach ( array_keys($this->roles) as $role ) {
813
- $role_caps = get_role($role);
814
- $caps = array_merge( $caps, (array) $role_caps->capabilities ); // user reported PHP 5.3.3 error without array cast
815
- }
816
-
817
- $keys = array_keys($caps);
818
- $names = array_map(array($this, '_capNamesCB'), $keys);
819
- $this->capabilities = array_combine($keys, $names);
820
-
821
- asort($this->capabilities);
822
- }
823
-
824
- /**
825
- * Generates an array with the user capability names.
826
- * If user has 'administrator' role, system roles are generated.
827
- * The key is the capability and the value the created screen name.
828
- * A user cannot manage more capabilities that has himself (Except for administrators).
829
- *
830
- * @uses self::_capNamesCB()
831
- * @return void
832
- */
833
- function generateNames ()
834
- {
835
- if ( current_user_can('administrator') || ( is_multisite() && is_super_admin() ) ) {
836
- $this->generateSysNames();
837
- } else {
838
- global $user_ID;
839
- $user = new WP_User($user_ID);
840
- $this->max_level = ak_caps2level($user->allcaps);
841
-
842
- $keys = array_keys($user->allcaps);
843
- $names = array_map(array($this, '_capNamesCB'), $keys);
844
-
845
- $this->capabilities = ( $keys ) ? array_combine($keys, $names) : array();
846
-
847
- $roles = ak_get_roles(true);
848
- unset($roles['administrator']);
849
-
850
- if ( ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) || ( ! empty( $_REQUEST['page'] ) && 'pp-capabilities' == $_REQUEST['page'] ) ) {
851
- foreach ( $user->roles as $role ) { // Unset the roles from capability list.
852
- unset ( $this->capabilities[$role] );
853
- unset ( $roles[$role]); // User cannot manage his roles.
854
- }
855
- }
856
-
857
- asort($this->capabilities);
858
-
859
- foreach ( array_keys($roles) as $role ) {
860
- $r = get_role($role);
861
- $level = ak_caps2level($r->capabilities);
862
-
863
- if ( $level > $this->max_level ) {
864
- unset($roles[$role]);
865
- }
866
- }
867
-
868
- $this->roles = $roles;
869
- }
870
- }
871
-
872
- /**
873
- * Manages backup, restore and resset roles and capabilities
874
- *
875
- * @hook add_management_page
876
- * @return void
877
- */
878
- function backupTool ()
879
- {
880
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles')) {
881
- // TODO: Implement exceptions.
882
- wp_die('<strong>' . esc_html__('You do not have permission to restore roles.', 'capsman-enhanced') . '</strong>');
883
- }
884
-
885
- if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
886
- check_admin_referer('pp-capabilities-backup');
887
- require_once( dirname(__FILE__).'/backup-handler.php' );
888
- $cme_backup_handler = new Capsman_BackupHandler( $this );
889
- $cme_backup_handler->processBackupTool();
890
- }
891
-
892
- if ( isset($_GET['action']) && 'reset-defaults' == $_GET['action']) {
893
- check_admin_referer('capsman-reset-defaults');
894
- require_once( dirname(__FILE__).'/backup-handler.php' );
895
- $cme_backup_handler = new Capsman_BackupHandler( $this );
896
- $cme_backup_handler->backupToolReset();
897
- }
898
-
899
- include ( dirname(CME_FILE) . '/includes/backup.php' );
900
- }
901
-
902
-
903
- /**
904
- * Processes export.
905
- *
906
- * This function need to run in admin init
907
- * to enable clean download.
908
- *
909
- * @return void
910
- */
911
- function processExport()
912
- {
913
- global $wpdb;
914
-
915
- if ( isset($_POST['export_backup']) && isset($_POST['pp_capabilities_export_section']) && !empty($_POST['pp_capabilities_export_section'])) {
916
- check_admin_referer('pp-capabilities-backup');
917
-
918
- if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles')) {
919
- // TODO: Implement exceptions.
920
- wp_die('<strong>' . esc_html__('You do not have permission to perform this action.', 'capsman-enhanced') . '</strong>');
921
- }
922
-
923
- $export_option = array_map('sanitize_text_field', $_POST['pp_capabilities_export_section']);
924
- $backup_sections = pp_capabilities_backup_sections();
925
- $charset = get_option( 'blog_charset' );
926
- $data = [];
927
-
928
- //add role
929
- if(in_array('user_roles', $export_option)){
930
- $data['user_roles'] = get_option($wpdb->prefix . 'user_roles');
931
- }
932
-
933
- //other section
934
- foreach($backup_sections as $backup_key => $backup_section){
935
-
936
- if(!in_array($backup_key, $export_option)){
937
- continue;
938
- }
939
- $section_options = $backup_section['options'];
940
- if(is_array($section_options) && !empty($section_options)){
941
- foreach($section_options as $section_option){
942
- $active_backup[] = $backup_section['label'];
943
- $data[$section_option] = get_option($section_option);
944
- }
945
- }
946
- }
947
-
948
- // Set the download headers.
949
- nocache_headers();
950
- header( 'Content-Type: application/json; charset=' . $charset );
951
- header( 'Content-Disposition: attachment; filename=capabilities-export-' . current_time('Y-m-d_g-i-s_a') . '.json' );
952
- header( "Expires: 0" );
953
-
954
- // Serialize the export data.
955
- echo serialize( $data );
956
-
957
- // Start the download.
958
- die();
959
-
960
- }
961
- }
962
-
963
- function settingsPage() {
964
- include ( dirname(CME_FILE) . '/includes/settings.php' );
965
- }
966
- }
967
-
968
- function cme_publishpressFooter() {
969
- ?>
970
- <footer>
971
-
972
- <div class="pp-rating">
973
- <a href="https://wordpress.org/support/plugin/capability-manager-enhanced/reviews/#new-post" target="_blank" rel="noopener noreferrer">
974
- <?php printf(
975
- esc_html__('If you like %s, please leave us a %s rating. Thank you!', 'capsman-enhanced'),
976
- '<strong>PublishPress Capabilities</strong>',
977
- '<span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span>'
978
- );
979
- ?>
980
- </a>
981
- </div>
982
-
983
- <hr>
984
- <nav>
985
- <ul>
986
- <li><a href="https://publishpress.com/capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('About PublishPress Capabilities', 'capsman-enhanced');?>"><?php esc_html_e('About', 'capsman-enhanced');?>
987
- </a></li>
988
- <li><a href="https://publishpress.com/knowledge-base/how-to-use-capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Capabilites Documentation', 'capsman-enhanced');?>"><?php esc_html_e('Documentation', 'capsman-enhanced');?>
989
- </a></li>
990
- <li><a href="https://publishpress.com/contact" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Contact the PublishPress team', 'capsman-enhanced');?>"><?php esc_html_e('Contact', 'capsman-enhanced');?>
991
- </a></li>
992
- <li><a href="https://twitter.com/publishpresscom" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-twitter"></span>
993
- </a></li>
994
- <li><a href="https://facebook.com/publishpress" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-facebook"></span>
995
- </a></li>
996
- </ul>
997
- </nav>
998
-
999
- <div class="pp-pressshack-logo">
1000
- <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
1001
-
1002
- <img src="<?php echo esc_url_raw(plugins_url('', CME_FILE) . '/common/img/publishpress-logo.png');?>" />
1003
- </a>
1004
- </div>
1005
-
1006
- </footer>
1007
- <?php
1008
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Plugin to create and manage roles and capabilities.
6
+ *
7
+ * This is the plugin's original controller module, which is due for some refactoring.
8
+ * It registers and handles menus, loads javascript, and processes or routes update operations from the Capabilities screen.
9
+ *
10
+ * Note: for lower overhead, this module is only loaded for Capabilities Pro URLs.
11
+ * For all other wp-admin URLs, menus are registered by a separate skeleton module.
12
+ *
13
+ * @author Jordi Canals, Kevin Behrens
14
+ * @copyright Copyright (C) 2009, 2010 Jordi Canals, (C) 2020 PublishPress
15
+ * @license GNU General Public License version 2
16
+ * @link https://publishpress.com/
17
+ *
18
+ *
19
+ * Copyright 2009, 2010 Jordi Canals <devel@jcanals.cat>
20
+ *
21
+ * Modifications Copyright 2020, PublishPress <help@publishpress.com>
22
+ *
23
+ * This program is free software; you can redistribute it and/or
24
+ * modify it under the terms of the GNU General Public License
25
+ * version 2 as published by the Free Software Foundation.
26
+ *
27
+ * This program is distributed in the hope that it will be useful,
28
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
+ * GNU General Public License for more details.
31
+ *
32
+ * You should have received a copy of the GNU General Public License
33
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
34
+ */
35
+
36
+ add_action( 'init', 'cme_update_pp_usage' ); // update early so resulting post type cap changes are applied for this request's UI construction
37
+
38
+ function cme_update_pp_usage() {
39
+ if ( ! empty($_REQUEST['update_filtered_types']) || ! empty($_REQUEST['update_filtered_taxonomies']) || ! empty($_REQUEST['update_detailed_taxonomies']) || ! empty($_REQUEST['SaveRole']) ) {
40
+ check_admin_referer('capsman-general-manager');
41
+
42
+ require_once( dirname(__FILE__).'/pp-handler.php' );
43
+ return _cme_update_pp_usage();
44
+ }
45
+ }
46
+
47
+ // Core WP roles to apply safeguard preventing accidental lockout from dashboard
48
+ function _cme_core_roles() {
49
+ return apply_filters( 'pp_caps_core_roles', array( 'administrator', 'editor', 'revisor', 'author', 'contributor', 'subscriber' ) );
50
+ }
51
+
52
+ function _cme_core_caps() {
53
+ $core_caps = array_fill_keys( array( 'switch_themes', 'edit_themes', 'activate_plugins', 'edit_plugins', 'edit_users', 'edit_files', 'manage_options', 'moderate_comments',
54
+ 'manage_links', 'upload_files', 'import', 'unfiltered_html', 'read', 'delete_users', 'create_users', 'unfiltered_upload', 'edit_dashboard',
55
+ 'update_plugins', 'delete_plugins', 'install_plugins', 'update_themes', 'install_themes',
56
+ 'update_core', 'list_users', 'remove_users', 'promote_users', 'edit_theme_options', 'delete_themes', 'export' ), true );
57
+
58
+ ksort( $core_caps );
59
+ return $core_caps;
60
+ }
61
+
62
+ function _cme_is_read_removal_blocked( $role_name ) {
63
+ $role = get_role($role_name);
64
+ $rcaps = $role->capabilities;
65
+
66
+ $core_caps = array_diff_key( _cme_core_caps(), array_fill_keys( array( 'unfiltered_html', 'unfiltered_upload', 'upload_files', 'edit_files', 'read' ), true ) );
67
+
68
+ if ( empty( $rcaps['dashboard_lockout_ok'] ) ) {
69
+ $edit_caps = array();
70
+ foreach ( get_post_types( array( 'public' => true ), 'object' ) as $type_obj ) {
71
+ $edit_caps = array_merge( $edit_caps, array_values( array_diff_key( (array) $type_obj->cap, array( 'read_private_posts' => true ) ) ) );
72
+ }
73
+
74
+ $edit_caps = array_fill_keys( $edit_caps, true );
75
+ unset( $edit_caps['read'] );
76
+ unset( $edit_caps['upload_files'] );
77
+ unset( $edit_caps['edit_files'] );
78
+
79
+ if ( $role_has_admin_caps = in_array( $role_name, _cme_core_roles() ) && ( array_intersect_key( $rcaps, array_diff_key( $core_caps, array( 'read' => true ) ) ) || array_intersect_key( $rcaps, $edit_caps ) ) ) {
80
+ return true;
81
+ }
82
+ }
83
+
84
+ return false;
85
+ }
86
+
87
+ /**
88
+ * Class CapabilityManager.
89
+ * Sets the main environment for all Capability Manager components.
90
+ *
91
+ * @author Jordi Canals, Kevin Behrens
92
+ * @link https://publishpress.com/
93
+ */
94
+ class CapabilityManager
95
+ {
96
+ /**
97
+ * Array with all capabilities to be managed. (Depends on user caps).
98
+ * The array keys are the capability, the value is its screen name.
99
+ * @var array
100
+ */
101
+ var $capabilities = array();
102
+
103
+ /**
104
+ * Array with roles that can be managed. (Depends on user roles).
105
+ * The array keys are the role name, the value is its translated name.
106
+ * @var array
107
+ */
108
+ var $roles = array();
109
+
110
+ /**
111
+ * Current role we are managing
112
+ * @var string
113
+ */
114
+ var $current;
115
+
116
+ /**
117
+ * Maximum level current manager can assign to a user.
118
+ * @var int
119
+ */
120
+ private $max_level;
121
+
122
+ private $log_db_role_objects = array();
123
+
124
+ var $message;
125
+
126
+ /**
127
+ * Module ID. Is the module internal short name.
128
+ *
129
+ * @var string
130
+ */
131
+ public $ID;
132
+
133
+ public function __construct()
134
+ {
135
+ $this->ID = 'capsman';
136
+ $this->mod_url = plugins_url( '', CME_FILE );
137
+
138
+ if (is_admin() && !empty($_REQUEST['page']) && ('pp-capabilities-settings' == $_REQUEST['page']) && (!empty($_POST['all_options']) || !empty($_POST['all_options_pro']))) {
139
+ add_action('init', function() {
140
+ if (isset($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'pp-capabilities-settings') && current_user_can('manage_capabilities')) {
141
+ require_once (dirname(CME_FILE) . '/includes/settings-handler.php');
142
+ }
143
+ }, 1);
144
+ }
145
+
146
+ $this->moduleLoad();
147
+
148
+ add_action('admin_menu', array($this, 'adminMenus'), 5); // execute prior to PP, to use menu hook
149
+
150
+ // Load styles
151
+ add_action('admin_print_styles', array($this, 'adminStyles'));
152
+
153
+ if ( isset($_REQUEST['page']) && ( 'pp-capabilities' == $_REQUEST['page'] ) ) {
154
+ add_action('admin_enqueue_scripts', array($this, 'adminScriptsPP'));
155
+ }
156
+
157
+ add_action('init', [$this, 'initRolesAdmin']);
158
+
159
+ add_action('wp_ajax_pp-roles-add-role', [$this, 'handleRolesAjax']);
160
+ add_action('wp_ajax_pp-roles-delete-role', [$this, 'handleRolesAjax']);
161
+
162
+ if (defined('PRESSPERMIT_VERSION')) {
163
+ add_action('wp_ajax_pp-roles-hide-role', [$this, 'handleRolesAjax']);
164
+ add_action('wp_ajax_pp-roles-unhide-role', [$this, 'handleRolesAjax']);
165
+ }
166
+
167
+ //process export
168
+ add_action( 'admin_init', [$this, 'processExport']);
169
+ }
170
+
171
+ /**
172
+ * Enqueues administration styles.
173
+ *
174
+ * @hook action 'admin_print_styles'
175
+ *
176
+ * @return void
177
+ */
178
+ function adminStyles()
179
+ {
180
+ if (empty($_REQUEST['page'])
181
+ || !in_array(
182
+ $_REQUEST['page'],
183
+ ['pp-capabilities', 'pp-capabilities-roles', 'pp-capabilities-admin-menus', 'pp-capabilities-nav-menus', 'pp-capabilities-editor-features', 'pp-capabilities-backup', 'pp-capabilities-settings', 'pp-capabilities-admin-features']
184
+ )
185
+ ) {
186
+ return;
187
+ }
188
+
189
+ wp_enqueue_style('cme-admin-common', $this->mod_url . '/common/css/pressshack-admin.css', [], PUBLISHPRESS_CAPS_VERSION);
190
+
191
+ wp_register_style( $this->ID . 'framework_admin', $this->mod_url . '/framework/styles/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
192
+ wp_enqueue_style( $this->ID . 'framework_admin');
193
+
194
+ wp_register_style( $this->ID . '_admin', $this->mod_url . '/common/css/admin.css', false, PUBLISHPRESS_CAPS_VERSION);
195
+ wp_enqueue_style( $this->ID . '_admin');
196
+
197
+ $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : '';
198
+ $url = $this->mod_url . "/common/js/admin{$suffix}.js";
199
+ wp_enqueue_script( 'cme_admin', $url, array('jquery'), PUBLISHPRESS_CAPS_VERSION, true );
200
+ wp_localize_script( 'cme_admin', 'cmeAdmin', [
201
+ 'negationCaption' => __( 'Explicity negate this capability by storing as disabled', 'capsman-enhanced' ),
202
+ 'typeCapsNegationCaption' => __( 'Explicitly negate these capabilities by storing as disabled', 'capsman-enhanced' ),
203
+ 'typeCapUnregistered' => __( 'Post type registration does not define this capability distinctly', 'capsman-enhanced' ),
204
+ 'capNegated' => __( 'This capability is explicitly negated. Click to add/remove normally.', 'capsman-enhanced' ),
205
+ 'chkCaption' => __( 'Add or remove this capability from the WordPress role', 'capsman-enhanced' ),
206
+ 'switchableCaption' => __( 'Add or remove capability from the role normally', 'capsman-enhanced' ),
207
+ 'deleteWarning' => __( 'Are you sure you want to delete this item ?', 'capsman-enhanced' ),
208
+ 'saveWarning' => __( 'Add or clear custom item entry before saving changes.', 'capsman-enhanced' )
209
+ ]
210
+ );
211
+ }
212
+
213
+ function adminScriptsPP() {
214
+ wp_enqueue_style( 'plugin-install' );
215
+ wp_enqueue_script( 'plugin-install' );
216
+ add_thickbox();
217
+ }
218
+
219
+ /**
220
+ * Creates some filters at module load time.
221
+ *
222
+ * @return void
223
+ */
224
+ protected function moduleLoad ()
225
+ {
226
+ $old_version = get_option($this->ID . '_version');
227
+ if ( version_compare( $old_version, PUBLISHPRESS_CAPS_VERSION, 'ne') ) {
228
+ update_option($this->ID . '_version', PUBLISHPRESS_CAPS_VERSION);
229
+ $this->pluginUpdate();
230
+ }
231
+
232
+ // Only roles that a user can administer can be assigned to others.
233
+ add_filter('editable_roles', array($this, 'filterEditRoles'));
234
+
235
+ // Users with roles that cannot be managed, are not allowed to be edited.
236
+ add_filter('map_meta_cap', array(&$this, 'filterUserEdit'), 10, 4);
237
+
238
+ // ensure storage, retrieval of db-stored customizations to dynamic roles
239
+ if ( isset($_REQUEST['page']) && in_array( $_REQUEST['page'], array( 'pp-capabilities', 'pp-capabilities-backup' ) ) ) {
240
+ global $wpdb;
241
+ $role_key = $wpdb->prefix . 'user_roles';
242
+ $this->log_db_roles();
243
+ add_filter( 'option_' . $role_key, array( &$this, 'reinstate_db_roles' ), PHP_INT_MAX );
244
+ }
245
+
246
+ $action = (defined('PP_CAPABILITIES_COMPAT_MODE')) ? 'init' : 'plugins_loaded';
247
+ add_action( $action, array( &$this, 'processRoleUpdate' ) );
248
+ }
249
+
250
+ public function set_current_role($role_name) {
251
+ global $current_user;
252
+
253
+ if ($role_name && !empty($current_user) && !empty($current_user->ID)) {
254
+ update_option("capsman_last_role_{$current_user->ID}", $role_name);
255
+ }
256
+ }
257
+
258
+ public function get_last_role() {
259
+ global $current_user;
260
+
261
+ $role_name = get_option("capsman_last_role_{$current_user->ID}");
262
+
263
+ if (!$role_name || !get_role($role_name)) {
264
+ $role_name = get_option('default_role');
265
+ }
266
+
267
+ return $role_name;
268
+ }
269
+
270
+ // Direct query of stored role definitions
271
+ function log_db_roles( $legacy_arg = '' ) {
272
+ global $wpdb;
273
+
274
+ $results = (array) maybe_unserialize( $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = '{$wpdb->prefix}user_roles' LIMIT 1") );
275
+ foreach( $results as $_role_name => $_role ) {
276
+ $this->log_db_role_objects[$_role_name] = (object) $_role;
277
+ }
278
+
279
+ return $legacy_arg;
280
+ }
281
+
282
+ // note: this is only applied when accessing the cme role edit form
283
+ function reinstate_db_roles( $passthru_roles = array() ) {
284
+ global $wp_roles;
285
+
286
+ if ( isset($wp_roles) && $this->log_db_role_objects ) {
287
+ $intersect = array_intersect_key( $wp_roles->role_objects, $this->log_db_role_objects );
288
+ foreach( array_keys( $intersect ) as $key ) {
289
+ if ( ! empty( $this->log_db_role_objects[$key]->capabilities ) )
290
+ $wp_roles->role_objects[$key]->capabilities = $this->log_db_role_objects[$key]->capabilities;
291
+ }
292
+ }
293
+
294
+ return $passthru_roles;
295
+ }
296
+
297
+ /**
298
+ * Updates Capability Manager to a new version
299
+ *
300
+ * @return void
301
+ */
302
+ protected function pluginUpdate ()
303
+ {
304
+ global $wpdb;
305
+
306
+ $backup = get_option($this->ID . '_backup');
307
+ if ( false === $backup ) { // No previous backup found. Save it!
308
+ $roles = get_option($wpdb->prefix . 'user_roles');
309
+ update_option( $this->ID . '_backup', $roles, false );
310
+ update_option( $this->ID . '_backup_datestamp', current_time( 'timestamp' ), false );
311
+ }
312
+
313
+ if (!$wpdb->get_var("SELECT COUNT(option_id) FROM $wpdb->options WHERE option_name LIKE 'cme_backup_auto_%'")) {
314
+ pp_capabilities_autobackup();
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Adds admin panel menus. (At plugins loading time. This is before plugins_loaded).
320
+ * User needs to have 'manage_capabilities' to access this menus.
321
+ * This is set as an action in the parent class constructor.
322
+ *
323
+ * @hook action admin_menu
324
+ * @return void
325
+ */
326
+ public function adminMenus ()
327
+ {
328
+ // First we check if user is administrator and can 'manage_capabilities'.
329
+ if ( current_user_can('administrator') && ! current_user_can('manage_capabilities') ) {
330
+ $this->setAdminCapability();
331
+ }
332
+
333
+ add_action( 'admin_menu', array( &$this, 'cme_menu' ), 18 );
334
+ }
335
+
336
+ public function cme_menu() {
337
+ $cap_name = (is_multisite() && is_super_admin()) ? 'read' : 'manage_capabilities';
338
+
339
+ $permissions_title = __('Capabilities', 'capsman-enhanced');
340
+
341
+ $menu_order = 72;
342
+
343
+ if (defined('PUBLISHPRESS_PERMISSIONS_MENU_GROUPING')) {
344
+ foreach ((array)get_option('active_plugins') as $plugin_file) {
345
+ if ( false !== strpos($plugin_file, 'publishpress.php') ) {
346
+ $menu_order = 27;
347
+ }
348
+ }
349
+ }
350
+
351
+ add_menu_page(
352
+ $permissions_title,
353
+ $permissions_title,
354
+ $cap_name,
355
+ 'pp-capabilities-roles',
356
+ array($this, 'ManageRoles'),
357
+ 'dashicons-admin-network',
358
+ $menu_order
359
+ );
360
+
361
+ $hook = add_submenu_page('pp-capabilities-roles', __('Roles', 'capsman-enhanced'), __('Roles', 'capsman-enhanced'), $cap_name, 'pp-capabilities-roles', [$this, 'ManageRoles']);
362
+
363
+ if (!empty($hook)) {
364
+ add_action(
365
+ "load-$hook",
366
+ function() {
367
+ require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
368
+ admin_roles_page_load();
369
+ }
370
+ );
371
+ }
372
+
373
+ add_submenu_page('pp-capabilities-roles', $permissions_title, $permissions_title, $cap_name, 'pp-capabilities', [$this, 'generalManager']);
374
+
375
+ add_submenu_page('pp-capabilities-roles', __('Editor Features', 'capsman-enhanced'), __('Editor Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-editor-features', [$this, 'ManageEditorFeatures']);
376
+
377
+ add_submenu_page('pp-capabilities-roles', __('Admin Features', 'capsman-enhanced'), __('Admin Features', 'capsman-enhanced'), $cap_name, 'pp-capabilities-admin-features', [$this, 'ManageAdminFeatures']);
378
+
379
+ do_action('pp-capabilities-admin-submenus');
380
+
381
+ add_submenu_page('pp-capabilities-roles', __('Backup', 'capsman-enhanced'), __('Backup', 'capsman-enhanced'), $cap_name, 'pp-capabilities-backup', array($this, 'backupTool'));
382
+
383
+ if (defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
384
+ add_submenu_page('pp-capabilities-roles', __('Settings', 'capsman-enhanced'), __('Settings', 'capsman-enhanced'), $cap_name, 'pp-capabilities-settings', array($this, 'settingsPage'));
385
+ }
386
+
387
+ if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) {
388
+ add_submenu_page(
389
+ 'pp-capabilities-roles',
390
+ __('Upgrade to Pro', 'capsman-enhanced'),
391
+ __('Upgrade to Pro', 'capsman-enhanced'),
392
+ 'manage_capabilities',
393
+ 'capsman-enhanced',
394
+ array($this, 'generalManager')
395
+ );
396
+ }
397
+ }
398
+
399
+ function initRolesAdmin() {
400
+ // @todo: solve order of execution issue so this column headers definition is not duplicated
401
+ if (!empty($_REQUEST['page']) && ('pp-capabilities-roles' == $_REQUEST['page'])) {
402
+ add_filter(
403
+ "manage_capabilities_page_pp-capabilities-roles_columns",
404
+
405
+ function($arr) {
406
+ return [
407
+ 'cb' => '<input type="checkbox"/>',
408
+ 'name' => esc_html__('Role Name', 'capsman-enhanced'),
409
+ 'count' => esc_html__('Users', 'capsman-enhanced'),
410
+ 'capabilities' => esc_html__('Capabilities', 'capsman-enhanced'),
411
+ 'editor_features' => esc_html__('Editor Features', 'capsman-enhanced'),
412
+ 'admin_features' => esc_html__('Admin Features', 'capsman-enhanced'),
413
+ 'admin_menus' => esc_html__('Admin Menus', 'capsman-enhanced'),
414
+ 'nav_menus' => esc_html__('Nav Menus', 'capsman-enhanced'),
415
+ ];
416
+ }
417
+ );
418
+ }
419
+ }
420
+
421
+ function handleRolesAjax() {
422
+ require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
423
+
424
+ if (!class_exists('PP_Capabilities_Roles')) {
425
+ require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
426
+ }
427
+
428
+ $roles = pp_capabilities_roles()->run();
429
+ }
430
+
431
+ /**
432
+ * Manages roles
433
+ *
434
+ * @hook add_management_page
435
+ * @return void
436
+ */
437
+ public function ManageRoles ()
438
+ {
439
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
440
+ // TODO: Implement exceptions.
441
+ wp_die('<strong>' . esc_html__('You do not have permission to manage roles.', 'capsman-enhanced') . '</strong>');
442
+ }
443
+
444
+ require_once (dirname(CME_FILE) . '/includes/roles/roles-functions.php');
445
+
446
+ if (!class_exists('PP_Capabilities_Roles')) {
447
+ require_once (dirname(CME_FILE) . '/includes/roles/class/class-pp-roles.php');
448
+ }
449
+
450
+ $roles = pp_capabilities_roles()->run();
451
+
452
+ require_once ( dirname(CME_FILE) . '/includes/roles/roles.php' );
453
+ }
454
+
455
+
456
+ /**
457
+ * Manages Editor Features
458
+ *
459
+ * @return void
460
+ */
461
+ public function ManageEditorFeatures() {
462
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
463
+ // TODO: Implement exceptions.
464
+ wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capabilities-pro') . '</strong>');
465
+ }
466
+
467
+ $this->generateNames();
468
+ $roles = array_keys($this->roles);
469
+
470
+ if (!isset($this->current)) {
471
+ if (empty($_POST) && !empty($_REQUEST['role'])) {
472
+ $this->set_current_role(sanitize_key($_REQUEST['role']));
473
+ }
474
+ }
475
+
476
+ if (!isset($this->current) || !get_role($this->current)) {
477
+ $this->current = get_option('default_role');
478
+ }
479
+
480
+ if (!in_array($this->current, $roles)) {
481
+ $this->current = array_shift($roles);
482
+ }
483
+
484
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-editor-features-role']) && !empty($_REQUEST['_wpnonce'])) {
485
+ if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-editor-features')) {
486
+ wp_die('<strong>' . esc_html__('You do not have permission to manage editor features.', 'capabilities-pro') . '</strong>');
487
+ } else {
488
+ $this->set_current_role(sanitize_key($_POST['ppc-editor-features-role']));
489
+
490
+ $classic_editor = pp_capabilities_is_classic_editor_available();
491
+
492
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
493
+
494
+ $active_tab = isset($_POST['pp_caps_tab']) ? sanitize_key($_POST['pp_caps_tab']) : 'post';
495
+
496
+ foreach ($def_post_types as $post_type) {
497
+ if ($classic_editor) {
498
+
499
+ if (isset($_POST['editor-features-all-submit'])){
500
+ $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$active_tab}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_classic_{$active_tab}"]) : [];
501
+ } else {
502
+ $posted_settings = (isset($_POST["capsman_feature_restrict_classic_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_classic_{$post_type}"]) : [];
503
+ }
504
+
505
+ $post_features_option = get_option("capsman_feature_restrict_classic_{$post_type}", []);
506
+ $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
507
+ update_option("capsman_feature_restrict_classic_{$post_type}", $post_features_option, false);
508
+ }
509
+
510
+ if (isset($_POST['editor-features-all-submit'])){
511
+ $posted_settings = (isset($_POST["capsman_feature_restrict_{$active_tab}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_{$active_tab}"]) : [];
512
+ }else {
513
+ $posted_settings = (isset($_POST["capsman_feature_restrict_{$post_type}"])) ? array_map('sanitize_text_field', $_POST["capsman_feature_restrict_{$post_type}"]) : [];
514
+ }
515
+
516
+ $post_features_option = get_option("capsman_feature_restrict_{$post_type}", []);
517
+ $post_features_option[sanitize_key($_POST['ppc-editor-features-role'])] = $posted_settings;
518
+ update_option("capsman_feature_restrict_{$post_type}", $post_features_option, false);
519
+ }
520
+
521
+ ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
522
+ }
523
+ }
524
+
525
+ do_action('pp_capabilities_editor_features');
526
+ include(dirname(CME_FILE) . '/includes/features/editor-features.php');
527
+ }
528
+
529
+ /**
530
+ * Manages Admin Features
531
+ *
532
+ * @return void
533
+ */
534
+ public function ManageAdminFeatures() {
535
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
536
+ // TODO: Implement exceptions.
537
+ wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capabilities-pro') . '</strong>');
538
+ }
539
+
540
+ $this->generateNames();
541
+ $roles = array_keys($this->roles);
542
+
543
+ if (!isset($this->current)) {
544
+ if (empty($_POST) && !empty($_REQUEST['role'])) {
545
+ $this->set_current_role(sanitize_key($_REQUEST['role']));
546
+ }
547
+ }
548
+
549
+ if (!isset($this->current) || !get_role($this->current)) {
550
+ $this->current = get_option('default_role');
551
+ }
552
+
553
+ if (!in_array($this->current, $roles)) {
554
+ $this->current = array_shift($roles);
555
+ }
556
+
557
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && isset($_POST['ppc-admin-features-role']) && !empty($_REQUEST['_wpnonce'])) {
558
+ if (!wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'pp-capabilities-admin-features')) {
559
+ wp_die('<strong>' . esc_html__('You do not have permission to manage admin features.', 'capabilities-pro') . '</strong>');
560
+ } else {
561
+ $features_role = sanitize_key($_POST['ppc-admin-features-role']);
562
+
563
+ $this->set_current_role($features_role);
564
+
565
+ $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
566
+ $disabled_admin_items[$features_role] = isset($_POST['capsman_disabled_admin_features']) ? array_map('sanitize_text_field', $_POST['capsman_disabled_admin_features']) : '';
567
+
568
+ update_option('capsman_disabled_admin_features', $disabled_admin_items, false);
569
+
570
+ //set reload option for instant reflection if user is updating own role
571
+ if (in_array($features_role, wp_get_current_user()->roles)){
572
+ $ppc_page_reload = '1';
573
+ }
574
+
575
+ ak_admin_notify(__('Settings updated.', 'capabilities-pro'));
576
+ }
577
+ }
578
+
579
+ include(dirname(CME_FILE) . '/includes/features/admin-features.php');
580
+ }
581
+
582
+ /**
583
+ * Sets the 'manage_capabilities' cap to the administrator role.
584
+ *
585
+ * @return void
586
+ */
587
+ public function setAdminCapability ()
588
+ {
589
+ if ($admin = get_role('administrator')) {
590
+ $admin->add_cap('manage_capabilities');
591
+ }
592
+ }
593
+
594
+ /**
595
+ * Filters roles that can be shown in roles list.
596
+ * This is mainly used to prevent an user admin to create other users with
597
+ * higher capabilities.
598
+ *
599
+ * @hook 'editable_roles' filter.
600
+ *
601
+ * @param $roles List of roles to check.
602
+ * @return array Restircted roles list
603
+ */
604
+ function filterEditRoles ( $roles )
605
+ {
606
+ global $current_user;
607
+
608
+ if (function_exists('wp_get_current_user') || defined('PP_CAPABILITIES_ROLES_FILTER_EARLY_EXECUTION')) { // Avoid downstream fatal error from premature current_user_can() call if get_editable_roles() is called too early
609
+ $this->generateNames();
610
+ $valid = array_keys($this->roles);
611
+
612
+ foreach ( $roles as $role => $caps ) {
613
+ if ( ! in_array($role, $valid) ) {
614
+ unset($roles[$role]);
615
+ }
616
+ }
617
+ }
618
+
619
+ return $roles;
620
+ }
621
+
622
+ /**
623
+ * Checks if a user can be edited or not by current administrator.
624
+ * Returns array('do_not_allow') if user cannot be edited.
625
+ *
626
+ * @hook 'map_meta_cap' filter
627
+ *
628
+ * @param array $caps Current user capabilities
629
+ * @param string $cap Capability to check
630
+ * @param int $user_id Current user ID
631
+ * @param array $args For our purpose, we receive edited user id at $args[0]
632
+ * @return array Allowed capabilities.
633
+ */
634
+ function filterUserEdit ( $caps, $cap, $user_id, $args )
635
+ {
636
+ if ( ! in_array( $cap, array( 'edit_user', 'delete_user', 'promote_user', 'remove_user' ) ) || ( ! isset($args[0]) ) || $user_id == (int) $args[0] ) {
637
+ return $caps;
638
+ }
639
+
640
+ $user = new WP_User( (int) $args[0] );
641
+
642
+ $this->generateNames();
643
+
644
+ if ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) {
645
+ $valid = array_keys($this->roles);
646
+
647
+ foreach ( $user->roles as $role ) {
648
+ if ( ! in_array($role, $valid) ) {
649
+ $caps = array('do_not_allow');
650
+ break;
651
+ }
652
+ }
653
+ } else {
654
+ global $wp_roles;
655
+
656
+ foreach ( $user->roles as $role ) {
657
+ $r = get_role( $role );
658
+ $level = ak_caps2level($r->capabilities);
659
+
660
+ if ( ( ! $level ) && ( 'administrator' == $role ) )
661
+ $level = 10;
662
+
663
+ if ( $level > $this->max_level ) {
664
+ $caps = array('do_not_allow');
665
+ break;
666
+ }
667
+ }
668
+
669
+ }
670
+
671
+ return $caps;
672
+ }
673
+
674
+ function processRoleUpdate() {
675
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['SaveRole']) || ! empty($_REQUEST['AddCap']) ) ) {
676
+ check_admin_referer('capsman-general-manager');
677
+
678
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
679
+ // TODO: Implement exceptions.
680
+ wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
681
+ }
682
+
683
+ if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
684
+ $role = get_role(sanitize_key($_REQUEST['current']));
685
+ $current_level = ($role) ? ak_caps2level($role->capabilities) : 0;
686
+
687
+ $this->processAdminGeneral();
688
+
689
+ $set_level = (isset($_POST['level'])) ? (int) $_POST['level'] : 0;
690
+
691
+ if ($set_level != $current_level) {
692
+ global $wp_roles, $wp_version;
693
+
694
+ if ( version_compare($wp_version, '4.9', '>=') ) {
695
+ $wp_roles->for_site();
696
+ } else {
697
+ $wp_roles->reinit();
698
+ }
699
+
700
+ foreach( get_users(array('role' => sanitize_key($_REQUEST['current']), 'fields' => 'ID')) as $ID ) {
701
+ $user = new WP_User($ID);
702
+ $user->get_role_caps();
703
+ $user->update_user_level_from_caps();
704
+ }
705
+ }
706
+ }
707
+ }
708
+
709
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD']) && ( ! empty($_REQUEST['RenameRole']) ) ) {
710
+ check_admin_referer('capsman-general-manager');
711
+
712
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
713
+ // TODO: Implement exceptions.
714
+ wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
715
+ }
716
+
717
+ if ( ! empty($_REQUEST['current']) ) { // don't process role update unless form variable is received
718
+ $this->processAdminGeneral();
719
+ }
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Manages global settings admin.
725
+ *
726
+ * @hook add_submenu_page
727
+ * @return void
728
+ */
729
+ function generalManager () {
730
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('manage_capabilities')) {
731
+ // TODO: Implement exceptions.
732
+ wp_die('<strong>' . esc_html__('You do not have permission to manage capabilities.', 'capsman-enhanced') . '</strong>');
733
+ }
734
+
735
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
736
+ if ( empty($_REQUEST['SaveRole']) && empty($_REQUEST['AddCap']) && empty($_REQUEST['RenameRole']) ) {
737
+ check_admin_referer('capsman-general-manager');
738
+ $this->processAdminGeneral();
739
+ } elseif ( ! empty($_REQUEST['SaveRole']) ) {
740
+ ak_admin_notify( $this->message ); // moved update operation to earlier action to avoid UI refresh issues. But outputting notification there breaks styling.
741
+ } elseif ( ! empty($_REQUEST['AddCap']) ) {
742
+ ak_admin_notify( $this->message );
743
+ }
744
+ } else {
745
+ if (!empty($_REQUEST['added'])) {
746
+ ak_admin_notify(__('New capability added to role.', 'capsman-enhanced'));
747
+ }
748
+ }
749
+
750
+ $this->generateNames();
751
+ $roles = array_keys($this->roles);
752
+
753
+ if ( ! isset($this->current) ) { // By default, we manage the default role
754
+ if (empty($_POST) && !empty($_REQUEST['role'])) {
755
+ $role = sanitize_key($_REQUEST['role']);
756
+
757
+ if (!pp_capabilities_is_editable_role($role)) {
758
+ wp_die(esc_html__('The selected role is not editable.', 'capsman-enhanced'));
759
+ }
760
+
761
+ $this->set_current_role($role);
762
+ }
763
+ }
764
+
765
+ if (!isset($this->current) || !get_role($this->current)) {
766
+ $this->current = $this->get_last_role();
767
+ }
768
+
769
+ if ( ! in_array($this->current, $roles) ) { // Current role has been deleted.
770
+ $this->current = array_shift($roles);
771
+ }
772
+
773
+ include ( dirname(CME_FILE) . '/includes/admin.php' );
774
+ }
775
+
776
+ /**
777
+ * Processes and saves the changes in the general capabilities form.
778
+ *
779
+ * @return void
780
+ */
781
+ private function processAdminGeneral ()
782
+ {
783
+ check_admin_referer('capsman-general-manager');
784
+
785
+ if (! isset($_POST['action']) || 'update' != $_POST['action'] ) {
786
+ // TODO: Implement exceptions. This must be a fatal error.
787
+ ak_admin_error(__('Bad form Received', 'capsman-enhanced'));
788
+ return;
789
+ }
790
+
791
+ // Select a new role.
792
+ if ( ! empty($post['LoadRole']) && !empty($_POST['role']) ) {
793
+ $this->set_current_role(sanitize_key($_POST['role']));
794
+ } elseif (!empty($_POST['current'])) {
795
+ $this->set_current_role(sanitize_key($_POST['current']));
796
+
797
+ require_once( dirname(__FILE__).'/handler.php' );
798
+ $capsman_modify = new CapsmanHandler( $this );
799
+ $capsman_modify->processAdminGeneral();
800
+ }
801
+ }
802
+
803
+ /**
804
+ * Callback function to create names.
805
+ * Replaces underscores by spaces and uppercases the first letter.
806
+ *
807
+ * @access private
808
+ * @param string $cap Capability name.
809
+ * @return string The generated name.
810
+ */
811
+ function _capNamesCB ( $cap )
812
+ {
813
+ $cap = str_replace('_', ' ', $cap);
814
+
815
+ return $cap;
816
+ }
817
+
818
+ /**
819
+ * Generates an array with the system capability names.
820
+ * The key is the capability and the value the created screen name.
821
+ *
822
+ * @uses self::_capNamesCB()
823
+ * @return void
824
+ */
825
+ function generateSysNames ()
826
+ {
827
+ $this->max_level = 10;
828
+ $this->roles = ak_get_roles(true);
829
+ $caps = array();
830
+
831
+ foreach ( array_keys($this->roles) as $role ) {
832
+ $role_caps = get_role($role);
833
+ $caps = array_merge( $caps, (array) $role_caps->capabilities ); // user reported PHP 5.3.3 error without array cast
834
+ }
835
+
836
+ $keys = array_keys($caps);
837
+ $names = array_map(array($this, '_capNamesCB'), $keys);
838
+ $this->capabilities = array_combine($keys, $names);
839
+
840
+ asort($this->capabilities);
841
+ }
842
+
843
+ /**
844
+ * Generates an array with the user capability names.
845
+ * If user has 'administrator' role, system roles are generated.
846
+ * The key is the capability and the value the created screen name.
847
+ * A user cannot manage more capabilities that has himself (Except for administrators).
848
+ *
849
+ * @uses self::_capNamesCB()
850
+ * @return void
851
+ */
852
+ function generateNames ()
853
+ {
854
+ if ( current_user_can('administrator') || ( is_multisite() && is_super_admin() ) ) {
855
+ $this->generateSysNames();
856
+ } else {
857
+ global $user_ID;
858
+ $user = new WP_User($user_ID);
859
+ $this->max_level = ak_caps2level($user->allcaps);
860
+
861
+ $keys = array_keys($user->allcaps);
862
+ $names = array_map(array($this, '_capNamesCB'), $keys);
863
+
864
+ $this->capabilities = ( $keys ) ? array_combine($keys, $names) : array();
865
+
866
+ $roles = ak_get_roles(true);
867
+ unset($roles['administrator']);
868
+
869
+ if ( ( defined( 'CME_LEGACY_USER_EDIT_FILTER' ) && CME_LEGACY_USER_EDIT_FILTER ) || ( ! empty( $_REQUEST['page'] ) && 'pp-capabilities' == $_REQUEST['page'] ) ) {
870
+ foreach ( $user->roles as $role ) { // Unset the roles from capability list.
871
+ unset ( $this->capabilities[$role] );
872
+ unset ( $roles[$role]); // User cannot manage his roles.
873
+ }
874
+ }
875
+
876
+ asort($this->capabilities);
877
+
878
+ foreach ( array_keys($roles) as $role ) {
879
+ $r = get_role($role);
880
+ $level = ak_caps2level($r->capabilities);
881
+
882
+ if ( $level > $this->max_level ) {
883
+ unset($roles[$role]);
884
+ }
885
+ }
886
+
887
+ $this->roles = $roles;
888
+ }
889
+ }
890
+
891
+ /**
892
+ * Manages backup, restore and resset roles and capabilities
893
+ *
894
+ * @hook add_management_page
895
+ * @return void
896
+ */
897
+ function backupTool ()
898
+ {
899
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles')) {
900
+ // TODO: Implement exceptions.
901
+ wp_die('<strong>' . esc_html__('You do not have permission to restore roles.', 'capsman-enhanced') . '</strong>');
902
+ }
903
+
904
+ if (!empty($_SERVER['REQUEST_METHOD']) && ('POST' == $_SERVER['REQUEST_METHOD'])) {
905
+ check_admin_referer('pp-capabilities-backup');
906
+ require_once( dirname(__FILE__).'/backup-handler.php' );
907
+ $cme_backup_handler = new Capsman_BackupHandler( $this );
908
+ $cme_backup_handler->processBackupTool();
909
+ }
910
+
911
+ if ( isset($_GET['action']) && 'reset-defaults' == $_GET['action']) {
912
+ check_admin_referer('capsman-reset-defaults');
913
+ require_once( dirname(__FILE__).'/backup-handler.php' );
914
+ $cme_backup_handler = new Capsman_BackupHandler( $this );
915
+ $cme_backup_handler->backupToolReset();
916
+ }
917
+
918
+ include ( dirname(CME_FILE) . '/includes/backup.php' );
919
+ }
920
+
921
+
922
+ /**
923
+ * Processes export.
924
+ *
925
+ * This function need to run in admin init
926
+ * to enable clean download.
927
+ *
928
+ * @return void
929
+ */
930
+ function processExport()
931
+ {
932
+ global $wpdb;
933
+
934
+ if ( isset($_POST['export_backup']) && isset($_POST['pp_capabilities_export_section']) && !empty($_POST['pp_capabilities_export_section'])) {
935
+ check_admin_referer('pp-capabilities-backup');
936
+
937
+ if ((!is_multisite() || !is_super_admin()) && !current_user_can('administrator') && !current_user_can('restore_roles')) {
938
+ // TODO: Implement exceptions.
939
+ wp_die('<strong>' . esc_html__('You do not have permission to perform this action.', 'capsman-enhanced') . '</strong>');
940
+ }
941
+
942
+ $export_option = array_map('sanitize_text_field', $_POST['pp_capabilities_export_section']);
943
+ $backup_sections = pp_capabilities_backup_sections();
944
+ $charset = get_option( 'blog_charset' );
945
+ $data = [];
946
+
947
+ //add role
948
+ if(in_array('user_roles', $export_option)){
949
+ $data['user_roles'] = get_option($wpdb->prefix . 'user_roles');
950
+ }
951
+
952
+ //other section
953
+ foreach($backup_sections as $backup_key => $backup_section){
954
+
955
+ if(!in_array($backup_key, $export_option)){
956
+ continue;
957
+ }
958
+ $section_options = $backup_section['options'];
959
+ if(is_array($section_options) && !empty($section_options)){
960
+ foreach($section_options as $section_option){
961
+ $active_backup[] = $backup_section['label'];
962
+ $data[$section_option] = get_option($section_option);
963
+ }
964
+ }
965
+ }
966
+
967
+ // Set the download headers.
968
+ nocache_headers();
969
+ header( 'Content-Type: application/json; charset=' . $charset );
970
+ header( 'Content-Disposition: attachment; filename=capabilities-export-' . current_time('Y-m-d_g-i-s_a') . '.json' );
971
+ header( "Expires: 0" );
972
+
973
+ // Serialize the export data.
974
+ echo serialize( $data );
975
+
976
+ // Start the download.
977
+ die();
978
+
979
+ }
980
+ }
981
+
982
+ function settingsPage() {
983
+ include ( dirname(CME_FILE) . '/includes/settings.php' );
984
+ }
985
+ }
986
+
987
+ function cme_publishpressFooter() {
988
+ ?>
989
+ <footer>
990
+
991
+ <div class="pp-rating">
992
+ <a href="https://wordpress.org/support/plugin/capability-manager-enhanced/reviews/#new-post" target="_blank" rel="noopener noreferrer">
993
+ <?php printf(
994
+ esc_html__('If you like %s, please leave us a %s rating. Thank you!', 'capsman-enhanced'),
995
+ '<strong>PublishPress Capabilities</strong>',
996
+ '<span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span>'
997
+ );
998
+ ?>
999
+ </a>
1000
+ </div>
1001
+
1002
+ <hr>
1003
+ <nav>
1004
+ <ul>
1005
+ <li><a href="https://publishpress.com/capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('About PublishPress Capabilities', 'capsman-enhanced');?>"><?php esc_html_e('About', 'capsman-enhanced');?>
1006
+ </a></li>
1007
+ <li><a href="https://publishpress.com/knowledge-base/how-to-use-capability-manager/" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Capabilites Documentation', 'capsman-enhanced');?>"><?php esc_html_e('Documentation', 'capsman-enhanced');?>
1008
+ </a></li>
1009
+ <li><a href="https://publishpress.com/contact" target="_blank" rel="noopener noreferrer" title="<?php esc_attr_e('Contact the PublishPress team', 'capsman-enhanced');?>"><?php esc_html_e('Contact', 'capsman-enhanced');?>
1010
+ </a></li>
1011
+ <li><a href="https://twitter.com/publishpresscom" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-twitter"></span>
1012
+ </a></li>
1013
+ <li><a href="https://facebook.com/publishpress" target="_blank" rel="noopener noreferrer"><span class="dashicons dashicons-facebook"></span>
1014
+ </a></li>
1015
+ </ul>
1016
+ </nav>
1017
+
1018
+ <div class="pp-pressshack-logo">
1019
+ <a href="https://publishpress.com" target="_blank" rel="noopener noreferrer">
1020
+
1021
+ <img src="<?php echo esc_url_raw(plugins_url('', CME_FILE) . '/common/img/publishpress-logo.png');?>" />
1022
+ </a>
1023
+ </div>
1024
+
1025
+ </footer>
1026
+ <?php
1027
+ }
includes/network.php CHANGED
@@ -1,85 +1,85 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Multisite-related functions / filter handlers
6
- *
7
- */
8
-
9
- add_action( 'wpmu_new_blog', '_cme_new_blog' );
10
- function _cme_new_blog( $new_blog_id ) {
11
- if ( $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) ) {
12
- global $wp_roles, $blog_id;
13
-
14
- $restore_blog_id = $blog_id;
15
-
16
- $main_site_id = (function_exists('get_main_site_id')) ? get_main_site_id() : 1;
17
-
18
- switch_to_blog($main_site_id);
19
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
20
-
21
- $main_site_caps = array();
22
- $role_captions = array();
23
-
24
- $admin_role = $wp_roles->get_role('administrator');
25
- $main_admin_caps = $admin_role->capabilities;
26
-
27
- if ( defined('PRESSPERMIT_ACTIVE') ) {
28
- $main_pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
29
- }
30
-
31
- foreach( $autocreate_roles as $role_name ) {
32
- if ( $role = get_role( $role_name ) ) {
33
- $main_site_caps[$role_name] = $role->capabilities;
34
- $role_captions[$role_name] = $wp_roles->role_names[$role_name];
35
- }
36
- }
37
-
38
- switch_to_blog($new_blog_id);
39
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
40
-
41
- if ( defined('PRESSPERMIT_ACTIVE') ) {
42
- pp_refresh_options();
43
- $blog_pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
44
- }
45
-
46
- foreach( $main_site_caps as $role_name => $caps ) {
47
- if ( $blog_role = $wp_roles->get_role( $role_name ) ) {
48
- $stored_role_caps = ( ! empty($blog_role->capabilities) && is_array($blog_role->capabilities) ) ? array_intersect( $blog_role->capabilities, array(true, 1) ) : array();
49
-
50
- // Find caps to add and remove
51
- $add_caps = array_diff_key($caps, $stored_role_caps);
52
- $del_caps = array_intersect_key( array_diff_key($stored_role_caps, $caps), $main_admin_caps ); // don't mess with caps that are totally unused on main site
53
-
54
- // Add new capabilities to role
55
- foreach ( $add_caps as $cap => $grant )
56
- $blog_role->add_cap($cap);
57
-
58
- // Remove capabilities from role
59
- foreach ( $del_caps as $cap => $grant)
60
- $blog_role->remove_cap($cap);
61
- } else {
62
- $wp_roles->add_role( $role_name, $role_captions[$role_name], $caps );
63
- }
64
-
65
- if ( defined('PRESSPERMIT_ACTIVE') ) {
66
- if ( in_array( $role_name, $main_pp_only ) ) {
67
- _cme_pp_default_pattern_role( $role_name );
68
- $blog_pp_only []= $role_name;
69
- } else
70
- array_diff( $blog_pp_only, array( $role_name ) );
71
- }
72
- }
73
-
74
- if ( defined('PRESSPERMIT_ACTIVE') ) {
75
- pp_capabilities_update_permissions_option('supplemental_role_defs', $blog_pp_only);
76
- }
77
-
78
- restore_current_blog();
79
- ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
80
-
81
- if ( defined('PRESSPERMIT_ACTIVE') )
82
- pp_refresh_options();
83
- }
84
- }
85
-
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Multisite-related functions / filter handlers
6
+ *
7
+ */
8
+
9
+ add_action( 'wpmu_new_blog', '_cme_new_blog' );
10
+ function _cme_new_blog( $new_blog_id ) {
11
+ if ( $autocreate_roles = get_site_option( 'cme_autocreate_roles' ) ) {
12
+ global $wp_roles, $blog_id;
13
+
14
+ $restore_blog_id = $blog_id;
15
+
16
+ $main_site_id = (function_exists('get_main_site_id')) ? get_main_site_id() : 1;
17
+
18
+ switch_to_blog($main_site_id);
19
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
20
+
21
+ $main_site_caps = array();
22
+ $role_captions = array();
23
+
24
+ $admin_role = $wp_roles->get_role('administrator');
25
+ $main_admin_caps = $admin_role->capabilities;
26
+
27
+ if ( defined('PRESSPERMIT_ACTIVE') ) {
28
+ $main_pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
29
+ }
30
+
31
+ foreach( $autocreate_roles as $role_name ) {
32
+ if ( $role = get_role( $role_name ) ) {
33
+ $main_site_caps[$role_name] = $role->capabilities;
34
+ $role_captions[$role_name] = $wp_roles->role_names[$role_name];
35
+ }
36
+ }
37
+
38
+ switch_to_blog($new_blog_id);
39
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
40
+
41
+ if ( defined('PRESSPERMIT_ACTIVE') ) {
42
+ pp_refresh_options();
43
+ $blog_pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
44
+ }
45
+
46
+ foreach( $main_site_caps as $role_name => $caps ) {
47
+ if ( $blog_role = $wp_roles->get_role( $role_name ) ) {
48
+ $stored_role_caps = ( ! empty($blog_role->capabilities) && is_array($blog_role->capabilities) ) ? array_intersect( $blog_role->capabilities, array(true, 1) ) : array();
49
+
50
+ // Find caps to add and remove
51
+ $add_caps = array_diff_key($caps, $stored_role_caps);
52
+ $del_caps = array_intersect_key( array_diff_key($stored_role_caps, $caps), $main_admin_caps ); // don't mess with caps that are totally unused on main site
53
+
54
+ // Add new capabilities to role
55
+ foreach ( $add_caps as $cap => $grant )
56
+ $blog_role->add_cap($cap);
57
+
58
+ // Remove capabilities from role
59
+ foreach ( $del_caps as $cap => $grant)
60
+ $blog_role->remove_cap($cap);
61
+ } else {
62
+ $wp_roles->add_role( $role_name, $role_captions[$role_name], $caps );
63
+ }
64
+
65
+ if ( defined('PRESSPERMIT_ACTIVE') ) {
66
+ if ( in_array( $role_name, $main_pp_only ) ) {
67
+ _cme_pp_default_pattern_role( $role_name );
68
+ $blog_pp_only []= $role_name;
69
+ } else
70
+ array_diff( $blog_pp_only, array( $role_name ) );
71
+ }
72
+ }
73
+
74
+ if ( defined('PRESSPERMIT_ACTIVE') ) {
75
+ pp_capabilities_update_permissions_option('supplemental_role_defs', $blog_pp_only);
76
+ }
77
+
78
+ restore_current_blog();
79
+ ( method_exists( $wp_roles, 'for_site' ) ) ? $wp_roles->for_site() : $wp_roles->reinit();
80
+
81
+ if ( defined('PRESSPERMIT_ACTIVE') )
82
+ pp_refresh_options();
83
+ }
84
+ }
85
+
includes/pp-handler.php CHANGED
@@ -1,102 +1,102 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Process updates to Type-Specific Types / Taxonomies, Detailed Taxonomies
6
- *
7
- */
8
-
9
- function _cme_update_pp_usage() {
10
- static $updated;
11
- if ( ! empty($updated) ) { return true; }
12
-
13
- check_admin_referer('capsman-general-manager');
14
-
15
- if (!current_user_can( 'manage_capabilities' )) {
16
- return false;
17
- }
18
-
19
- if ( ! empty( $_REQUEST['update_filtered_types']) || ! empty( $_REQUEST['update_filtered_taxonomies']) || ! empty($_REQUEST['update_detailed_taxonomies']) || ! empty( $_REQUEST['SaveRole']) ) {
20
- // update Press Permit "Filtered Post Types". This determines whether type-specific capability definitions are forced
21
- $options = array( 'enabled_post_types', 'enabled_taxonomies', 'detailed_taxonomies' );
22
-
23
- $posted = $_POST;
24
-
25
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
26
-
27
- foreach( $options as $option_basename ) {
28
- if ( ! isset( $posted["{$option_basename}-options"] ) )
29
- continue;
30
-
31
- $unselected = array();
32
- $value = array();
33
-
34
- foreach( $posted["{$option_basename}-options"] as $key ) {
35
- if ( ( 'enabled_taxonomies' == $option_basename ) && ! empty( $posted["detailed_taxonomies-{$key}"] ) && ! empty( $posted['update_detailed_taxonomies']) ) {
36
- // if Detailed is selected, also select Type-Specific
37
- $posted["enabled_taxonomies-{$key}"] = true;
38
- $value[$key] = true;
39
- } elseif ( ( 'detailed_taxonomies' == $option_basename ) && empty( $posted["enabled_taxonomies-{$key}"] ) && ! empty( $posted['update_filtered_taxonomies']) ) {
40
- // if Enabled is deselected, also deselect Type-Specific
41
- $unselected[$key] = true;
42
- } elseif ( empty( $posted["{$option_basename}-$key"] ) ) {
43
- $unselected[$key] = true;
44
- } else {
45
- $value[$key] = true;
46
- }
47
- }
48
-
49
- $option_name = ( 'detailed_taxonomies' == $option_basename ) ? 'cme_' . $option_basename : $pp_prefix . '_' . $option_basename;
50
-
51
- if ( $current = get_option( $option_name ) ) {
52
- if ( $current = array_diff_key( $current, $unselected ) )
53
- $value = array_merge( $current, $value ); // retain setting for any types which were previously enabled for filtering but are currently not registered
54
- }
55
-
56
- $value = array_map('sanitize_key', $value);
57
-
58
- update_option( $option_name, $value );
59
-
60
- if (in_array($option_name, ['presspermit_enabled_post_types', 'pp_enabled_post_types'])) {
61
- // ensure smooth transition if Press Permit Core is deactivated
62
- update_option( 'cme_enabled_post_types', $value );
63
- }
64
-
65
- if (defined('PRESSPERMIT_ACTIVE') && in_array($option_basename, ['enabled_post_types', 'enabled_taxonomies'])) {
66
- pp_capabilities_update_permissions_option($option_basename, $value);
67
- }
68
-
69
- $updated = true;
70
- }
71
-
72
- if ( ! empty( $_REQUEST['update_filtered_types']) ) {
73
- update_option( $pp_prefix . '_define_create_posts_cap', ! empty($_REQUEST['pp_define_create_posts_cap']) );
74
- }
75
- }
76
-
77
- if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
78
- if ( ! empty( $_REQUEST['SaveRole']) ) {
79
- if ( ! empty( $_REQUEST['role'] ) ) {
80
- $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
81
-
82
- $role = sanitize_key($_REQUEST['role']);
83
-
84
- if (empty($_REQUEST['pp_only_role'])) {
85
- $pp_only = array_diff($pp_only, [$role]);
86
- } else {
87
- $pp_only[]= $role;
88
- }
89
-
90
- pp_capabilities_update_permissions_option('supplemental_role_defs', array_unique($pp_only));
91
-
92
- _cme_pp_default_pattern_role($role);
93
- }
94
- }
95
-
96
- if ( $updated ) {
97
- pp_refresh_options();
98
- }
99
- }
100
-
101
- return $updated;
102
- }
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Process updates to Type-Specific Types / Taxonomies, Detailed Taxonomies
6
+ *
7
+ */
8
+
9
+ function _cme_update_pp_usage() {
10
+ static $updated;
11
+ if ( ! empty($updated) ) { return true; }
12
+
13
+ check_admin_referer('capsman-general-manager');
14
+
15
+ if (!current_user_can( 'manage_capabilities' )) {
16
+ return false;
17
+ }
18
+
19
+ if ( ! empty( $_REQUEST['update_filtered_types']) || ! empty( $_REQUEST['update_filtered_taxonomies']) || ! empty($_REQUEST['update_detailed_taxonomies']) || ! empty( $_REQUEST['SaveRole']) ) {
20
+ // update Press Permit "Filtered Post Types". This determines whether type-specific capability definitions are forced
21
+ $options = array( 'enabled_post_types', 'enabled_taxonomies', 'detailed_taxonomies' );
22
+
23
+ $posted = $_POST;
24
+
25
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
26
+
27
+ foreach( $options as $option_basename ) {
28
+ if ( ! isset( $posted["{$option_basename}-options"] ) )
29
+ continue;
30
+
31
+ $unselected = array();
32
+ $value = array();
33
+
34
+ foreach( $posted["{$option_basename}-options"] as $key ) {
35
+ if ( ( 'enabled_taxonomies' == $option_basename ) && ! empty( $posted["detailed_taxonomies-{$key}"] ) && ! empty( $posted['update_detailed_taxonomies']) ) {
36
+ // if Detailed is selected, also select Type-Specific
37
+ $posted["enabled_taxonomies-{$key}"] = true;
38
+ $value[$key] = true;
39
+ } elseif ( ( 'detailed_taxonomies' == $option_basename ) && empty( $posted["enabled_taxonomies-{$key}"] ) && ! empty( $posted['update_filtered_taxonomies']) ) {
40
+ // if Enabled is deselected, also deselect Type-Specific
41
+ $unselected[$key] = true;
42
+ } elseif ( empty( $posted["{$option_basename}-$key"] ) ) {
43
+ $unselected[$key] = true;
44
+ } else {
45
+ $value[$key] = true;
46
+ }
47
+ }
48
+
49
+ $option_name = ( 'detailed_taxonomies' == $option_basename ) ? 'cme_' . $option_basename : $pp_prefix . '_' . $option_basename;
50
+
51
+ if ( $current = get_option( $option_name ) ) {
52
+ if ( $current = array_diff_key( $current, $unselected ) )
53
+ $value = array_merge( $current, $value ); // retain setting for any types which were previously enabled for filtering but are currently not registered
54
+ }
55
+
56
+ $value = array_map('sanitize_key', $value);
57
+
58
+ update_option( $option_name, $value );
59
+
60
+ if (in_array($option_name, ['presspermit_enabled_post_types', 'pp_enabled_post_types'])) {
61
+ // ensure smooth transition if Press Permit Core is deactivated
62
+ update_option( 'cme_enabled_post_types', $value );
63
+ }
64
+
65
+ if (defined('PRESSPERMIT_ACTIVE') && in_array($option_basename, ['enabled_post_types', 'enabled_taxonomies'])) {
66
+ pp_capabilities_update_permissions_option($option_basename, $value);
67
+ }
68
+
69
+ $updated = true;
70
+ }
71
+
72
+ if ( ! empty( $_REQUEST['update_filtered_types']) ) {
73
+ update_option( $pp_prefix . '_define_create_posts_cap', ! empty($_REQUEST['pp_define_create_posts_cap']) );
74
+ }
75
+ }
76
+
77
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
78
+ if ( ! empty( $_REQUEST['SaveRole']) ) {
79
+ if ( ! empty( $_REQUEST['role'] ) ) {
80
+ $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
81
+
82
+ $role = sanitize_key($_REQUEST['role']);
83
+
84
+ if (empty($_REQUEST['pp_only_role'])) {
85
+ $pp_only = array_diff($pp_only, [$role]);
86
+ } else {
87
+ $pp_only[]= $role;
88
+ }
89
+
90
+ pp_capabilities_update_permissions_option('supplemental_role_defs', array_unique($pp_only));
91
+
92
+ _cme_pp_default_pattern_role($role);
93
+ }
94
+ }
95
+
96
+ if ( $updated ) {
97
+ pp_refresh_options();
98
+ }
99
+ }
100
+
101
+ return $updated;
102
+ }
includes/pp-ui.php CHANGED
@@ -1,294 +1,294 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Capabilities UI: PublishPress Permissions integration
6
- *
7
- * This module also contains the Settings UI for Type-Specific Types / Taxonomies, which were previously a front end to PublishPress Permissions
8
- *
9
- */
10
-
11
- class Capsman_PP_UI {
12
- function get_metagroup_caps( $default ) {
13
- global $wpdb;
14
-
15
- if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
16
- $pp_supplemental_roles = $wpdb->get_col(
17
- $wpdb->prepare(
18
- "SELECT role_name FROM $wpdb->ppc_roles AS r INNER JOIN $wpdb->pp_groups AS g ON g.ID = r.agent_id AND r.agent_type = 'pp_group' WHERE g.metagroup_type = 'wp_role' AND g.metagroup_id = %s",
19
- $default
20
- )
21
- );
22
- } else {
23
- $pp_supplemental_roles = $wpdb->get_col(
24
- $wpdb->prepare(
25
- "SELECT role_name FROM $wpdb->pp_roles AS r INNER JOIN $wpdb->pp_groups AS g ON g.ID = r.group_id AND r.group_type = 'pp_group' AND r.scope = 'site' WHERE g.metagroup_type = 'wp_role' AND g.metagroup_id = %s",
26
- $default
27
- )
28
- );
29
- }
30
-
31
- $pp_filtered_types = pp_get_enabled_types('post');
32
- $pp_metagroup_caps = array();
33
- $pp_cap_caster = pp_init_cap_caster();
34
-
35
- foreach( $pp_supplemental_roles as $_role_name ) {
36
- $role_specs = explode( ':', $_role_name );
37
- if ( empty($role_specs[2]) || ! in_array( $role_specs[2], $pp_filtered_types ) )
38
- continue;
39
-
40
- // add all type-specific caps whose base property cap is included in this pattern role
41
- // i.e. If 'edit_posts' is in the pattern role, grant $type_obj->cap->edit_posts
42
- $pp_metagroup_caps = array_merge( $pp_metagroup_caps, array_fill_keys( $pp_cap_caster->get_typecast_caps( $_role_name, 'site' ), true ) );
43
- }
44
-
45
- return $pp_metagroup_caps;
46
- }
47
-
48
- function show_capability_hints( $default ) {
49
- if ( pp_capabilities_get_permissions_option('display_hints') ) {
50
- echo '<ul class="ul-disc publishpress-caps-extra-hints" style="margin-top:10px;display:none">';
51
-
52
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
53
-
54
- if ( defined( 'PPCE_VERSION' ) || ! defined( 'PRESSPERMIT_ACTIVE' ) || in_array( $default, array( 'subscriber', 'contributor', 'author', 'editor' ) ) ) {
55
- echo '<li>';
56
- if ( defined( 'PPCE_VERSION' ) || ! defined( 'PRESSPERMIT_ACTIVE' ) ) {
57
- if ( pp_capabilities_get_permissions_option( 'advanced_options' ) )
58
- $parenthetical = ' (' . sprintf( esc_html__( 'see %1$sRole Usage%2$s: "Pattern Roles"', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) . ')';
59
- else
60
- $parenthetical = ' (' . sprintf( esc_html__( 'activate %1$sAdvanced settings%2$s, see Role Usage', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-settings&pp_tab=advanced") . "'>", '</a>' ). ')';
61
- } else
62
- $parenthetical = '';
63
-
64
- if ( defined( 'PRESSPERMIT_ACTIVE' ) )
65
- printf( esc_html__( '"Posts" capabilities selected here also define type-specific role assignment for Permission Groups%s.', 'capsman-enhanced' ), $parenthetical ) ;
66
- else
67
- printf( esc_html__( '"Posts" capabilities selected here also define type-specific role assignment for Permit Groups%s.', 'capsman-enhanced' ), $parenthetical ) ;
68
-
69
- echo '</li>';
70
- }
71
-
72
- $status_hint = '';
73
- if ( defined( 'PRESSPERMIT_ACTIVE' ) )
74
- if ( defined( 'PPS_VERSION' ) )
75
- $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added here. (See %sPermissions > Post Statuses%s for applicable names). %sSupplemental status-specific roles%s are usually more convenient, though.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-statuses&show_caps=1") . "'>", '</a>', "<a href='" . admin_url("admin.php?page={$pp_prefix}-groups") . "'>", '</a>' ) ;
76
- elseif ( pp_capabilities_get_permissions_option( 'display_extension_hints' ) )
77
- $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added here. Or activate the PP Custom Post Statuses extension to assign status-specific supplemental roles.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) ;
78
-
79
- elseif ( defined( 'PP_VERSION' ) )
80
- $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added to a role here (see Conditions > Status > Capability Mapping for applicable names). However, it is usually more convenient to use Permit Groups to assign a supplemental status-specific role.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) ;
81
-
82
- if ( $status_hint )
83
- echo "<li>" . esc_html($status_hint) . "</li>";
84
-
85
- echo '</ul>';
86
- }
87
- }
88
-
89
- // Note: CME can now impose type-specific capabilities without Press Permit Core active
90
- function pp_types_ui( $defined_types ) {
91
- ?>
92
- <dl>
93
- <dt><?php esc_html_e('Type-Specific Capabilities', 'capsman-enhanced'); ?></dt>
94
- <dd style="text-align:center;">
95
- <?php
96
- echo "<p class='cme-hint'>" . esc_html__( 'Ensure permissions can be controlled separately from other post types.', 'capsman-enhanced' ) . "</p>";
97
-
98
- if ( defined( 'PRESSPERMIT_ACTIVE' ) && pp_capabilities_get_permissions_option( 'display_hints' ) ) :?>
99
- <div class="cme-subtext" style="margin-top:0">
100
- </div>
101
- <?php endif;
102
-
103
- echo "<table style='width:100%'><tr>";
104
-
105
- // bbPress' dynamic role def requires additional code to enforce stored caps
106
- $unfiltered = apply_filters('presspermit_unfiltered_post_types', ['forum','topic','reply','wp_block', 'customize_changeset']);
107
- $unfiltered = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered : apply_filters('pp_unfiltered_post_types', $unfiltered); // maintain legacy filter to support custom code
108
-
109
- $hidden = apply_filters('presspermit_hidden_post_types', []);
110
- $hidden = apply_filters('pp_hidden_post_types', $hidden); // maintain legacy filter to support custom code
111
-
112
- echo '<td style="width:50%">';
113
-
114
- $option_basename = 'enabled_post_types';
115
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
116
-
117
- $enabled = get_option( $pp_prefix . '_' . $option_basename, array( 'post' => true, 'page' => true ) );
118
-
119
- foreach( $defined_types as $key => $type_obj ) {
120
- if ( ! $key )
121
- continue;
122
-
123
- if ( in_array( $key, $unfiltered ) )
124
- continue;
125
-
126
- $key = sanitize_key($key);
127
-
128
- $id = "$option_basename-" . $key;
129
- ?>
130
- <div style="text-align:left">
131
- <?php if ( ! empty( $hidden[$key] ) ) :?>
132
- <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
133
- <input name="<?php echo(esc_attr($option_basename) . "-options[]");?>" type="hidden" value="<?php echo(esc_attr($key))?>" />
134
-
135
- <?php else: ?>
136
- <div class="agp-vspaced_input">
137
- <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($key));?>">
138
- <input name="<?php echo(esc_attr($option_basename) . "-options[]");?>" type="hidden" value="<?php echo(esc_attr($key))?>" />
139
- <input name="<?php echo(esc_attr($id));?>" type="checkbox" id="<?php echo(esc_attr($id));?>" autocomplete="off" value="1" <?php checked('1', ! empty($enabled[$key]) );?> /> <?php echo(esc_html($type_obj->label));?>
140
-
141
- <?php
142
- echo ('</label></div>');
143
-
144
- endif; // displaying checkbox UI
145
-
146
- echo '</div>';
147
- }
148
- echo '</td>';
149
- ?>
150
- </tr>
151
- </table>
152
-
153
- <?php
154
-
155
- $define_create_posts_cap = get_option("{$pp_prefix}_define_create_posts_cap");?>
156
-
157
- <div style="margin-top:10px;margin-bottom:10px">
158
- <label for="pp_define_create_posts_cap">
159
- <input name="pp_define_create_posts_cap" type="checkbox" id="pp_define_create_posts_cap" autocomplete="off" value="1" <?php checked('1', $define_create_posts_cap );?> title="<?php esc_attr_e( 'Make selected post types require a different capability to add new posts.', 'capsman-enhanced');?>" /> <?php esc_html_e('Use create_posts capability');?>
160
- </label>
161
- </div>
162
-
163
- <?php
164
- do_action('pp-capabilities-type-specific-ui');
165
- ?>
166
-
167
- <input type="submit" name="update_filtered_types" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
168
- </dd>
169
- </dl>
170
- <?php
171
- }
172
-
173
- // Note: CME can now impose type-specific capabilities without Press Permit Core active
174
- function pp_taxonomies_ui( $defined_taxonomies ) {
175
- ?>
176
- <dl>
177
- <dt><?php esc_html_e('Taxonomy-Specific Capabilities', 'capsman-enhanced'); ?></dt>
178
- <dd style="text-align:center;">
179
- <?php
180
- echo "<p class='cme-hint'>" . esc_html__( 'Ensure permissions can be controlled separately from other taxonomies.', 'capsman-enhanced' ) . "</p>";
181
-
182
- echo "<table style='width:100%'><tr>";
183
-
184
- $unfiltered = apply_filters( 'pp_unfiltered_taxonomies', array( 'post_status', 'topic-tag' ) ); // avoid confusion with Edit Flow administrative taxonomy
185
- $hidden = apply_filters( 'pp_hidden_taxonomies', array() );
186
-
187
- echo '<td style="width:50%">';
188
-
189
- $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
190
-
191
- $option_basename = 'enabled_taxonomies';
192
- $option_name = $pp_prefix . '_' . $option_basename;
193
-
194
- $enabled = get_option( $option_name, array() );
195
-
196
- foreach( $defined_taxonomies as $taxonomy => $type_obj ) {
197
- if ( ! $taxonomy )
198
- continue;
199
-
200
- if ( in_array( $taxonomy, $unfiltered ) )
201
- continue;
202
-
203
- $taxonomy = sanitize_key($taxonomy);
204
-
205
- $id = "$option_basename-" . $taxonomy;
206
- ?>
207
- <div style="text-align:left">
208
- <?php if ( ! empty( $hidden[$taxonomy] ) ) :?>
209
- <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
210
- <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
211
-
212
- <?php else: ?>
213
-
214
- <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($taxonomy));?>">
215
- <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
216
- <input name="<?php echo(esc_attr($id));?>" type="checkbox" autocomplete="off" id="<?php echo(esc_attr($id));?>" value="1" <?php checked('1', ! empty($enabled[$taxonomy]) );?> /> <?php echo(esc_html($type_obj->label));?>
217
-
218
- <?php
219
- echo ('</label></div>');
220
-
221
- endif; // displaying checkbox UI
222
-
223
- echo '</div>';
224
- }
225
- echo '</td>';
226
-
227
- ?>
228
- </tr>
229
- </table>
230
-
231
- <input type="submit" name="update_filtered_taxonomies" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
232
- </dd>
233
- </dl>
234
-
235
- <dl>
236
- <dt><?php esc_html_e('Detailed Taxonomy Capabilities', 'capsman-enhanced'); ?></dt>
237
- <dd style="text-align:center;">
238
- <?php
239
- echo "<p class='cme-hint'>" . esc_html__( 'Enforce Edit, Delete and Assign capabilities separately from Management capability.', 'capsman-enhanced' ) . "</p>";
240
-
241
- echo "<table style='width:100%'><tr>";
242
-
243
- $unfiltered = apply_filters( 'pp_unfiltered_taxonomies', array( 'post_status', 'topic-tag' ) ); // avoid confusion with Edit Flow administrative taxonomy
244
- $hidden = apply_filters( 'pp_hidden_taxonomies', array() );
245
-
246
- echo '<td style="width:50%">';
247
-
248
- $option_basename = 'detailed_taxonomies';
249
- $option_name = 'cme_' . $option_basename;
250
-
251
- $enabled = get_option( $option_name, array() );
252
-
253
- foreach( $defined_taxonomies as $taxonomy => $type_obj ) {
254
- if ( ! $taxonomy )
255
- continue;
256
-
257
- if ( in_array( $taxonomy, $unfiltered ) )
258
- continue;
259
-
260
- $taxonomy = sanitize_key($taxonomy);
261
-
262
- $id = "$option_basename-" . $taxonomy;
263
- ?>
264
- <div style="text-align:left">
265
- <?php if ( ! empty( $hidden[$taxonomy] ) ) :?>
266
- <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
267
- <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
268
-
269
- <?php else: ?>
270
- <div class="agp-vspaced_input">
271
- <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($taxonomy));?>">
272
- <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
273
- <input name="<?php echo(esc_attr($id));?>" type="checkbox" autocomplete="off" id="<?php echo(esc_attr($id));?>" value="1" <?php checked('1', ! empty($enabled[$taxonomy]) );?> /> <?php echo(esc_html($type_obj->label));?>
274
-
275
- <?php
276
- echo ('</label></div>');
277
-
278
- endif; // displaying checkbox UI
279
-
280
- echo '</div>';
281
- }
282
- echo '</td>';
283
-
284
- ?>
285
- </tr>
286
- </table>
287
-
288
- <input type="submit" name="update_detailed_taxonomies" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
289
- </dd>
290
- </dl>
291
- <?php
292
- }
293
- }
294
-
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Capabilities UI: PublishPress Permissions integration
6
+ *
7
+ * This module also contains the Settings UI for Type-Specific Types / Taxonomies, which were previously a front end to PublishPress Permissions
8
+ *
9
+ */
10
+
11
+ class Capsman_PP_UI {
12
+ function get_metagroup_caps( $default ) {
13
+ global $wpdb;
14
+
15
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) ) {
16
+ $pp_supplemental_roles = $wpdb->get_col(
17
+ $wpdb->prepare(
18
+ "SELECT role_name FROM $wpdb->ppc_roles AS r INNER JOIN $wpdb->pp_groups AS g ON g.ID = r.agent_id AND r.agent_type = 'pp_group' WHERE g.metagroup_type = 'wp_role' AND g.metagroup_id = %s",
19
+ $default
20
+ )
21
+ );
22
+ } else {
23
+ $pp_supplemental_roles = $wpdb->get_col(
24
+ $wpdb->prepare(
25
+ "SELECT role_name FROM $wpdb->pp_roles AS r INNER JOIN $wpdb->pp_groups AS g ON g.ID = r.group_id AND r.group_type = 'pp_group' AND r.scope = 'site' WHERE g.metagroup_type = 'wp_role' AND g.metagroup_id = %s",
26
+ $default
27
+ )
28
+ );
29
+ }
30
+
31
+ $pp_filtered_types = pp_get_enabled_types('post');
32
+ $pp_metagroup_caps = array();
33
+ $pp_cap_caster = pp_init_cap_caster();
34
+
35
+ foreach( $pp_supplemental_roles as $_role_name ) {
36
+ $role_specs = explode( ':', $_role_name );
37
+ if ( empty($role_specs[2]) || ! in_array( $role_specs[2], $pp_filtered_types ) )
38
+ continue;
39
+
40
+ // add all type-specific caps whose base property cap is included in this pattern role
41
+ // i.e. If 'edit_posts' is in the pattern role, grant $type_obj->cap->edit_posts
42
+ $pp_metagroup_caps = array_merge( $pp_metagroup_caps, array_fill_keys( $pp_cap_caster->get_typecast_caps( $_role_name, 'site' ), true ) );
43
+ }
44
+
45
+ return $pp_metagroup_caps;
46
+ }
47
+
48
+ function show_capability_hints( $default ) {
49
+ if ( pp_capabilities_get_permissions_option('display_hints') ) {
50
+ echo '<ul class="ul-disc publishpress-caps-extra-hints" style="margin-top:10px;display:none">';
51
+
52
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
53
+
54
+ if ( defined( 'PPCE_VERSION' ) || ! defined( 'PRESSPERMIT_ACTIVE' ) || in_array( $default, array( 'subscriber', 'contributor', 'author', 'editor' ) ) ) {
55
+ echo '<li>';
56
+ if ( defined( 'PPCE_VERSION' ) || ! defined( 'PRESSPERMIT_ACTIVE' ) ) {
57
+ if ( pp_capabilities_get_permissions_option( 'advanced_options' ) )
58
+ $parenthetical = ' (' . sprintf( esc_html__( 'see %1$sRole Usage%2$s: "Pattern Roles"', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) . ')';
59
+ else
60
+ $parenthetical = ' (' . sprintf( esc_html__( 'activate %1$sAdvanced settings%2$s, see Role Usage', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-settings&pp_tab=advanced") . "'>", '</a>' ). ')';
61
+ } else
62
+ $parenthetical = '';
63
+
64
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) )
65
+ printf( esc_html__( '"Posts" capabilities selected here also define type-specific role assignment for Permission Groups%s.', 'capsman-enhanced' ), $parenthetical ) ;
66
+ else
67
+ printf( esc_html__( '"Posts" capabilities selected here also define type-specific role assignment for Permit Groups%s.', 'capsman-enhanced' ), $parenthetical ) ;
68
+
69
+ echo '</li>';
70
+ }
71
+
72
+ $status_hint = '';
73
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) )
74
+ if ( defined( 'PPS_VERSION' ) )
75
+ $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added here. (See %sPermissions > Post Statuses%s for applicable names). %sSupplemental status-specific roles%s are usually more convenient, though.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-statuses&show_caps=1") . "'>", '</a>', "<a href='" . admin_url("admin.php?page={$pp_prefix}-groups") . "'>", '</a>' ) ;
76
+ elseif ( pp_capabilities_get_permissions_option( 'display_extension_hints' ) )
77
+ $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added here. Or activate the PP Custom Post Statuses extension to assign status-specific supplemental roles.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) ;
78
+
79
+ elseif ( defined( 'PP_VERSION' ) )
80
+ $status_hint = sprintf( __( 'Capabilities for custom statuses can be manually added to a role here (see Conditions > Status > Capability Mapping for applicable names). However, it is usually more convenient to use Permit Groups to assign a supplemental status-specific role.', 'capsman-enhanced' ), "<a href='" . admin_url("admin.php?page={$pp_prefix}-role-usage") . "'>", '</a>' ) ;
81
+
82
+ if ( $status_hint )
83
+ echo "<li>" . esc_html($status_hint) . "</li>";
84
+
85
+ echo '</ul>';
86
+ }
87
+ }
88
+
89
+ // Note: CME can now impose type-specific capabilities without Press Permit Core active
90
+ function pp_types_ui( $defined_types ) {
91
+ ?>
92
+ <dl>
93
+ <dt><?php esc_html_e('Type-Specific Capabilities', 'capsman-enhanced'); ?></dt>
94
+ <dd style="text-align:center;">
95
+ <?php
96
+ echo "<p class='cme-hint'>" . esc_html__( 'Ensure permissions can be controlled separately from other post types.', 'capsman-enhanced' ) . "</p>";
97
+
98
+ if ( defined( 'PRESSPERMIT_ACTIVE' ) && pp_capabilities_get_permissions_option( 'display_hints' ) ) :?>
99
+ <div class="cme-subtext" style="margin-top:0">
100
+ </div>
101
+ <?php endif;
102
+
103
+ echo "<table style='width:100%'><tr>";
104
+
105
+ // bbPress' dynamic role def requires additional code to enforce stored caps
106
+ $unfiltered = apply_filters('presspermit_unfiltered_post_types', ['forum','topic','reply','wp_block', 'customize_changeset']);
107
+ $unfiltered = (defined('PP_CAPABILITIES_NO_LEGACY_FILTERS')) ? $unfiltered : apply_filters('pp_unfiltered_post_types', $unfiltered); // maintain legacy filter to support custom code
108
+
109
+ $hidden = apply_filters('presspermit_hidden_post_types', []);
110
+ $hidden = apply_filters('pp_hidden_post_types', $hidden); // maintain legacy filter to support custom code
111
+
112
+ echo '<td style="width:50%">';
113
+
114
+ $option_basename = 'enabled_post_types';
115
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
116
+
117
+ $enabled = get_option( $pp_prefix . '_' . $option_basename, array( 'post' => true, 'page' => true ) );
118
+
119
+ foreach( $defined_types as $key => $type_obj ) {
120
+ if ( ! $key )
121
+ continue;
122
+
123
+ if ( in_array( $key, $unfiltered ) )
124
+ continue;
125
+
126
+ $key = sanitize_key($key);
127
+
128
+ $id = "$option_basename-" . $key;
129
+ ?>
130
+ <div style="text-align:left">
131
+ <?php if ( ! empty( $hidden[$key] ) ) :?>
132
+ <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
133
+ <input name="<?php echo(esc_attr($option_basename) . "-options[]");?>" type="hidden" value="<?php echo(esc_attr($key))?>" />
134
+
135
+ <?php else: ?>
136
+ <div class="agp-vspaced_input">
137
+ <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($key));?>">
138
+ <input name="<?php echo(esc_attr($option_basename) . "-options[]");?>" type="hidden" value="<?php echo(esc_attr($key))?>" />
139
+ <input name="<?php echo(esc_attr($id));?>" type="checkbox" id="<?php echo(esc_attr($id));?>" autocomplete="off" value="1" <?php checked('1', ! empty($enabled[$key]) );?> /> <?php echo(esc_html($type_obj->label));?>
140
+
141
+ <?php
142
+ echo ('</label></div>');
143
+
144
+ endif; // displaying checkbox UI
145
+
146
+ echo '</div>';
147
+ }
148
+ echo '</td>';
149
+ ?>
150
+ </tr>
151
+ </table>
152
+
153
+ <?php
154
+
155
+ $define_create_posts_cap = get_option("{$pp_prefix}_define_create_posts_cap");?>
156
+
157
+ <div style="margin-top:10px;margin-bottom:10px">
158
+ <label for="pp_define_create_posts_cap">
159
+ <input name="pp_define_create_posts_cap" type="checkbox" id="pp_define_create_posts_cap" autocomplete="off" value="1" <?php checked('1', $define_create_posts_cap );?> title="<?php esc_attr_e( 'Make selected post types require a different capability to add new posts.', 'capsman-enhanced');?>" /> <?php esc_html_e('Use create_posts capability');?>
160
+ </label>
161
+ </div>
162
+
163
+ <?php
164
+ do_action('pp-capabilities-type-specific-ui');
165
+ ?>
166
+
167
+ <input type="submit" name="update_filtered_types" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
168
+ </dd>
169
+ </dl>
170
+ <?php
171
+ }
172
+
173
+ // Note: CME can now impose type-specific capabilities without Press Permit Core active
174
+ function pp_taxonomies_ui( $defined_taxonomies ) {
175
+ ?>
176
+ <dl>
177
+ <dt><?php esc_html_e('Taxonomy-Specific Capabilities', 'capsman-enhanced'); ?></dt>
178
+ <dd style="text-align:center;">
179
+ <?php
180
+ echo "<p class='cme-hint'>" . esc_html__( 'Ensure permissions can be controlled separately from other taxonomies.', 'capsman-enhanced' ) . "</p>";
181
+
182
+ echo "<table style='width:100%'><tr>";
183
+
184
+ $unfiltered = apply_filters( 'pp_unfiltered_taxonomies', array( 'post_status', 'topic-tag' ) ); // avoid confusion with Edit Flow administrative taxonomy
185
+ $hidden = apply_filters( 'pp_hidden_taxonomies', array() );
186
+
187
+ echo '<td style="width:50%">';
188
+
189
+ $pp_prefix = (defined('PPC_VERSION') && !defined('PRESSPERMIT_VERSION')) ? 'pp' : 'presspermit';
190
+
191
+ $option_basename = 'enabled_taxonomies';
192
+ $option_name = $pp_prefix . '_' . $option_basename;
193
+
194
+ $enabled = get_option( $option_name, array() );
195
+
196
+ foreach( $defined_taxonomies as $taxonomy => $type_obj ) {
197
+ if ( ! $taxonomy )
198
+ continue;
199
+
200
+ if ( in_array( $taxonomy, $unfiltered ) )
201
+ continue;
202
+
203
+ $taxonomy = sanitize_key($taxonomy);
204
+
205
+ $id = "$option_basename-" . $taxonomy;
206
+ ?>
207
+ <div style="text-align:left">
208
+ <?php if ( ! empty( $hidden[$taxonomy] ) ) :?>
209
+ <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
210
+ <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
211
+
212
+ <?php else: ?>
213
+
214
+ <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($taxonomy));?>">
215
+ <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
216
+ <input name="<?php echo(esc_attr($id));?>" type="checkbox" autocomplete="off" id="<?php echo(esc_attr($id));?>" value="1" <?php checked('1', ! empty($enabled[$taxonomy]) );?> /> <?php echo(esc_html($type_obj->label));?>
217
+
218
+ <?php
219
+ echo ('</label></div>');
220
+
221
+ endif; // displaying checkbox UI
222
+
223
+ echo '</div>';
224
+ }
225
+ echo '</td>';
226
+
227
+ ?>
228
+ </tr>
229
+ </table>
230
+
231
+ <input type="submit" name="update_filtered_taxonomies" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
232
+ </dd>
233
+ </dl>
234
+
235
+ <dl>
236
+ <dt><?php esc_html_e('Detailed Taxonomy Capabilities', 'capsman-enhanced'); ?></dt>
237
+ <dd style="text-align:center;">
238
+ <?php
239
+ echo "<p class='cme-hint'>" . esc_html__( 'Enforce Edit, Delete and Assign capabilities separately from Management capability.', 'capsman-enhanced' ) . "</p>";
240
+
241
+ echo "<table style='width:100%'><tr>";
242
+
243
+ $unfiltered = apply_filters( 'pp_unfiltered_taxonomies', array( 'post_status', 'topic-tag' ) ); // avoid confusion with Edit Flow administrative taxonomy
244
+ $hidden = apply_filters( 'pp_hidden_taxonomies', array() );
245
+
246
+ echo '<td style="width:50%">';
247
+
248
+ $option_basename = 'detailed_taxonomies';
249
+ $option_name = 'cme_' . $option_basename;
250
+
251
+ $enabled = get_option( $option_name, array() );
252
+
253
+ foreach( $defined_taxonomies as $taxonomy => $type_obj ) {
254
+ if ( ! $taxonomy )
255
+ continue;
256
+
257
+ if ( in_array( $taxonomy, $unfiltered ) )
258
+ continue;
259
+
260
+ $taxonomy = sanitize_key($taxonomy);
261
+
262
+ $id = "$option_basename-" . $taxonomy;
263
+ ?>
264
+ <div style="text-align:left">
265
+ <?php if ( ! empty( $hidden[$taxonomy] ) ) :?>
266
+ <input name="<?php echo(esc_attr($id));?>" type="hidden" id="<?php echo(esc_attr($id));?>" value="1" />
267
+ <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
268
+
269
+ <?php else: ?>
270
+ <div class="agp-vspaced_input">
271
+ <label for="<?php echo(esc_attr($id));?>" title="<?php echo(esc_attr($taxonomy));?>">
272
+ <input name="<?php echo(esc_attr($option_basename) . '-options[]');?>" type="hidden" value="<?php echo(esc_attr($taxonomy))?>" />
273
+ <input name="<?php echo(esc_attr($id));?>" type="checkbox" autocomplete="off" id="<?php echo(esc_attr($id));?>" value="1" <?php checked('1', ! empty($enabled[$taxonomy]) );?> /> <?php echo(esc_html($type_obj->label));?>
274
+
275
+ <?php
276
+ echo ('</label></div>');
277
+
278
+ endif; // displaying checkbox UI
279
+
280
+ echo '</div>';
281
+ }
282
+ echo '</td>';
283
+
284
+ ?>
285
+ </tr>
286
+ </table>
287
+
288
+ <input type="submit" name="update_detailed_taxonomies" value="<?php esc_attr_e('Update', 'capsman-enhanced') ?>" class="button" />
289
+ </dd>
290
+ </dl>
291
+ <?php
292
+ }
293
+ }
294
+
includes/publishpress-roles.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
- class CME_PublishPressRoles {
3
- public static function scripts() {
4
- ?>
5
- <script type="text/javascript">
6
- /* <![CDATA[ */
7
- jQuery(document).ready(function ($) {
8
- $('#the-list').children('tr').each(function(index, e) {
9
- if (!$(e).find('td.display_name div.row-actions span.edit-capabilities').count) {
10
- var link = '';
11
- var is_administrator_role = ('role-administrator' == $(e).attr('id'));
12
- var role_name = $(e).attr('id');
13
- role_name = role_name.replace('role-', '');
14
-
15
- if (is_administrator_role) {
16
- link += ' | ';
17
- }
18
-
19
- link += '<a href="<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities'));?>' + '&role=' + role_name + '">' + 'Capabilities' + '</a> ';
20
-
21
- if (!is_administrator_role) {
22
- link += '| ';
23
- }
24
-
25
- $(e).find('td.display_name div.row-actions span.edit-role').after(' <span class="edit edit-capabilities">' + link + '</span>');
26
- }
27
- });
28
- });
29
- /* ]]> */
30
- </script>
31
- <style type="text/css">
32
-
33
- </style>
34
- <?php
35
- }
36
- }
1
+ <?php
2
+ class CME_PublishPressRoles {
3
+ public static function scripts() {
4
+ ?>
5
+ <script type="text/javascript">
6
+ /* <![CDATA[ */
7
+ jQuery(document).ready(function ($) {
8
+ $('#the-list').children('tr').each(function(index, e) {
9
+ if (!$(e).find('td.display_name div.row-actions span.edit-capabilities').count) {
10
+ var link = '';
11
+ var is_administrator_role = ('role-administrator' == $(e).attr('id'));
12
+ var role_name = $(e).attr('id');
13
+ role_name = role_name.replace('role-', '');
14
+
15
+ if (is_administrator_role) {
16
+ link += ' | ';
17
+ }
18
+
19
+ link += '<a href="<?php echo esc_url_raw(admin_url('admin.php?page=pp-capabilities'));?>' + '&role=' + role_name + '">' + 'Capabilities' + '</a> ';
20
+
21
+ if (!is_administrator_role) {
22
+ link += '| ';
23
+ }
24
+
25
+ $(e).find('td.display_name div.row-actions span.edit-role').after(' <span class="edit edit-capabilities">' + link + '</span>');
26
+ }
27
+ });
28
+ });
29
+ /* ]]> */
30
+ </script>
31
+ <style type="text/css">
32
+
33
+ </style>
34
+ <?php
35
+ }
36
+ }
includes/roles/class/class-pp-roles-actions.php CHANGED
@@ -1,615 +1,659 @@
1
- <?php
2
-
3
- class Pp_Roles_Actions
4
- {
5
-
6
- /**
7
- * @var string
8
- */
9
- protected $capability = 'manage_options';
10
-
11
- /**
12
- * @var Pp_Roles_Manager
13
- */
14
- protected $manager = null;
15
-
16
- /**
17
- * @var array
18
- */
19
- protected $actions = [
20
- 'pp-roles-add-role',
21
- 'pp-roles-edit-role',
22
- 'pp-roles-delete-role',
23
- 'pp-roles-hide-role',
24
- 'pp-roles-unhide-role',
25
- ];
26
-
27
- /**
28
- * Pp_Roles_Actions constructor.
29
- */
30
- public function __construct()
31
- {
32
- $this->manager = pp_capabilities_roles()->manager;
33
-
34
- if (did_action('wp_ajax_pp-roles-add-role') || did_action('wp_ajax_pp-roles-delete-role')) {
35
- $this->handle();
36
- }
37
- }
38
-
39
- /**
40
- * Is ajax request
41
- *
42
- * @return bool
43
- */
44
- protected function is_ajax()
45
- {
46
- return (defined('DOING_AJAX') && DOING_AJAX);
47
- }
48
-
49
- /**
50
- * Handle post actions
51
- */
52
- public function handle()
53
- {
54
- $current_action = $this->current_action();
55
-
56
- if (in_array($current_action, $this->actions)) {
57
- $current_action = str_replace('pp-roles-', '', $current_action);
58
- $current_action = str_replace('-', '_', $current_action);
59
- $this->$current_action();
60
- }
61
- }
62
-
63
- /**
64
- * Get the current action selected from the bulk actions dropdown.
65
- *
66
- * @return string|false The action name or False if no action was selected
67
- */
68
- protected function current_action()
69
- {
70
- if (isset($_REQUEST['filter_action']) && !empty($_REQUEST['filter_action'])) {
71
- return false;
72
- }
73
-
74
- if (isset($_REQUEST['action']) && -1 != $_REQUEST['action']) {
75
- return sanitize_key($_REQUEST['action']);
76
- }
77
-
78
- if (isset($_REQUEST['action2']) && -1 != $_REQUEST['action2']) {
79
- return sanitize_key($_REQUEST['action2']);
80
- }
81
-
82
- return false;
83
- }
84
-
85
- protected function notify_success($message) {
86
- $this->notify($message, 'success', false);
87
- }
88
-
89
- protected function notify_info($message) {
90
- $this->notify($message, 'info', false);
91
- }
92
-
93
- protected function notify_error($message) {
94
- $this->notify($message, 'error', false);
95
- }
96
-
97
- /**
98
- * Notify the user with a message. Handles ajax and post requests
99
- *
100
- * @param string $message The message to show to the user
101
- * @param string $type The type of message to show [error|success|warning\info]
102
- * @param bool $redirect If we should redirect to referrer
103
- * @param bool|string $redirect_url url to redirect to if provided
104
- */
105
- protected function notify($message, $type = 'error', $redirect = true, $redirect_url = false)
106
- {
107
- if (!in_array($type, ['error', 'success', 'warning'])) {
108
- $type = 'error';
109
- }
110
-
111
- if ($this->is_ajax()) {
112
- $format = '<div class="notice notice-%s is-dismissible"><p>%s</p></div>';
113
- wp_send_json_error(sprintf($format, $type, $message));
114
- exit;
115
- } else {
116
- //enqueue message
117
- pp_capabilities_roles()->notify->add($type, $message);
118
-
119
- if (!empty($_REQUEST['page']) && ('pp-capabilities' == $_REQUEST['page'])) {
120
- $redirect = false;
121
- }
122
-
123
- if ($redirect) {
124
- if (!$redirect_url) {
125
- $redirect_url = wp_get_referer();
126
- $redirect_url = wp_get_raw_referer();
127
-
128
- if (empty($redirect_url)) {
129
- $params = [
130
- 'page' => 'pp-capabilities-roles',
131
- ];
132
- $redirect_url = esc_url_raw(add_query_arg($params, admin_url('admin.php')));
133
- }
134
- }
135
- wp_safe_redirect($redirect_url);
136
- die();
137
- }
138
- }
139
- }
140
-
141
- /**
142
- * Check if the user is able to access this page
143
- */
144
- protected function check_permissions()
145
- {
146
-
147
- if (!current_user_can($this->capability)) {
148
- $this->notify(esc_html__('You do not have sufficient permissions to perform this action.', 'capsman-enhanced'));
149
- }
150
- }
151
-
152
- /**
153
- * Check nonce and notify if error
154
- *
155
- * @param string $action
156
- * @param string $query_arg
157
- */
158
- protected function check_nonce($action = '-1', $query_arg = '_wpnonce')
159
- {
160
- $checked = isset($_REQUEST[$query_arg]) && wp_verify_nonce(sanitize_key($_REQUEST[$query_arg]), $action);
161
- if (!$checked) {
162
- $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
163
- }
164
- }
165
-
166
- /**
167
- * Handles add role action
168
- */
169
- public function add_role()
170
- {
171
- /**
172
- * Check capabilities
173
- */
174
- $this->check_permissions();
175
-
176
- /**
177
- * Check nonce
178
- */
179
- if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'add-role')) {
180
- $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
181
- }
182
-
183
- if (empty($_REQUEST['role_name'])) {
184
- $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
185
- }
186
-
187
- if (empty($_REQUEST['role_slug'])) {
188
- $role_slug = str_replace(
189
- [' ', '(', ')', '&', '#', '@', '+', ','],
190
- '_',
191
- strtolower(sanitize_text_field($_REQUEST['role_name']))
192
- );
193
-
194
- $role_slug = preg_replace('/[^0-9a-zA-Z\-\_]/', '', $role_slug);
195
- } else {
196
- $role_slug = sanitize_key($_REQUEST['role_slug']);
197
- }
198
-
199
- /**
200
- * Validate input data
201
- */
202
- require_once(dirname(CME_FILE).'/includes/handler.php');
203
- $capsman_handler = new CapsmanHandler();
204
- $role = $capsman_handler->createNewName(sanitize_key($role_slug));
205
-
206
- /**
207
- * Check for invalid name entry
208
- */
209
- if (!empty($role['error']) && ('invalid_name' == $role['error'])) {
210
- $out = sprintf(
211
- __('Invalid role name entry: %s', 'capsman-enhanced'),
212
- esc_html($role['name'])
213
- );
214
- $this->notify($out);
215
- }
216
-
217
- /**
218
- * Check role doesn't exist
219
- */
220
- if (!empty($role['error']) && ('role_exists' == $role['error'])) {
221
- //this role already exist
222
- $out = sprintf(
223
- __('The role "%s" already exists. Please choose a different name.', 'capsman-enhanced'),
224
- esc_html($role['name'])
225
- );
226
-
227
- $this->notify($out);
228
- }
229
-
230
- /**
231
- * Add role
232
- */
233
- $role_capabilities = [];
234
-
235
- //get copied role capabilites
236
- if (!empty($_REQUEST['role_action']) && $_REQUEST['role_action'] === 'copy'
237
- && !empty($_REQUEST['role'])
238
- && $role_data = pp_roles_get_role_data(sanitize_key($_REQUEST['role']))
239
- ) {
240
- $role_capabilities = $role_data['capabilities'];
241
- }
242
- if (isset($_REQUEST['role_level'])) {
243
- $role_capabilities = array_merge($role_capabilities, ak_level2caps(absint($_REQUEST['role_level'])));
244
- }
245
- $result = add_role($role['name'], sanitize_text_field($_REQUEST['role_name']), $role_capabilities);
246
- if (!$result instanceof WP_Role) {
247
- if ($this->notify(esc_html__('Something went wrong, the system wasn\'t able to create the role, refresh the page and try again.', 'capsman-enhanced'))) {
248
- return;
249
- }
250
- }
251
-
252
- /**
253
- * Notify user and redirect
254
- */
255
- $out = sprintf(esc_html__('The new role %s was created successfully.', 'capsman-enhanced'), sanitize_text_field($_REQUEST['role_name']));
256
-
257
- $redirect_url = esc_url_raw(
258
- add_query_arg(
259
- [
260
- 'page' => 'pp-capabilities-roles',
261
- 'add' => 'new_item',
262
- 'role_action' => 'edit',
263
- 'role' => esc_attr($role['name'])
264
- ],
265
- admin_url('admin.php')
266
- )
267
- );
268
-
269
- $this->notify($out, 'success', true, $redirect_url);
270
- }
271
-
272
- /**
273
- * Handles edit role action
274
- */
275
- public function edit_role()
276
- {
277
- global $wp_roles;
278
-
279
- /**
280
- * Check capabilities
281
- */
282
- $this->check_permissions();
283
-
284
- /**
285
- * Check nonce
286
- */
287
- if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'edit-role')) {
288
- $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
289
- }
290
-
291
- if (empty($_REQUEST['current_role']) || empty($_REQUEST['role_name'])) {
292
- $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
293
- }
294
-
295
- /**
296
- * check if it's delete action and refer
297
- */
298
- if (!empty($_REQUEST['delete_role'])) {
299
- $this->delete_role(sanitize_key($_REQUEST['current_role']), ['nonce_check' => 'edit-role']);
300
- return;
301
- }
302
-
303
- /**
304
- * Update role
305
- */
306
- $current = get_role(sanitize_key($_REQUEST['current_role']));
307
- $new_title = sanitize_text_field($_REQUEST['role_name']);
308
-
309
- $old_title = $wp_roles->roles[$current->name]['name'];
310
- $wp_roles->roles[$current->name]['name'] = $new_title;
311
-
312
- if ($current && isset($wp_roles->roles[$current->name]) && $new_title) {
313
- $old_title = $wp_roles->roles[$current->name]['name'];
314
- $wp_roles->roles[$current->name]['name'] = $new_title;
315
- update_option($wp_roles->role_key, $wp_roles->roles);
316
- }
317
-
318
- $new_caps = pp_roles_remove_capabilities_role_level($current->capabilities);
319
-
320
- if (isset($_REQUEST['role_level'])) {
321
- $add_caps = array_merge($new_caps, ak_level2caps(absint($_REQUEST['role_level'])));
322
- }else{
323
- $add_caps = $new_caps;
324
- }
325
- $del_caps = array_diff_key($current->capabilities, $new_caps);
326
-
327
-
328
- // Remove capabilities from role
329
- foreach ( $del_caps as $cap => $grant) {
330
- if ( current_user_can('administrator') || current_user_can($cap) )
331
- $current->remove_cap($cap);
332
- }
333
-
334
- //add new capabilities to the role
335
- foreach ( $add_caps as $cap => $grant ) {
336
- if ( current_user_can('administrator') || current_user_can($cap) )
337
- $current->add_cap( $cap, $grant );
338
- }
339
-
340
-
341
- /**
342
- * Notify user and redirect
343
- */
344
- $out = sprintf( __('%s role updated successfully.', 'capsman-enhanced'), $new_title);
345
-
346
- $redirect_url = esc_url_raw(
347
- add_query_arg(
348
- [
349
- 'page' => 'pp-capabilities-roles',
350
- 'add' => 'new_item',
351
- 'role_action' => 'edit',
352
- 'role' => esc_attr(sanitize_key($_REQUEST['current_role']))
353
- ],
354
- admin_url('admin.php')
355
- )
356
- );
357
-
358
- $this->notify($out, 'success', true, $redirect_url);
359
- }
360
-
361
- /**
362
- * Delete role action
363
- */
364
- public function delete_role($role = '', $args = [])
365
- {
366
- $defaults = ['allow_system_role_deletion' => false, 'nonce_check' => 'bulk-roles'];
367
- $args = array_merge($defaults, $args);
368
- foreach (array_keys($defaults) as $var) {
369
- $$var = $args[$var];
370
- }
371
-
372
- if (empty($role)) {
373
- $role = (isset($_REQUEST['role'])) ? array_map('sanitize_key', (array) ($_REQUEST['role'])) : '';
374
- }
375
-
376
- /**
377
- * Check capabilities
378
- */
379
- $this->check_permissions();
380
-
381
- /**
382
- * Check nonce
383
- */
384
- if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), $nonce_check)) {
385
- $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
386
- }
387
-
388
- /**
389
- * Validate input data
390
- */
391
- $roles = [];
392
- if ($role) {
393
- if (is_string($role)) {
394
- $input = sanitize_key($role);
395
- $roles[] = $input;
396
- } else if (is_array($role)) {
397
- foreach ($role as $key => $id) {
398
- $roles[] = sanitize_key($id);
399
- }
400
- }
401
- } else {
402
- return;
403
- }
404
-
405
- /**
406
- * If no roles provided return
407
- */
408
- if (empty($roles)) {
409
- $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
410
- }
411
-
412
- $default = get_option('default_role');
413
-
414
- if ( $default == $role ) {
415
- $this->notify(
416
- sprintf(
417
- esc_html__('Cannot delete default role. You <a href="%s">have to change it first</a>.', 'capsman-enhanced'),
418
- 'options-general.php'
419
- )
420
- );
421
- return;
422
- }
423
-
424
- /**
425
- * Check if is a system role
426
- */
427
- if (!$allow_system_role_deletion) {
428
- foreach ($roles as $key => $role) {
429
-
430
- if ($this->manager->is_system_role($role)) {
431
- unset($roles[$key]);
432
- }
433
- }
434
-
435
- if (empty($roles)) {
436
- $this->notify(esc_html__('Deleting a system role is not allowed.', 'capsman-enhanced'));
437
- }
438
- }
439
-
440
- /**
441
- * Delete roles
442
- */
443
- $deleted = 0;
444
- $user_count = 0;
445
-
446
- foreach ($roles as $role) {
447
- if (pp_capabilities_is_editable_role($role)) {
448
- $moved_users = $this->manager->delete_role($role);
449
- if (false !== $moved_users) {
450
- $deleted++;
451
- $user_count = $user_count + $moved_users;
452
- }
453
- }
454
- }
455
-
456
- if ($deleted) {
457
- $default_name = (wp_roles()->is_role($default)) ? wp_roles()->role_names[$default] : $default;
458
- $users_message = ($user_count) ? sprintf(esc_html__('%1$d users moved to default role %2$s.', 'capsman-enhanced'), (int) $user_count, esc_html($default_name)) : '';
459
-
460
- $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
461
-
462
- $single = sprintf(
463
- esc_html__('The role %1$s was successfully deleted. %2$s', 'capsman-enhanced'),
464
- esc_html($roles[0]),
465
- $users_message
466
- );
467
-
468
- $plural = sprintf(
469
- esc_html__('The selected %1$s roles were successfully deleted. %2$s', 'capsman-enhanced'),
470
- $deleted,
471
- $users_message
472
- );
473
-
474
- $out = _n($single, $plural, $deleted, 'capsman-enhanced');
475
-
476
- if ($this->is_ajax()) {
477
- wp_send_json_success($out);
478
- } else {
479
- $redirect_url = esc_url_raw(
480
- add_query_arg(
481
- [
482
- 'page' => 'pp-capabilities-roles'
483
- ],
484
- admin_url('admin.php')
485
- )
486
- );
487
-
488
- $this->notify($out, 'success', true, $redirect_url);
489
- }
490
- } else {
491
- $this->notify(esc_html__('The role could not be deleted.', 'capsman-enhanced'));
492
- }
493
- }
494
-
495
- /**
496
- * Hide role action
497
- */
498
- public function hide_role($role = '', $args = [])
499
- {
500
- if (!defined('PRESSPERMIT_ACTIVE')) {
501
- return;
502
- }
503
-
504
- if (empty($role)) {
505
- $role = (isset($_REQUEST['role'])) ? sanitize_key($_REQUEST['role']) : '';
506
- }
507
-
508
- /**
509
- * Check capabilities
510
- */
511
- $this->check_permissions();
512
-
513
- /**
514
- * Validate input data
515
- */
516
- $roles = [];
517
- if ($role) {
518
- if (is_string($role)) {
519
- $input = sanitize_key($role);
520
- $roles[] = $input;
521
- } else if (is_array($role)) {
522
- foreach ($role as $key => $id) {
523
- $roles[] = sanitize_key($id);
524
- }
525
- }
526
- } else {
527
- return;
528
- }
529
-
530
- /**
531
- * If no roles provided return
532
- */
533
- if (empty($roles)) {
534
- $out = __('Missing parameters, refresh the page and try again.', 'capsman-enhanced');
535
- $this->notify($out);
536
- }
537
-
538
- $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
539
- $pp_only = array_merge($pp_only, (array) $roles);
540
- pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
541
-
542
- $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
543
-
544
- $out = sprintf(
545
- __('The role %1$s was successfully hidden.', 'capsman-enhanced'),
546
- $roles[0]
547
- );
548
-
549
- if ($this->is_ajax()) {
550
- wp_send_json_success($out);
551
- } else {
552
- $this->notify($out, 'success');
553
- }
554
- }
555
-
556
- /**
557
- * Unhide role action
558
- */
559
- public function unhide_role($role = '', $args = [])
560
- {
561
- if (!defined('PRESSPERMIT_ACTIVE')) {
562
- return;
563
- }
564
-
565
- if (empty($role)) {
566
- $role = (isset($_REQUEST['role'])) ? sanitize_key($_REQUEST['role']) : '';
567
- }
568
-
569
- /**
570
- * Check capabilities
571
- */
572
- $this->check_permissions();
573
-
574
- /**
575
- * Validate input data
576
- */
577
- $roles = [];
578
- if ($role) {
579
- if (is_string($role)) {
580
- $input = sanitize_key($role);
581
- $roles[] = $input;
582
- } else if (is_array($role)) {
583
- foreach ($role as $key => $id) {
584
- $roles[] = sanitize_key($id);
585
- }
586
- }
587
- } else {
588
- return;
589
- }
590
-
591
- /**
592
- * If no roles provided return
593
- */
594
- if (empty($roles)) {
595
- $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
596
- }
597
-
598
- $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
599
- $pp_only = array_diff($pp_only, (array) $roles);
600
- pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
601
-
602
- $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
603
-
604
- $out = sprintf(
605
- __('The role %1$s was successfully unhidden.', 'capsman-enhanced'),
606
- $roles[0]
607
- );
608
-
609
- if ($this->is_ajax()) {
610
- wp_send_json_success($out);
611
- } else {
612
- $this->notify($out, 'success');
613
- }
614
- }
615
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pp_Roles_Actions
4
+ {
5
+
6
+ /**
7
+ * @var string
8
+ */
9
+ protected $capability = 'manage_options';
10
+
11
+ /**
12
+ * @var Pp_Roles_Manager
13
+ */
14
+ protected $manager = null;
15
+
16
+ /**
17
+ * @var array
18
+ */
19
+ protected $actions = [
20
+ 'pp-roles-add-role',
21
+ 'pp-roles-edit-role',
22
+ 'pp-roles-delete-role',
23
+ 'pp-roles-hide-role',
24
+ 'pp-roles-unhide-role',
25
+ ];
26
+
27
+ /**
28
+ * Pp_Roles_Actions constructor.
29
+ */
30
+ public function __construct()
31
+ {
32
+ $this->manager = pp_capabilities_roles()->manager;
33
+
34
+ if (did_action('wp_ajax_pp-roles-add-role') || did_action('wp_ajax_pp-roles-delete-role')) {
35
+ $this->handle();
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Is ajax request
41
+ *
42
+ * @return bool
43
+ */
44
+ protected function is_ajax()
45
+ {
46
+ return (defined('DOING_AJAX') && DOING_AJAX);
47
+ }
48
+
49
+ /**
50
+ * Handle post actions
51
+ */
52
+ public function handle()
53
+ {
54
+ $current_action = $this->current_action();
55
+
56
+ if (in_array($current_action, $this->actions)) {
57
+ $current_action = str_replace('pp-roles-', '', $current_action);
58
+ $current_action = str_replace('-', '_', $current_action);
59
+ $this->$current_action();
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Get the current action selected from the bulk actions dropdown.
65
+ *
66
+ * @return string|false The action name or False if no action was selected
67
+ */
68
+ protected function current_action()
69
+ {
70
+ if (isset($_REQUEST['filter_action']) && !empty($_REQUEST['filter_action'])) {
71
+ return false;
72
+ }
73
+
74
+ if (isset($_REQUEST['action']) && -1 != $_REQUEST['action']) {
75
+ return sanitize_key($_REQUEST['action']);
76
+ }
77
+
78
+ if (isset($_REQUEST['action2']) && -1 != $_REQUEST['action2']) {
79
+ return sanitize_key($_REQUEST['action2']);
80
+ }
81
+
82
+ return false;
83
+ }
84
+
85
+ protected function notify_success($message) {
86
+ $this->notify($message, 'success', false);
87
+ }
88
+
89
+ protected function notify_info($message) {
90
+ $this->notify($message, 'info', false);
91
+ }
92
+
93
+ protected function notify_error($message) {
94
+ $this->notify($message, 'error', false);
95
+ }
96
+
97
+ /**
98
+ * Notify the user with a message. Handles ajax and post requests
99
+ *
100
+ * @param string $message The message to show to the user
101
+ * @param string $type The type of message to show [error|success|warning\info]
102
+ * @param bool $redirect If we should redirect to referrer
103
+ * @param bool|string $redirect_url url to redirect to if provided
104
+ */
105
+ protected function notify($message, $type = 'error', $redirect = true, $redirect_url = false)
106
+ {
107
+ if (!in_array($type, ['error', 'success', 'warning'])) {
108
+ $type = 'error';
109
+ }
110
+
111
+ if ($this->is_ajax()) {
112
+ $format = '<div class="notice notice-%s is-dismissible"><p>%s</p></div>';
113
+ wp_send_json_error(sprintf($format, $type, $message));
114
+ exit;
115
+ } else {
116
+ //enqueue message
117
+ pp_capabilities_roles()->notify->add($type, $message);
118
+
119
+ if (!empty($_REQUEST['page']) && ('pp-capabilities' == $_REQUEST['page'])) {
120
+ $redirect = false;
121
+ }
122
+
123
+ if ($redirect) {
124
+ if (!$redirect_url) {
125
+ $redirect_url = wp_get_referer();
126
+ $redirect_url = wp_get_raw_referer();
127
+
128
+ if (empty($redirect_url)) {
129
+ $params = [
130
+ 'page' => 'pp-capabilities-roles',
131
+ ];
132
+ $redirect_url = esc_url_raw(add_query_arg($params, admin_url('admin.php')));
133
+ }
134
+ }
135
+ wp_safe_redirect($redirect_url);
136
+ die();
137
+ }
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Check if the user is able to access this page
143
+ */
144
+ protected function check_permissions()
145
+ {
146
+
147
+ if (!current_user_can($this->capability)) {
148
+ $this->notify(esc_html__('You do not have sufficient permissions to perform this action.', 'capsman-enhanced'));
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Check nonce and notify if error
154
+ *
155
+ * @param string $action
156
+ * @param string $query_arg
157
+ */
158
+ protected function check_nonce($action = '-1', $query_arg = '_wpnonce')
159
+ {
160
+ $checked = isset($_REQUEST[$query_arg]) && wp_verify_nonce(sanitize_key($_REQUEST[$query_arg]), $action);
161
+ if (!$checked) {
162
+ $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Handles add role action
168
+ */
169
+ public function add_role()
170
+ {
171
+ /**
172
+ * Check capabilities
173
+ */
174
+ $this->check_permissions();
175
+
176
+ /**
177
+ * Check nonce
178
+ */
179
+ if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'add-role')) {
180
+ $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
181
+ }
182
+
183
+ if (empty($_REQUEST['role_name'])) {
184
+ $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
185
+ }
186
+
187
+ if (empty($_REQUEST['role_slug'])) {
188
+ $role_slug = str_replace(
189
+ [' ', '(', ')', '&', '#', '@', '+', ','],
190
+ '_',
191
+ strtolower(sanitize_text_field($_REQUEST['role_name']))
192
+ );
193
+
194
+ $role_slug = preg_replace('/[^0-9a-zA-Z\-\_]/', '', $role_slug);
195
+ } else {
196
+ $role_slug = sanitize_key($_REQUEST['role_slug']);
197
+ }
198
+
199
+ /**
200
+ * Validate input data
201
+ */
202
+ require_once(dirname(CME_FILE).'/includes/handler.php');
203
+ $capsman_handler = new CapsmanHandler();
204
+ $role = $capsman_handler->createNewName(sanitize_key($role_slug));
205
+
206
+ /**
207
+ * Check for invalid name entry
208
+ */
209
+ if (!empty($role['error']) && ('invalid_name' == $role['error'])) {
210
+ $out = sprintf(
211
+ __('Invalid role name entry: %s', 'capsman-enhanced'),
212
+ esc_html($role['name'])
213
+ );
214
+ $this->notify($out);
215
+ }
216
+
217
+ /**
218
+ * Check role doesn't exist
219
+ */
220
+ if (!empty($role['error']) && ('role_exists' == $role['error'])) {
221
+ //this role already exist
222
+ $out = sprintf(
223
+ __('The role "%s" already exists. Please choose a different name.', 'capsman-enhanced'),
224
+ esc_html($role['name'])
225
+ );
226
+
227
+ $this->notify($out);
228
+ }
229
+
230
+ /**
231
+ * Add role
232
+ */
233
+ $role_capabilities = [];
234
+ $copied_role = false;
235
+
236
+ //get copied role capabilites
237
+ if (!empty($_REQUEST['role_action']) && $_REQUEST['role_action'] === 'copy'
238
+ && !empty($_REQUEST['role'])
239
+ && $role_data = pp_roles_get_role_data(sanitize_key($_REQUEST['role']))
240
+ ) {
241
+ $role_capabilities = $role_data['capabilities'];
242
+ $copied_role = sanitize_key($_REQUEST['role']);
243
+ }
244
+
245
+ if (isset($_REQUEST['role_level'])) {
246
+ $role_capabilities = array_merge($role_capabilities, ak_level2caps(absint($_REQUEST['role_level'])));
247
+ }
248
+ $result = add_role($role['name'], sanitize_text_field($_REQUEST['role_name']), $role_capabilities);
249
+ if (!$result instanceof WP_Role) {
250
+ if ($this->notify(esc_html__('Something went wrong, the system wasn\'t able to create the role, refresh the page and try again.', 'capsman-enhanced'))) {
251
+ return;
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Copy all features to new role
257
+ */
258
+ if ($copied_role) {
259
+ $role_slug = $role['name'];
260
+ //Editor Features
261
+ $classic_editor = pp_capabilities_is_classic_editor_available();
262
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
263
+ foreach ($def_post_types as $post_type) {
264
+ if ($classic_editor) {
265
+ $post_features_option = get_option("capsman_feature_restrict_classic_{$post_type}", []);
266
+ if (is_array($post_features_option) && array_key_exists($copied_role, $post_features_option)) {
267
+ $post_features_option[$role_slug] = $post_features_option[$copied_role];
268
+ update_option("capsman_feature_restrict_classic_{$post_type}", $post_features_option, false);
269
+ }
270
+ }
271
+ $post_features_option = get_option("capsman_feature_restrict_{$post_type}", []);
272
+ if (is_array($post_features_option) && array_key_exists($copied_role, $post_features_option)) {
273
+ $post_features_option[$role_slug] = $post_features_option[$copied_role];
274
+ update_option("capsman_feature_restrict_{$post_type}", $post_features_option, false);
275
+ }
276
+ }
277
+
278
+ //Admin Features
279
+ $disabled_admin_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
280
+ if (is_array($disabled_admin_items) && array_key_exists($copied_role, $disabled_admin_items)) {
281
+ $disabled_admin_items[$role_slug] = $disabled_admin_items[$copied_role];
282
+ update_option('capsman_disabled_admin_features', $disabled_admin_items, false);
283
+ }
284
+
285
+ /**
286
+ * Allow other plugins to perform action after role is copied.
287
+ *
288
+ * @param string $role_slug New role slug.
289
+ * @param string $copied_role Original role name that was copied.
290
+ *
291
+ * @since 2.4.0
292
+ */
293
+ do_action('pp_capabilities_after_role_copied', $role_slug, $copied_role);
294
+ }
295
+
296
+ /**
297
+ * Notify user and redirect
298
+ */
299
+ $out = sprintf(esc_html__('The new role %s was created successfully.', 'capsman-enhanced'), sanitize_text_field($_REQUEST['role_name']));
300
+
301
+ $redirect_url = esc_url_raw(
302
+ add_query_arg(
303
+ [
304
+ 'page' => 'pp-capabilities-roles',
305
+ 'add' => 'new_item',
306
+ 'role_action' => 'edit',
307
+ 'role' => esc_attr($role['name'])
308
+ ],
309
+ admin_url('admin.php')
310
+ )
311
+ );
312
+
313
+ $this->notify($out, 'success', true, $redirect_url);
314
+ }
315
+
316
+ /**
317
+ * Handles edit role action
318
+ */
319
+ public function edit_role()
320
+ {
321
+ global $wp_roles;
322
+
323
+ /**
324
+ * Check capabilities
325
+ */
326
+ $this->check_permissions();
327
+
328
+ /**
329
+ * Check nonce
330
+ */
331
+ if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'edit-role')) {
332
+ $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
333
+ }
334
+
335
+ if (empty($_REQUEST['current_role']) || empty($_REQUEST['role_name'])) {
336
+ $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
337
+ }
338
+
339
+ /**
340
+ * check if it's delete action and refer
341
+ */
342
+ if (!empty($_REQUEST['delete_role'])) {
343
+ $this->delete_role(sanitize_key($_REQUEST['current_role']), ['nonce_check' => 'edit-role']);
344
+ return;
345
+ }
346
+
347
+ /**
348
+ * Update role
349
+ */
350
+ $current = get_role(sanitize_key($_REQUEST['current_role']));
351
+ $new_title = sanitize_text_field($_REQUEST['role_name']);
352
+
353
+ $old_title = $wp_roles->roles[$current->name]['name'];
354
+ $wp_roles->roles[$current->name]['name'] = $new_title;
355
+
356
+ if ($current && isset($wp_roles->roles[$current->name]) && $new_title) {
357
+ $old_title = $wp_roles->roles[$current->name]['name'];
358
+ $wp_roles->roles[$current->name]['name'] = $new_title;
359
+ update_option($wp_roles->role_key, $wp_roles->roles);
360
+ }
361
+
362
+ $new_caps = pp_roles_remove_capabilities_role_level($current->capabilities);
363
+
364
+ if (isset($_REQUEST['role_level'])) {
365
+ $add_caps = array_merge($new_caps, ak_level2caps(absint($_REQUEST['role_level'])));
366
+ }else{
367
+ $add_caps = $new_caps;
368
+ }
369
+ $del_caps = array_diff_key($current->capabilities, $new_caps);
370
+
371
+
372
+ // Remove capabilities from role
373
+ foreach ( $del_caps as $cap => $grant) {
374
+ if ( current_user_can('administrator') || current_user_can($cap) )
375
+ $current->remove_cap($cap);
376
+ }
377
+
378
+ //add new capabilities to the role
379
+ foreach ( $add_caps as $cap => $grant ) {
380
+ if ( current_user_can('administrator') || current_user_can($cap) )
381
+ $current->add_cap( $cap, $grant );
382
+ }
383
+
384
+
385
+ /**
386
+ * Notify user and redirect
387
+ */
388
+ $out = sprintf( __('%s role updated successfully.', 'capsman-enhanced'), $new_title);
389
+
390
+ $redirect_url = esc_url_raw(
391
+ add_query_arg(
392
+ [
393
+ 'page' => 'pp-capabilities-roles',
394
+ 'add' => 'new_item',
395
+ 'role_action' => 'edit',
396
+ 'role' => esc_attr(sanitize_key($_REQUEST['current_role']))
397
+ ],
398
+ admin_url('admin.php')
399
+ )
400
+ );
401
+
402
+ $this->notify($out, 'success', true, $redirect_url);
403
+ }
404
+
405
+ /**
406
+ * Delete role action
407
+ */
408
+ public function delete_role($role = '', $args = [])
409
+ {
410
+ $defaults = ['allow_system_role_deletion' => false, 'nonce_check' => 'bulk-roles'];
411
+ $args = array_merge($defaults, $args);
412
+ foreach (array_keys($defaults) as $var) {
413
+ $$var = $args[$var];
414
+ }
415
+
416
+ if (empty($role)) {
417
+ $role = (isset($_REQUEST['role'])) ? array_map('sanitize_key', (array) ($_REQUEST['role'])) : '';
418
+ }
419
+
420
+ /**
421
+ * Check capabilities
422
+ */
423
+ $this->check_permissions();
424
+
425
+ /**
426
+ * Check nonce
427
+ */
428
+ if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), $nonce_check)) {
429
+ $this->notify(esc_html__('Your link has expired, refresh the page and try again.', 'capsman-enhanced'));
430
+ }
431
+
432
+ /**
433
+ * Validate input data
434
+ */
435
+ $roles = [];
436
+ if ($role) {
437
+ if (is_string($role)) {
438
+ $input = sanitize_key($role);
439
+ $roles[] = $input;
440
+ } else if (is_array($role)) {
441
+ foreach ($role as $key => $id) {
442
+ $roles[] = sanitize_key($id);
443
+ }
444
+ }
445
+ } else {
446
+ return;
447
+ }
448
+
449
+ /**
450
+ * If no roles provided return
451
+ */
452
+ if (empty($roles)) {
453
+ $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
454
+ }
455
+
456
+ $default = get_option('default_role');
457
+
458
+ if ( $default == $role ) {
459
+ $this->notify(
460
+ sprintf(
461
+ esc_html__('Cannot delete default role. You <a href="%s">have to change it first</a>.', 'capsman-enhanced'),
462
+ 'options-general.php'
463
+ )
464
+ );
465
+ return;
466
+ }
467
+
468
+ /**
469
+ * Check if is a system role
470
+ */
471
+ if (!$allow_system_role_deletion) {
472
+ foreach ($roles as $key => $role) {
473
+
474
+ if ($this->manager->is_system_role($role)) {
475
+ unset($roles[$key]);
476
+ }
477
+ }
478
+
479
+ if (empty($roles)) {
480
+ $this->notify(esc_html__('Deleting a system role is not allowed.', 'capsman-enhanced'));
481
+ }
482
+ }
483
+
484
+ /**
485
+ * Delete roles
486
+ */
487
+ $deleted = 0;
488
+ $user_count = 0;
489
+
490
+ foreach ($roles as $role) {
491
+ if (pp_capabilities_is_editable_role($role)) {
492
+ $moved_users = $this->manager->delete_role($role);
493
+ if (false !== $moved_users) {
494
+ $deleted++;
495
+ $user_count = $user_count + $moved_users;
496
+ }
497
+ }
498
+ }
499
+
500
+ if ($deleted) {
501
+ $default_name = (wp_roles()->is_role($default)) ? wp_roles()->role_names[$default] : $default;
502
+ $users_message = ($user_count) ? sprintf(esc_html__('%1$d users moved to default role %2$s.', 'capsman-enhanced'), (int) $user_count, esc_html($default_name)) : '';
503
+
504
+ $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
505
+
506
+ $single = sprintf(
507
+ esc_html__('The role %1$s was successfully deleted. %2$s', 'capsman-enhanced'),
508
+ esc_html($roles[0]),
509
+ $users_message
510
+ );
511
+
512
+ $plural = sprintf(
513
+ esc_html__('The selected %1$s roles were successfully deleted. %2$s', 'capsman-enhanced'),
514
+ $deleted,
515
+ $users_message
516
+ );
517
+
518
+ $out = _n($single, $plural, $deleted, 'capsman-enhanced');
519
+
520
+ if ($this->is_ajax()) {
521
+ wp_send_json_success($out);
522
+ } else {
523
+ $redirect_url = esc_url_raw(
524
+ add_query_arg(
525
+ [
526
+ 'page' => 'pp-capabilities-roles'
527
+ ],
528
+ admin_url('admin.php')
529
+ )
530
+ );
531
+
532
+ $this->notify($out, 'success', true, $redirect_url);
533
+ }
534
+ } else {
535
+ $this->notify(esc_html__('The role could not be deleted.', 'capsman-enhanced'));
536
+ }
537
+ }
538
+
539
+ /**
540
+ * Hide role action
541
+ */
542
+ public function hide_role($role = '', $args = [])
543
+ {
544
+ if (!defined('PRESSPERMIT_ACTIVE')) {
545
+ return;
546
+ }
547
+
548
+ if (empty($role)) {
549
+ $role = (isset($_REQUEST['role'])) ? sanitize_key($_REQUEST['role']) : '';
550
+ }
551
+
552
+ /**
553
+ * Check capabilities
554
+ */
555
+ $this->check_permissions();
556
+
557
+ /**
558
+ * Validate input data
559
+ */
560
+ $roles = [];
561
+ if ($role) {
562
+ if (is_string($role)) {
563
+ $input = sanitize_key($role);
564
+ $roles[] = $input;
565
+ } else if (is_array($role)) {
566
+ foreach ($role as $key => $id) {
567
+ $roles[] = sanitize_key($id);
568
+ }
569
+ }
570
+ } else {
571
+ return;
572
+ }
573
+
574
+ /**
575
+ * If no roles provided return
576
+ */
577
+ if (empty($roles)) {
578
+ $out = __('Missing parameters, refresh the page and try again.', 'capsman-enhanced');
579
+ $this->notify($out);
580
+ }
581
+
582
+ $pp_only = (array) pp_capabilities_get_permissions_option( 'supplemental_role_defs' );
583
+ $pp_only = array_merge($pp_only, (array) $roles);
584
+ pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
585
+
586
+ $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
587
+
588
+ $out = sprintf(
589
+ __('The role %1$s was successfully hidden.', 'capsman-enhanced'),
590
+ $roles[0]
591
+ );
592
+
593
+ if ($this->is_ajax()) {
594
+ wp_send_json_success($out);
595
+ } else {
596
+ $this->notify($out, 'success');
597
+ }
598
+ }
599
+
600
+ /**
601
+ * Unhide role action
602
+ */
603
+ public function unhide_role($role = '', $args = [])
604
+ {
605
+ if (!defined('PRESSPERMIT_ACTIVE')) {
606
+ return;
607
+ }
608
+
609
+ if (empty($role)) {
610
+ $role = (isset($_REQUEST['role'])) ? sanitize_key($_REQUEST['role']) : '';
611
+ }
612
+
613
+ /**
614
+ * Check capabilities
615
+ */
616
+ $this->check_permissions();
617
+
618
+ /**
619
+ * Validate input data
620
+ */
621
+ $roles = [];
622
+ if ($role) {
623
+ if (is_string($role)) {
624
+ $input = sanitize_key($role);
625
+ $roles[] = $input;
626
+ } else if (is_array($role)) {
627
+ foreach ($role as $key => $id) {
628
+ $roles[] = sanitize_key($id);
629
+ }
630
+ }
631
+ } else {
632
+ return;
633
+ }
634
+
635
+ /**
636
+ * If no roles provided return
637
+ */
638
+ if (empty($roles)) {
639
+ $this->notify(esc_html__('Missing parameters, refresh the page and try again.', 'capsman-enhanced'));
640
+ }
641
+
642
+ $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
643
+ $pp_only = array_diff($pp_only, (array) $roles);
644
+ pp_capabilities_update_permissions_option('supplemental_role_defs', $pp_only);
645
+
646
+ $role_name = (wp_roles()->is_role($roles[0])) ? wp_roles()->role_names[$roles[0]] : $roles[0];
647
+
648
+ $out = sprintf(
649
+ __('The role %1$s was successfully unhidden.', 'capsman-enhanced'),
650
+ $roles[0]
651
+ );
652
+
653
+ if ($this->is_ajax()) {
654
+ wp_send_json_success($out);
655
+ } else {
656
+ $this->notify($out, 'success');
657
+ }
658
+ }
659
+ }
includes/roles/class/class-pp-roles-admin.php CHANGED
@@ -1,491 +1,502 @@
1
- <?php
2
-
3
- class Pp_Roles_Admin
4
- {
5
-
6
- /**
7
- * The capability
8
- *
9
- * @access protected
10
- * @var string
11
- */
12
- protected $capability = 'manage_options';
13
-
14
- /**
15
- * Roles list table instance
16
- *
17
- * @var null
18
- */
19
- protected $roles_list_table;
20
-
21
- /**
22
- * Initialize the class and set its properties.
23
- *
24
- */
25
- public function __construct()
26
- {
27
- global $hook_suffix; //avoid warning outputs
28
- if (!isset($hook_suffix)) {
29
- $hook_suffix = '';
30
- }
31
-
32
- $this->roles_list_table = null;
33
- $this->get_roles_list_table();
34
- }
35
-
36
- /**
37
- * Handle post actions
38
- */
39
- public function handle()
40
- {
41
- $current_action = $this->current_action();
42
-
43
- if (in_array($current_action, $this->actions)) {
44
- $current_action = str_replace('pp-roles-', '', $current_action);
45
- $current_action = str_replace('-', '_', $current_action);
46
- $this->$current_action();
47
- }
48
- }
49
-
50
- /**
51
- * Get the current action selected from the bulk actions dropdown.
52
- *
53
- * @return string|false The action name or False if no action was selected
54
- */
55
- protected function current_action()
56
- {
57
- if (isset($_REQUEST['filter_action']) && !empty($_REQUEST['filter_action'])) {
58
- return false;
59
- }
60
-
61
- if (isset($_REQUEST['action']) && -1 != $_REQUEST['action']) {
62
- return sanitize_key($_REQUEST['action']);
63
- }
64
-
65
- if (isset($_REQUEST['action2']) && -1 != $_REQUEST['action2']) {
66
- return sanitize_key($_REQUEST['action2']);
67
- }
68
-
69
- return false;
70
- }
71
-
72
- /**
73
- * Returns the admin list table instance
74
- *
75
- * @return PP_Capabilities_Roles_List_Table
76
- */
77
- public function get_roles_list_table()
78
- {
79
- if ($this->roles_list_table === null) {
80
- if (!class_exists('PP_Capabilities_Roles_List_Table')) {
81
- require_once plugin_dir_path(__FILE__) . 'class-pp-roles-list-table.php';
82
- }
83
-
84
- $this->roles_list_table = new PP_Capabilities_Roles_List_Table([
85
- 'screen' => get_current_screen()
86
- ]);
87
- }
88
-
89
- return $this->roles_list_table;
90
- }
91
-
92
- /**
93
- * Get the fields tabs to be rendered on role screen
94
- *
95
- * @param mixed $current
96
- * @param bool $role_edit whether current action is role edit
97
- * @param bool $role_copy whether current action is role copy
98
- *
99
- * @return array
100
- */
101
- public static function get_fields_tabs($current, $role_edit, $role_copy)
102
- {
103
- $fields_tabs = [
104
- 'general' => [
105
- 'label' => esc_html__('General', 'capsman-enhanced'),
106
- 'icon' => 'dashicons dashicons-admin-tools',
107
- ],
108
- 'advanced' => [
109
- 'label' => esc_html__('Advanced', 'capsman-enhanced'),
110
- 'icon' => 'dashicons dashicons-admin-generic',
111
- ],
112
- ];
113
-
114
- if ($role_edit && !$current['is_system']) {
115
- $fields_tabs['delete'] = [
116
- 'label' => esc_html__('Delete', 'capsman-enhanced'),
117
- 'icon' => 'dashicons dashicons-trash',
118
- ];
119
- }
120
-
121
- /**
122
- * Customize fields tabs presented on role screen.
123
- *
124
- * @param array $fields_tabs Existing fields tabs to display.
125
- * @param mixed $current
126
- */
127
- $fields_tabs = apply_filters('pp_roles_tabs', $fields_tabs, $current);
128
-
129
- return $fields_tabs;
130
- }
131
-
132
- /**
133
- * Get the fields to be rendered on role screen
134
- *
135
- * @param mixed $current.
136
- * @param bool $role_edit whether current action is role edit
137
- * @param bool $role_copy whether current action is role copy
138
- *
139
- * @return array
140
- */
141
- public static function get_fields($current, $role_edit, $role_copy)
142
- {
143
- $fields = [
144
- 'role_name' => [
145
- 'label' => esc_html__('Role Name', 'capsman-enhanced'),
146
- 'type' => 'text',
147
- 'value_key' => 'name',
148
- 'tab' => 'general',
149
- 'editable' => true,
150
- 'required' => true,
151
- ],
152
- 'role_slug' => [
153
- 'label' => esc_html__('Role Slug', 'capsman-enhanced'),
154
- 'description' => esc_html__('The slug is the URL-friendly version of the role. It is usually all lowercase and contains only letters, numbers and underscores.', 'capsman-enhanced'),
155
- 'type' => 'text',
156
- 'value_key' => 'role',
157
- 'tab' => 'general',
158
- 'editable' => ($role_edit) ? false : true,
159
- 'required' => false,
160
- ],
161
- 'role_level' => [
162
- 'label' => esc_html__('Role Level', 'capsman-enhanced'),
163
- 'type' => 'select',
164
- 'value_key' => '',
165
- 'tab' => 'advanced',
166
- 'editable' => true,
167
- 'options' => [
168
- '10' => '10',
169
- '9' => '9',
170
- '8' => '8',
171
- '7' => '7',
172
- '6' => '6',
173
- '5' => '5',
174
- '4' => '4',
175
- '3' => '3',
176
- '2' => '2',
177
- '1' => '1',
178
- '0' => '0',
179
- ],
180
- 'selected' => (is_array($current) && isset($current['capabilities'])) ? ak_caps2level($current['capabilities']) : '0',
181
- ],
182
- 'delete_role' => [
183
- 'label' => esc_html__('Delete role', 'capsman-enhanced'),
184
- 'description' => esc_html__('Deleting this role will completely remove it from database and is irrecoverable.', 'capsman-enhanced'),
185
- 'type' => 'button',
186
- 'value_key' => '',
187
- 'tab' => 'delete',
188
- 'editable' => true,
189
- ],
190
- ];
191
-
192
- /**
193
- * Customize fields presented on role screen.
194
- *
195
- * @param array $fields Existing fields to display.
196
- * @param mixed $current Author to be rendered.
197
- */
198
- $fields = apply_filters('pp_roles_fields', $fields, $current);
199
-
200
- return $fields;
201
- }
202
-
203
- /**
204
- * Get a rendered field partial
205
- *
206
- * @param array $args Arguments to render in the partial.
207
- */
208
- private static function get_rendered_role_partial($args)
209
- {
210
- $defaults = [
211
- 'description' => '',
212
- 'type' => 'text',
213
- 'tab' => 'general',
214
- 'editable' => true,
215
- 'required' => false,
216
- 'value' => '',
217
- 'options' => [],
218
- 'selected' => '',
219
- 'label' => '',
220
- ];
221
- $args = array_merge($defaults, $args);
222
- $key = $args['key'];
223
- $tab_class = 'pp-roles-tab-tr pp-roles-' . $args['tab'] . '-tab';
224
- $tab_style = ($args['tab'] === 'general') ? '' : 'display:none;';
225
- ?>
226
- <tr valign="top"
227
- class="<?php echo esc_attr('form-field role-' . $key . '-wrap '. $tab_class); ?>"
228
- data-tab="<?php echo esc_attr($args['tab']); ?>"
229
- style="<?php echo esc_attr($tab_style); ?>"
230
- >
231
- <th scope="row">
232
- <?php if (!empty($args['label'])) : ?>
233
- <label for="<?php echo esc_attr($key); ?>"><?php echo esc_html($args['label']); ?></label>
234
- <?php if ($args['required']) { ?>
235
- <span class="required">*</span>
236
- <?php } ?>
237
- <?php endif; ?>
238
- <?php if ($key === 'role_slug') { ?>
239
- <p id="pp-role-slug-exists" class="red-warning" style="display:none;">
240
- <?php esc_html_e('Slug already exists', 'capsman-enhanced'); ?>
241
- <span class="dashicons dashicons-warning"></span>
242
- </p>
243
- <?php } ?>
244
- </th>
245
- <td>
246
- <?php
247
- if ($args['type'] === 'select') : ?>
248
- <select name="<?php echo esc_attr($key); ?>" <?php echo ($args['required'] ? 'required="true"' : '');?>>
249
- <?php
250
- foreach ($args['options'] as $select_key => $select_label) {
251
- ?>
252
- <option value="<?php esc_attr_e($select_key); ?>"
253
- <?php selected($select_key, $args['selected']); ?>>
254
- <?php echo esc_html($select_label); ?>
255
- </option>
256
- <?php } ?>
257
- </select>
258
- <?php
259
- elseif ($args['type'] === 'button') :
260
- ?>
261
- <input type="submit"
262
- class="button-secondary pp-roles-delete-botton"
263
- name="<?php echo esc_attr($key); ?>"
264
- value="<?php echo esc_attr($args['label']); ?>"
265
- onclick="return confirm('<?php esc_attr_e('Are you sure you want to delete this role?', 'capsman-enhanced'); ?>');"
266
- />
267
- <?php if (isset($args['description'])) : ?>
268
- <p class="description" style="color: red;"><?php echo esc_html($args['description']); ?></p>
269
- <?php endif; ?>
270
- <?php else : ?>
271
- <input name="<?php echo esc_attr($key); ?>" type="<?php echo esc_attr($args['type']); ?>"
272
- value="<?php echo esc_attr($args['value']); ?>"
273
- <?php echo ($args['required'] ? 'required="true"' : '');?>
274
- <?php echo (!$args['editable'] ? 'readonly="readonly"' : ''); ?>/>
275
-
276
- <?php if (isset($args['description'])) : ?>
277
- <p class="description"><?php echo esc_html($args['description']); ?></p>
278
- <?php endif; ?>
279
- <?php endif; ?>
280
- </td>
281
- </tr>
282
- <?php
283
- }
284
-
285
- /**
286
- * Get role edit screen
287
- *
288
- */
289
- public function get_roles_edit_ui()
290
- {
291
- global $wp_roles;
292
-
293
- if (!empty($_GET) && !empty($_GET['role_action'])) {
294
- $role_action = sanitize_key($_GET['role_action']);
295
- } else {
296
- $role_action = 'new';
297
- }
298
-
299
- $default_tab = (!empty($_GET) && !empty($_GET['active_tab'])) ? sanitize_key($_GET['active_tab']) : 'general';
300
- $tab_class = 'ppc-' . $role_action;
301
- $current_role = '';
302
- $current = false;
303
- $role_edit = false;
304
- $role_copy = false;
305
-
306
- if ($role_action === 'edit' && !empty($_GET['role']) && $role_data = pp_roles_get_role_data(sanitize_key($_GET['role']))) {
307
- $current_role = sanitize_key($_GET['role']);
308
- $current = $role_data;
309
- $role_edit = true;
310
- } elseif ($role_action === 'copy' && !empty($_GET['role']) && $role_data = pp_roles_get_role_data(sanitize_key($_GET['role']))) {
311
- $current_role = sanitize_key($_GET['role']);
312
- $current = $role_data;
313
- $role_copy = true;
314
- }
315
-
316
- $fields_tabs = apply_filters('pp_roles_fields_tabs', self::get_fields_tabs($current, $role_edit, $role_copy), $current, $role_edit, $role_copy);
317
- $fields = apply_filters('pp_roles_fields', self::get_fields($current, $role_edit, $role_copy), $current, $role_edit, $role_copy);
318
-
319
- if ($role_copy) {
320
- pp_capabilities_roles()->notify->add('info', sprintf( esc_html__('%s role copied to editor. Please click the "Create Role" button to create this new role.', 'capsman-enhanced'), $current['name']));
321
- //update new name and remove slug
322
- $current['role'] = $current['role'] . '_copy';
323
- $current['name'] = $current['name'] . ' Copy';
324
- }
325
-
326
- $save_button_text = ($role_edit) ? esc_html__('Update Role', 'capsman-enhanced') : esc_html__('Create Role', 'capsman-enhanced');
327
-
328
- pp_capabilities_roles()->notify->display();
329
- ?>
330
- <div class="wrap pp-role-edit-wrap <?php echo esc_attr($tab_class); ?>">
331
- <h1>
332
- <?php
333
- if ($role_edit) {
334
- esc_html_e('Edit Role', 'capsman-enhanced');
335
- } elseif ($role_copy) {
336
- esc_html_e('Copy Role', 'capsman-enhanced');
337
- } else {
338
- esc_html_e('Create New Role', 'capsman-enhanced');
339
- }
340
- ?>
341
- <a href="<?php echo esc_url(admin_url('admin.php?page=pp-capabilities-roles')); ?>" class="page-title-action">
342
- <?php esc_html_e('All Roles', 'capsman-enhanced'); ?>
343
- </a>
344
- </h1>
345
- <div class="wp-clearfix"></div>
346
-
347
- <form method="post" action="">
348
- <input type="hidden" name="active_tab" class="ppc-roles-active-tab" value="<?php echo esc_attr($default_tab); ?>">
349
- <input type="hidden" name="role_action" value="<?php echo esc_attr($role_action); ?>">
350
- <input type="hidden" name="action" value="<?php echo ($role_action === 'edit' ? 'pp-roles-edit-role' : 'pp-roles-add-role'); ?>">
351
- <input type="hidden" class="ppc-roles-all-roles" value="<?php echo esc_attr(join(',', array_keys($wp_roles->get_names()))); ?>">
352
- <input type="hidden" name="_wpnonce"
353
- value="<?php echo esc_attr($role_action === 'edit' ? wp_create_nonce('edit-role') : wp_create_nonce('add-role') ); ?>"
354
- >
355
- <input type="hidden" name="current_role" class="ppc-roles-current-role" value="<?php echo esc_attr($current_role); ?>">
356
- <div id="poststuff">
357
- <div id="post-body" class="metabox-holder columns-2">
358
- <div id="post-body-content">
359
- <div class="ppc-roles-section postbox">
360
-
361
- <div class="inside">
362
- <div class="main">
363
-
364
- <ul class="ppc-roles-tab">
365
- <?php
366
- foreach ($fields_tabs as $key => $args) {
367
- $active_tab = ($key === $default_tab) ? ' active' : '';
368
- ?>
369
- <li class="<?php esc_attr_e($active_tab); ?>"
370
- data-tab="<?php esc_attr_e($key); ?>"
371
- >
372
- <a href="#">
373
- <span class="<?php esc_attr_e($args['icon']); ?>"></span>
374
- <span><?php esc_html_e($args['label']); ?></span>
375
- </a>
376
- </li>
377
- <?php
378
- }
379
- ?>
380
- </ul>
381
-
382
- <div class="ppc-roles-tab-content">
383
- <table class="form-table">
384
- <?php
385
- foreach ($fields as $key => $args) {
386
- $args['key'] = $key;
387
- $args['value'] = (is_array($current) && isset($current[$args['value_key']])) ? $current[$args['value_key']] : '';
388
-
389
- self::get_rendered_role_partial($args);
390
- }
391
- ?>
392
- </table>
393
- </div>
394
- <div class="clear"></div>
395
- </div>
396
- </div>
397
- </div>
398
- </div>
399
-
400
- <div id="postbox-container-1" class="postbox-container ppc-roles-sidebar">
401
- <div id="submitdiv" class="postbox">
402
- <div class="inside">
403
- <div id="minor-publishing">
404
- <div id="misc-publishing-actions">
405
- <div class="misc-pub-section misc-pub-section-last" style="margin:0;">
406
- <p>
407
- <input type="submit"
408
- value="<?php echo esc_attr($save_button_text); ?>" class="button-primary" id="publish" name="publish">
409
- </p>
410
- </div>
411
- </div>
412
-
413
-
414
- <div id="major-publishing-actions">
415
- <div id="publishing-action">
416
- <h2 class="roles-capabilities-title"><?php esc_html_e('Capabilities', 'capsman-enhanced'); ?></h2>
417
- <p class="description">
418
- <?php
419
- printf(
420
- esc_html__(
421
- 'These can be edited on the %1s Capabilities screen %2s',
422
- 'capsman-enhanced'
423
- ),
424
- '<a href="' . esc_url(add_query_arg(['page' => 'pp-capabilities'], admin_url('admin.php'))) .'">',
425
- '</a>'
426
- );
427
- ?>
428
- </p>
429
- <ul class="pp-roles-capabilities">
430
- <?php
431
- if($current && isset($current['capabilities']) && is_array($current['capabilities'])) :
432
- ksort($current['capabilities']);
433
- $sn = 0;
434
- foreach ($current['capabilities'] as $cap_name => $val) :
435
- if (0 === strpos($cap_name, 'level_')) {
436
- continue;
437
- }
438
- $sn++;
439
- $style = ($sn > 6) ? 'display:none;' : '';
440
- ?>
441
- <li style="<?php echo esc_attr($style);?>">
442
- &nbsp; <?php echo esc_html($cap_name);?>
443
- </li>
444
- <?php endforeach; ?>
445
-
446
- <?php if ($sn > 6) :?>
447
- <div class="roles-capabilities-load-more">
448
- <?php echo esc_html__('Load More', 'capsman-enhanced'); ?>
449
- </div>
450
- <div class="roles-capabilities-load-less" style="display:none;">
451
- <?php echo esc_html__('Load Less', 'capsman-enhanced'); ?>
452
- </div>
453
- <?php endif;?>
454
-
455
- <?php endif; ?>
456
- </ul>
457
- </div>
458
- <div class="clear"></div>
459
- </div>
460
- </div>
461
- </div>
462
- </div>
463
- </div>
464
- <br class="clear">
465
- </div>
466
- </div>
467
- </form>
468
- </div>
469
- <?php
470
- }
471
-
472
- /**
473
- * Display admin flash notices
474
- */
475
- public function admin_notices()
476
- {
477
- pp_capabilities_roles()->notify->display();
478
- }
479
-
480
- /**
481
- * Handle post actions
482
- */
483
- public function handle_actions()
484
- {
485
-
486
- $actions = pp_capabilities_roles()->actions;
487
-
488
- $actions->handle();
489
- }
490
-
491
- }
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Pp_Roles_Admin
4
+ {
5
+
6
+ /**
7
+ * The capability
8
+ *
9
+ * @access protected
10
+ * @var string
11
+ */
12
+ protected $capability = 'manage_options';
13
+
14
+ /**
15
+ * Roles list table instance
16
+ *
17
+ * @var null
18
+ */
19
+ protected $roles_list_table;
20
+
21
+ /**
22
+ * Initialize the class and set its properties.
23
+ *
24
+ */
25
+ public function __construct()
26
+ {
27
+ global $hook_suffix; //avoid warning outputs
28
+ if (!isset($hook_suffix)) {
29
+ $hook_suffix = '';
30
+ }
31
+
32
+ $this->roles_list_table = null;
33
+ $this->get_roles_list_table();
34
+ }
35
+
36
+ /**
37
+ * Handle post actions
38
+ */
39
+ public function handle()
40
+ {
41
+ $current_action = $this->current_action();
42
+
43
+ if (in_array($current_action, $this->actions)) {
44
+ $current_action = str_replace('pp-roles-', '', $current_action);
45
+ $current_action = str_replace('-', '_', $current_action);
46
+ $this->$current_action();
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Get the current action selected from the bulk actions dropdown.
52
+ *
53
+ * @return string|false The action name or False if no action was selected
54
+ */
55
+ protected function current_action()
56
+ {
57
+ if (isset($_REQUEST['filter_action']) && !empty($_REQUEST['filter_action'])) {
58
+ return false;
59
+ }
60
+
61
+ if (isset($_REQUEST['action']) && -1 != $_REQUEST['action']) {
62
+ return sanitize_key($_REQUEST['action']);
63
+ }
64
+
65
+ if (isset($_REQUEST['action2']) && -1 != $_REQUEST['action2']) {
66
+ return sanitize_key($_REQUEST['action2']);
67
+ }
68
+
69
+ return false;
70
+ }
71
+
72
+ /**
73
+ * Returns the admin list table instance
74
+ *
75
+ * @return PP_Capabilities_Roles_List_Table
76
+ */
77
+ public function get_roles_list_table()
78
+ {
79
+ if ($this->roles_list_table === null) {
80
+ if (!class_exists('PP_Capabilities_Roles_List_Table')) {
81
+ require_once plugin_dir_path(__FILE__) . 'class-pp-roles-list-table.php';
82
+ }
83
+
84
+ $this->roles_list_table = new PP_Capabilities_Roles_List_Table([
85
+ 'screen' => get_current_screen()
86
+ ]);
87
+ }
88
+
89
+ return $this->roles_list_table;
90
+ }
91
+
92
+ /**
93
+ * Get the fields tabs to be rendered on role screen
94
+ *
95
+ * @param mixed $current
96
+ * @param bool $role_edit whether current action is role edit
97
+ * @param bool $role_copy whether current action is role copy
98
+ *
99
+ * @return array
100
+ */
101
+ public static function get_fields_tabs($current, $role_edit, $role_copy)
102
+ {
103
+ $fields_tabs = [
104
+ 'general' => [
105
+ 'label' => esc_html__('General', 'capsman-enhanced'),
106
+ 'icon' => 'dashicons dashicons-admin-tools',
107
+ ],
108
+ 'advanced' => [
109
+ 'label' => esc_html__('Advanced', 'capsman-enhanced'),
110
+ 'icon' => 'dashicons dashicons-admin-generic',
111
+ ],
112
+ ];
113
+
114
+ if ($role_edit && !$current['is_system']) {
115
+ $fields_tabs['delete'] = [
116
+ 'label' => esc_html__('Delete', 'capsman-enhanced'),
117
+ 'icon' => 'dashicons dashicons-trash',
118
+ ];
119
+ }
120
+
121
+ /**
122
+ * Customize fields tabs presented on role screen.
123
+ *
124
+ * @param array $fields_tabs Existing fields tabs to display.
125
+ * @param mixed $current
126
+ */
127
+ $fields_tabs = apply_filters('pp_roles_tabs', $fields_tabs, $current);
128
+
129
+ return $fields_tabs;
130
+ }
131
+
132
+ /**
133
+ * Get the fields to be rendered on role screen
134
+ *
135
+ * @param mixed $current.
136
+ * @param bool $role_edit whether current action is role edit
137
+ * @param bool $role_copy whether current action is role copy
138
+ *
139
+ * @return array
140
+ */
141
+ public static function get_fields($current, $role_edit, $role_copy)
142
+ {
143
+ $fields = [
144
+ 'role_name' => [
145
+ 'label' => esc_html__('Role Name', 'capsman-enhanced'),
146
+ 'type' => 'text',
147
+ 'value_key' => 'name',
148
+ 'tab' => 'general',
149
+ 'editable' => true,
150
+ 'required' => true,
151
+ ],
152
+ 'role_slug' => [
153
+ 'label' => esc_html__('Role Slug', 'capsman-enhanced'),
154
+ 'description' => esc_html__('The "slug" is the URL-friendly version of the role. It is usually all lowercase and contains only letters, numbers and underscores.', 'capsman-enhanced'),
155
+ 'type' => 'text',
156
+ 'value_key' => 'role',
157
+ 'tab' => 'general',
158
+ 'editable' => ($role_edit) ? false : true,
159
+ 'required' => false,
160
+ ],
161
+ 'role_level' => [
162
+ 'label' => esc_html__('Role Level', 'capsman-enhanced'),
163
+ 'description' => esc_html__('Each user role has a level from 0 to 10. The Subscriber role defaults to the lowest level (0). The Administrator role defaults to level 10.', 'capsman-enhanced'),
164
+ 'type' => 'select',
165
+ 'value_key' => '',
166
+ 'tab' => 'advanced',
167
+ 'editable' => true,
168
+ 'options' => [
169
+ '10' => '10',
170
+ '9' => '9',
171
+ '8' => '8',
172
+ '7' => '7',
173
+ '6' => '6',
174
+ '5' => '5',
175
+ '4' => '4',
176
+ '3' => '3',
177
+ '2' => '2',
178
+ '1' => '1',
179
+ '0' => '0',
180
+ ],
181
+ 'selected' => (is_array($current) && isset($current['capabilities'])) ? ak_caps2level($current['capabilities']) : '0',
182
+ ],
183
+ 'delete_role' => [
184
+ 'label' => esc_html__('Delete role', 'capsman-enhanced'),
185
+ 'description' => esc_html__('Deleting this role will completely remove it from database and is irrecoverable.', 'capsman-enhanced'),
186
+ 'type' => 'button',
187
+ 'value_key' => '',
188
+ 'tab' => 'delete',
189
+ 'editable' => true,
190
+ ],
191
+ ];
192
+
193
+ /**
194
+ * Customize fields presented on role screen.
195
+ *
196
+ * @param array $fields Existing fields to display.
197
+ * @param mixed $current Author to be rendered.
198
+ */
199
+ $fields = apply_filters('pp_roles_fields', $fields, $current);
200
+
201
+ return $fields;
202
+ }
203
+
204
+ /**
205
+ * Get a rendered field partial
206
+ *
207
+ * @param array $args Arguments to render in the partial.
208
+ */
209
+ private static function get_rendered_role_partial($args)
210
+ {
211
+ $defaults = [
212
+ 'description' => '',
213
+ 'type' => 'text',
214
+ 'tab' => 'general',
215
+ 'editable' => true,
216
+ 'required' => false,
217
+ 'value' => '',
218
+ 'options' => [],
219
+ 'selected' => '',
220
+ 'label' => '',
221
+ ];
222
+ $args = array_merge($defaults, $args);
223
+ $key = $args['key'];
224
+ $tab_class = 'pp-roles-tab-tr pp-roles-' . $args['tab'] . '-tab';
225
+ $tab_style = ($args['tab'] === 'general') ? '' : 'display:none;';
226
+ ?>
227
+ <tr valign="top"
228
+ class="<?php echo esc_attr('form-field role-' . $key . '-wrap '. $tab_class); ?>"
229
+ data-tab="<?php echo esc_attr($args['tab']); ?>"
230
+ style="<?php echo esc_attr($tab_style); ?>"
231
+ >
232
+ <th scope="row">
233
+ <?php if (!empty($args['label'])) : ?>
234
+ <label for="<?php echo esc_attr($key); ?>"><?php echo esc_html($args['label']); ?></label>
235
+ <?php if ($args['required']) { ?>
236
+ <span class="required">*</span>
237
+ <?php } ?>
238
+ <?php endif; ?>
239
+ <?php if ($key === 'role_slug') { ?>
240
+ <p id="pp-role-slug-exists" class="red-warning" style="display:none;">
241
+ <?php esc_html_e('Slug already exists', 'capsman-enhanced'); ?>
242
+ <span class="dashicons dashicons-warning"></span>
243
+ </p>
244
+ <?php } ?>
245
+ </th>
246
+ <td>
247
+ <?php
248
+ if ($args['type'] === 'select') : ?>
249
+ <select name="<?php echo esc_attr($key); ?>" <?php echo ($args['required'] ? 'required="true"' : '');?>>
250
+ <?php
251
+ foreach ($args['options'] as $select_key => $select_label) {
252
+ ?>
253
+ <option value="<?php esc_attr_e($select_key); ?>"
254
+ <?php selected($select_key, $args['selected']); ?>>
255
+ <?php echo esc_html($select_label); ?>
256
+ </option>
257
+ <?php } ?>
258
+ </select>
259
+ <?php if (isset($args['description'])) : ?>
260
+ <p class="description">
261
+ <?php echo esc_html($args['description']); ?>
262
+ <?php if ($key === 'role_level') : ?>
263
+ <a href="https://publishpress.com/blog/user-role-levels/" target="blank">
264
+ <?php esc_html_e('Read more on Role Level.', 'capsman-enhanced'); ?>
265
+ </a>
266
+ <?php endif; ?>
267
+ </p>
268
+ <?php endif; ?>
269
+ <?php
270
+ elseif ($args['type'] === 'button') :
271
+ ?>
272
+ <input type="submit"
273
+ class="button-secondary pp-roles-delete-botton"
274
+ name="<?php echo esc_attr($key); ?>"
275
+ value="<?php echo esc_attr($args['label']); ?>"
276
+ onclick="return confirm('<?php esc_attr_e('Are you sure you want to delete this role?', 'capsman-enhanced'); ?>');"
277
+ />
278
+ <?php if (isset($args['description'])) : ?>
279
+ <p class="description" style="color: red;"><?php echo esc_html($args['description']); ?></p>
280
+ <?php endif; ?>
281
+ <?php else : ?>
282
+ <input name="<?php echo esc_attr($key); ?>" type="<?php echo esc_attr($args['type']); ?>"
283
+ value="<?php echo esc_attr($args['value']); ?>"
284
+ <?php echo ($args['required'] ? 'required="true"' : '');?>
285
+ <?php echo (!$args['editable'] ? 'readonly="readonly"' : ''); ?>/>
286
+
287
+ <?php if (isset($args['description'])) : ?>
288
+ <p class="description"><?php echo esc_html($args['description']); ?></p>
289
+ <?php endif; ?>
290
+ <?php endif; ?>
291
+ </td>
292
+ </tr>
293
+ <?php
294
+ }
295
+
296
+ /**
297
+ * Get role edit screen
298
+ *
299
+ */
300
+ public function get_roles_edit_ui()
301
+ {
302
+ global $wp_roles;
303
+
304
+ if (!empty($_GET) && !empty($_GET['role_action'])) {
305
+ $role_action = sanitize_key($_GET['role_action']);
306
+ } else {
307
+ $role_action = 'new';
308
+ }
309
+
310
+ $default_tab = (!empty($_GET) && !empty($_GET['active_tab'])) ? sanitize_key($_GET['active_tab']) : 'general';
311
+ $tab_class = 'ppc-' . $role_action;
312
+ $current_role = '';
313
+ $current = false;
314
+ $role_edit = false;
315
+ $role_copy = false;
316
+
317
+ if ($role_action === 'edit' && !empty($_GET['role']) && $role_data = pp_roles_get_role_data(sanitize_key($_GET['role']))) {
318
+ $current_role = sanitize_key($_GET['role']);
319
+ $current = $role_data;
320
+ $role_edit = true;
321
+ } elseif ($role_action === 'copy' && !empty($_GET['role']) && $role_data = pp_roles_get_role_data(sanitize_key($_GET['role']))) {
322
+ $current_role = sanitize_key($_GET['role']);
323
+ $current = $role_data;
324
+ $role_copy = true;
325
+ }
326
+
327
+ $fields_tabs = apply_filters('pp_roles_fields_tabs', self::get_fields_tabs($current, $role_edit, $role_copy), $current, $role_edit, $role_copy);
328
+ $fields = apply_filters('pp_roles_fields', self::get_fields($current, $role_edit, $role_copy), $current, $role_edit, $role_copy);
329
+
330
+ if ($role_copy) {
331
+ pp_capabilities_roles()->notify->add('info', sprintf( esc_html__('%s role copied to editor. Please click the "Create Role" button to create this new role.', 'capsman-enhanced'), $current['name']));
332
+ //update new name and remove slug
333
+ $current['role'] = $current['role'] . '_copy';
334
+ $current['name'] = $current['name'] . ' Copy';
335
+ }
336
+
337
+ $save_button_text = ($role_edit) ? esc_html__('Update Role', 'capsman-enhanced') : esc_html__('Create Role', 'capsman-enhanced');
338
+
339
+ pp_capabilities_roles()->notify->display();
340
+ ?>
341
+ <div class="wrap pp-role-edit-wrap <?php echo esc_attr($tab_class); ?>">
342
+ <h1>
343
+ <?php
344
+ if ($role_edit) {
345
+ esc_html_e('Edit Role', 'capsman-enhanced');
346
+ } elseif ($role_copy) {
347
+ esc_html_e('Copy Role', 'capsman-enhanced');
348
+ } else {
349
+ esc_html_e('Create New Role', 'capsman-enhanced');
350
+ }
351
+ ?>
352
+ <a href="<?php echo esc_url(admin_url('admin.php?page=pp-capabilities-roles')); ?>" class="page-title-action">
353
+ <?php esc_html_e('All Roles', 'capsman-enhanced'); ?>
354
+ </a>
355
+ </h1>
356
+ <div class="wp-clearfix"></div>
357
+
358
+ <form method="post" action="">
359
+ <input type="hidden" name="active_tab" class="ppc-roles-active-tab" value="<?php echo esc_attr($default_tab); ?>">
360
+ <input type="hidden" name="role_action" value="<?php echo esc_attr($role_action); ?>">
361
+ <input type="hidden" name="action" value="<?php echo ($role_action === 'edit' ? 'pp-roles-edit-role' : 'pp-roles-add-role'); ?>">
362
+ <input type="hidden" class="ppc-roles-all-roles" value="<?php echo esc_attr(join(',', array_keys($wp_roles->get_names()))); ?>">
363
+ <input type="hidden" name="_wpnonce"
364
+ value="<?php echo esc_attr($role_action === 'edit' ? wp_create_nonce('edit-role') : wp_create_nonce('add-role') ); ?>"
365
+ >
366
+ <input type="hidden" name="current_role" class="ppc-roles-current-role" value="<?php echo esc_attr($current_role); ?>">
367
+ <div id="poststuff">
368
+ <div id="post-body" class="metabox-holder columns-2">
369
+ <div id="post-body-content">
370
+ <div class="ppc-roles-section postbox">
371
+
372
+ <div class="inside">
373
+ <div class="main">
374
+
375
+ <ul class="ppc-roles-tab">
376
+ <?php
377
+ foreach ($fields_tabs as $key => $args) {
378
+ $active_tab = ($key === $default_tab) ? ' active' : '';
379
+ ?>
380
+ <li class="<?php esc_attr_e($active_tab); ?>"
381
+ data-tab="<?php esc_attr_e($key); ?>"
382
+ >
383
+ <a href="#">
384
+ <span class="<?php esc_attr_e($args['icon']); ?>"></span>
385
+ <span><?php esc_html_e($args['label']); ?></span>
386
+ </a>
387
+ </li>
388
+ <?php
389
+ }
390
+ ?>
391
+ </ul>
392
+
393
+ <div class="ppc-roles-tab-content">
394
+ <table class="form-table">
395
+ <?php
396
+ foreach ($fields as $key => $args) {
397
+ $args['key'] = $key;
398
+ $args['value'] = (is_array($current) && isset($current[$args['value_key']])) ? $current[$args['value_key']] : '';
399
+
400
+ self::get_rendered_role_partial($args);
401
+ }
402
+ ?>
403
+ </table>
404
+ </div>
405
+ <div class="clear"></div>
406
+ </div>
407
+ </div>
408
+ </div>
409
+ </div>
410
+
411
+ <div id="postbox-container-1" class="postbox-container ppc-roles-sidebar">
412
+ <div id="submitdiv" class="postbox">
413
+ <div class="inside">
414
+ <div id="minor-publishing">
415
+ <div id="misc-publishing-actions">
416
+ <div class="misc-pub-section misc-pub-section-last" style="margin:0;">
417
+ <p>
418
+ <input type="submit"
419
+ value="<?php echo esc_attr($save_button_text); ?>" class="button-primary" id="publish" name="publish">
420
+ </p>
421
+ </div>
422
+ </div>
423
+
424
+
425
+ <div id="major-publishing-actions">
426
+ <div id="publishing-action">
427
+ <h2 class="roles-capabilities-title"><?php esc_html_e('Capabilities', 'capsman-enhanced'); ?></h2>
428
+ <p class="description">
429
+ <?php
430
+ printf(
431
+ esc_html__(
432
+ 'These can be edited on the %1s Capabilities screen %2s',
433
+ 'capsman-enhanced'
434
+ ),
435
+ '<a href="' . esc_url(add_query_arg(['page' => 'pp-capabilities'], admin_url('admin.php'))) .'">',
436
+ '</a>'
437
+ );
438
+ ?>
439
+ </p>
440
+ <ul class="pp-roles-capabilities">
441
+ <?php
442
+ if($current && isset($current['capabilities']) && is_array($current['capabilities'])) :
443
+ ksort($current['capabilities']);
444
+ $sn = 0;
445
+ foreach ($current['capabilities'] as $cap_name => $val) :
446
+ if (0 === strpos($cap_name, 'level_')) {
447
+ continue;
448
+ }
449
+ $sn++;
450
+ $style = ($sn > 6) ? 'display:none;' : '';
451
+ ?>
452
+ <li style="<?php echo esc_attr($style);?>">
453
+ &nbsp; <?php echo esc_html($cap_name);?>
454
+ </li>
455
+ <?php endforeach; ?>
456
+
457
+ <?php if ($sn > 6) :?>
458
+ <div class="roles-capabilities-load-more">
459
+ <?php echo esc_html__('Load More', 'capsman-enhanced'); ?>
460
+ </div>
461
+ <div class="roles-capabilities-load-less" style="display:none;">
462
+ <?php echo esc_html__('Load Less', 'capsman-enhanced'); ?>
463
+ </div>
464
+ <?php endif;?>
465
+
466
+ <?php endif; ?>
467
+ </ul>
468
+ </div>
469
+ <div class="clear"></div>
470
+ </div>
471
+ </div>
472
+ </div>
473
+ </div>
474
+ </div>
475
+ <br class="clear">
476
+ </div>
477
+ </div>
478
+ </form>
479
+ </div>
480
+ <?php
481
+ }
482
+
483
+ /**
484
+ * Display admin flash notices
485
+ */
486
+ public function admin_notices()
487
+ {
488
+ pp_capabilities_roles()->notify->display();
489
+ }
490
+
491
+ /**
492
+ * Handle post actions
493
+ */
494
+ public function handle_actions()
495
+ {
496
+
497
+ $actions = pp_capabilities_roles()->actions;
498
+
499
+ $actions->handle();
500
+ }
501
+
502
+ }
includes/roles/class/class-pp-roles-list-table.php CHANGED
@@ -1,595 +1,750 @@
1
- <?php
2
-
3
- if (!class_exists('WP_List_Table')) {
4
- require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
5
- }
6
-
7
- /**
8
- * Class PP_Capabilities_Roles_List_Table
9
- */
10
- class PP_Capabilities_Roles_List_Table extends WP_List_Table
11
- {
12
-
13
- /**
14
- * The roles manager
15
- *
16
- * @var Pp_Roles_Manager
17
- */
18
- protected $manager;
19
- private $default_role = '';
20
-
21
- /**
22
- * The current view.
23
- *
24
- * @access public
25
- * @var string
26
- */
27
- public $role_view = 'all';
28
-
29
- /**
30
- * Array of role views.
31
- *
32
- * @access public
33
- * @var array
34
- */
35
- public $role_views = array();
36
-
37
- /**
38
- * Allowed role views.
39
- *
40
- * @access public
41
- * @var array
42
- */
43
- public $allowed_role_views = array();
44
-
45
- /**
46
- * PP_Capabilities_Roles_List_Table constructor.
47
- *
48
- * @param array $args
49
- */
50
- function __construct($args = [])
51
- {
52
- global $status, $page;
53
-
54
- //Set parent defaults
55
- parent::__construct([
56
- 'singular' => 'role', //singular name of the listed records
57
- 'plural' => 'roles', //plural name of the listed records
58
- 'ajax' => true //does this table support ajax?
59
- ]);
60
-
61
- $this->manager = pp_capabilities_roles()->manager;
62
-
63
- $this->default_role = get_option('default_role');
64
-
65
- // Get the role views.
66
- $this->allowed_role_views = array_keys($this->get_views());
67
-
68
- // Get the current view.
69
- if (isset($_GET['view']) && in_array(sanitize_key($_GET['view']), $this->allowed_role_views)) {
70
- $this->role_view = sanitize_key($_GET['view']);
71
- }
72
- }
73
-
74
- /**
75
- * Returns an array of views for the list table.
76
- *
77
- * @access protected
78
- * @return array
79
- */
80
- protected function get_views() {
81
-
82
- $views = array();
83
- $current = ' class="current"';
84
-
85
- $role_view_filters = [
86
- 'all' => _n_noop('All %s', 'All %s', 'capsman-enhanced'),
87
- 'mine' => _n_noop('Mine %s', 'Mine %s', 'capsman-enhanced'),
88
- 'active' => _n_noop('Has Users %s', 'Has Users %s', 'capsman-enhanced'),
89
- 'inactive' => _n_noop('No Users %s', 'No Users %s', 'capsman-enhanced'),
90
- 'editable' => _n_noop('Editable %s', 'Editable %s', 'capsman-enhanced'),
91
- 'uneditable'=> _n_noop('Uneditable %s', 'Uneditable %s', 'capsman-enhanced'),
92
- 'system' => _n_noop('System %s', 'System %s', 'capsman-enhanced'),
93
- ];
94
-
95
- foreach($role_view_filters as $view => $noop){
96
- $view_roles = $this->manager->get_roles_for_list_table($view);
97
- //add role view
98
- $this->role_views[$view] = ['roles' => $view_roles];
99
-
100
- $count = count($view_roles);
101
-
102
- // Skip any views with 0 roles.
103
- if ((int)$count === 0) {
104
- continue;
105
- }
106
-
107
- // Add the view link.
108
- $views[ $view ] = sprintf(
109
- '<a%s href="%s">%s</a>',
110
- $view === $this->role_view ? $current : '',
111
- esc_url(
112
- add_query_arg(
113
- [
114
- 'page' => 'pp-capabilities-roles',
115
- 'view' => esc_attr($view)
116
- ],
117
- admin_url('admin.php')
118
- )
119
- ),
120
- sprintf(
121
- translate_nooped_plural($noop, $count, $noop['domain']),
122
- sprintf('<span class="count">(%s)</span>', number_format_i18n($count))
123
- )
124
- );
125
- }
126
-
127
- return $views;
128
- }
129
-
130
- /**
131
- * Get a list of CSS classes for the WP_List_Table table tag.
132
- *
133
- * @return array List of CSS classes for the table tag.
134
- */
135
- protected function get_table_classes()
136
- {
137
-
138
- return parent::get_table_classes();
139
- }
140
-
141
- /**
142
- * Show single row item
143
- *
144
- * @param array $item
145
- */
146
- public function single_row($item)
147
- {
148
- $class = ['roles-tr'];
149
-
150
- echo sprintf('<tr id="%s" class="%s">', 'role-' . esc_attr(md5($item['role'])), esc_attr(implode(' ', $class)));
151
- $this->single_row_columns($item);
152
- echo '</tr>';
153
- }
154
-
155
- /**
156
- * Get list table columns
157
- *
158
- * @return array
159
- */
160
- public function get_columns()
161
- {
162
- $columns = [
163
- 'cb' => '<input type="checkbox"/>', //Render a checkbox instead of text
164
- 'name' => esc_html__('Role Name', 'capsman-enhanced'),
165
- 'role' => esc_html__('Role', 'capsman-enhanced'),
166
- 'count' => esc_html__('Users', 'capsman-enhanced'),
167
- ];
168
-
169
- return $columns;
170
- }
171
-
172
- /**
173
- * Get a list of sortable columns.
174
- *
175
- * @return array
176
- *
177
- */
178
- protected function get_sortable_columns()
179
- {
180
- $sortable_columns = [
181
- 'name' => ['name', true],
182
- 'role' => ['role', true],
183
- 'count' => ['count', true],
184
- ];
185
-
186
- return $sortable_columns;
187
- }
188
-
189
- /**
190
- * Generates and display row actions links for the list table.
191
- *
192
- * @param object $item The item being acted upon.
193
- * @param string $column_name Current column name.
194
- * @param string $primary Primary column name.
195
- *
196
- * @return string The row actions HTML, or an empty string if the current column is the primary column.
197
- */
198
- protected function handle_row_actions($item, $column_name, $primary)
199
- {
200
- static $pp_only;
201
-
202
- //Build row actions
203
- if (pp_capabilities_is_editable_role($item['role'])) {
204
- $actions = [
205
- 'capabilities' => sprintf(
206
- '<a href="%s">%s</a>',
207
- esc_url(
208
- add_query_arg(
209
- ['page' => 'pp-capabilities', 'role' => esc_attr($item['role'])],
210
- admin_url('admin.php')
211
- )
212
- ),
213
- esc_html__('Capabilities', 'capsman-enhanced')
214
- ),
215
- ];
216
-
217
- $actions['edit'] = sprintf(
218
- '<a href="%s">%s</a>',
219
- esc_url(
220
- add_query_arg(
221
- ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'edit', 'role' => esc_attr($item['role'])],
222
- admin_url('admin.php')
223
- )
224
- ),
225
- esc_html__('Edit', 'capsman-enhanced')
226
- );
227
-
228
- $actions['copy'] = sprintf(
229
- '<a href="%s">%s</a>',
230
- esc_url(
231
- add_query_arg(
232
- ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'copy', 'role' => esc_attr($item['role'])],
233
- admin_url('admin.php')
234
- )
235
- ),
236
- esc_html__('Copy', 'capsman-enhanced')
237
- );
238
-
239
- } else {
240
- $actions = [
241
- 'capabilities' => '<span class="pp-caps-action-note">' . esc_html__('(non-editable role)', 'capsman-enhanced') . '</span>',
242
- ];
243
-
244
- if (defined("PRESSPERMIT_ACTIVE")) {
245
- if (!isset($pp_only)) {
246
- $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
247
- }
248
-
249
- if (in_array($item['role'], $pp_only)) {
250
- $actions['unhide'] = sprintf(
251
- '<a href="%s" class="hide-role">%s</a>',
252
- add_query_arg([
253
- 'page' => 'pp-capabilities-roles',
254
- 'action' => 'pp-roles-unhide-role',
255
- 'role' => esc_attr($item['role']),
256
- '_wpnonce' => wp_create_nonce('bulk-roles')
257
- ],
258
- admin_url('admin.php')),
259
- esc_html__('Unhide', 'capsman-enhanced')
260
- );
261
- }
262
- }
263
- }
264
-
265
- if (!$this->manager->is_system_role($item['role']) && ($this->default_role != $item['role']) && pp_capabilities_is_editable_role($item['role'])) {
266
- //Dont these actions if it's a system role
267
- $actions = array_merge($actions, [
268
- 'delete' => sprintf(
269
- '<a href="%s" class="delete-role">%s</a>',
270
- add_query_arg([
271
- 'page' => 'pp-capabilities-roles',
272
- 'action' => 'pp-roles-delete-role',
273
- 'role' => esc_attr($item['role']),
274
- '_wpnonce' => wp_create_nonce('bulk-roles')
275
- ],
276
- admin_url('admin.php')),
277
- esc_html__('Delete', 'capsman-enhanced')
278
- ),
279
- ]);
280
-
281
- if (defined("PRESSPERMIT_ACTIVE")) {
282
- if (!isset($pp_only)) {
283
- $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
284
- }
285
-
286
- if (!in_array($item['role'], $pp_only)) {
287
- $actions['hide'] = sprintf(
288
- '<a href="%s" class="hide-role">%s</a>',
289
- add_query_arg([
290
- 'page' => 'pp-capabilities-roles',
291
- 'action' => 'pp-roles-hide-role',
292
- 'role' => esc_attr($item['role']),
293
- '_wpnonce' => wp_create_nonce('bulk-roles')
294
- ],
295
- admin_url('admin.php')),
296
- esc_html__('Hide', 'capsman-enhanced')
297
- );
298
- }
299
- }
300
- }
301
-
302
- return $column_name === $primary ? $this->row_actions($actions, false) : '';
303
- }
304
-
305
- /**
306
- * Add default
307
- *
308
- * @param object $item
309
- * @param string $column_name
310
- *
311
- * @return mixed|string|void
312
- */
313
- protected function column_default($item, $column_name)
314
- {
315
- return !empty($item[$column_name]) ? $item[$column_name] : '&mdash;';
316
- }
317
-
318
- /**
319
- * The checkbox column
320
- *
321
- * @param object $item
322
- *
323
- * @return string|void
324
- */
325
- protected function column_cb($item)
326
- {
327
- $disabled = ($this->manager->is_system_role($item['role']) || ($this->default_role == $item['role']) || !pp_capabilities_is_editable_role($item['role'])) ? ' disabled=disabled' : '';
328
- $out = sprintf('<input type="checkbox" name="%1$s[]" value="%2$s"' . $disabled . ' />', 'role', $item['role']);
329
-
330
- return $out;
331
- }
332
-
333
- /**
334
- * The role column
335
- *
336
- * @param $item
337
- *
338
- * @return string
339
- */
340
- protected function column_name($item)
341
- {
342
- $states = [];
343
- $role_states = '';
344
-
345
- // If the role is the default role.
346
- if ($item['role'] == get_option('default_role')) {
347
- $states['default'] = esc_html__('Default Role', 'capsman-enhanced');
348
- }
349
-
350
- // If the current user has this role.
351
- if (pp_roles_current_user_has_role($item['role'])) {
352
- $states['mine'] = esc_html__('Your Role', 'capsman-enhanced');
353
- }
354
-
355
- // If we have states, string them together.
356
- if (!empty($states)) {
357
-
358
- foreach ($states as $state => $label)
359
- $states[$state] = sprintf('<span class="role-state">%s</span>', $label);
360
-
361
- $role_states = '<span class="row-title-divider"> &ndash; </span>' . join(', ', $states);
362
- }
363
-
364
- if (pp_capabilities_is_editable_role($item['role'])) {
365
- $out = sprintf(
366
- '<a href="%1$s"><strong><span class="row-title">%2$s</span>%3$s</strong></a>',
367
- add_query_arg(
368
- ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'edit', 'role' => esc_attr($item['role'])],
369
- admin_url('admin.php')
370
- ),
371
- esc_html($item['name']),
372
- $role_states
373
- );
374
- } else {
375
- $out = esc_html($item['name']);
376
- }
377
-
378
- return $out;
379
- }
380
-
381
- /**
382
- * The action column
383
- *
384
- * @param $item
385
- *
386
- * @return string
387
- */
388
- protected function column_text($item)
389
- {
390
-
391
- return !empty($item['name']) ? $item['name'] : '&mdash;';
392
- }
393
-
394
- /**
395
- * The action column
396
- *
397
- * @param $item
398
- *
399
- * @return string
400
- */
401
- protected function column_count($item)
402
- {
403
- return sprintf('<a href="%s" class="">%s</a>', add_query_arg('role', esc_attr($item['role']), admin_url('users.php')), number_format_i18n($item['count']));
404
- }
405
-
406
- /**
407
- * Get the bulk actions to show in the top page dropdown
408
- *
409
- * @return array
410
- */
411
- protected function get_bulk_actions()
412
- {
413
- $actions = [
414
- 'pp-roles-delete-role' => esc_html__('Delete', 'capsman-enhanced')
415
- ];
416
-
417
- return $actions;
418
- }
419
-
420
- /**
421
- * Process bulk actions
422
- */
423
- protected function process_bulk_action()
424
- {
425
-
426
- $query_arg = '_wpnonce';
427
- $action = 'bulk-' . $this->_args['plural'];
428
- $checked = $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce(sanitize_key($_REQUEST[$query_arg]), $action) : false;
429
-
430
- if (!$checked) {
431
- return;
432
- }
433
-
434
- $current_action = $this->current_action();
435
- //Detect when a bulk action is being triggered...
436
- switch ($current_action) {
437
- case 'delete':
438
- break;
439
- default:
440
-
441
- }
442
- }
443
-
444
- /**
445
- * Determine if a given string contains a given substring.
446
- *
447
- * @param string $haystack
448
- * @param string|array $needles
449
- * @param bool $sensitive Use case sensitive search
450
- *
451
- * @return bool
452
- */
453
- public function str_contains($haystack, $needles, $sensitive = true)
454
- {
455
- foreach ((array)$needles as $needle) {
456
- $function = $sensitive ? 'mb_strpos' : 'mb_stripos';
457
- if ($needle !== '' && $function($haystack, $needle) !== false) {
458
- return true;
459
- }
460
- }
461
-
462
- return false;
463
- }
464
-
465
- /**
466
- * Displays the search box.
467
- *
468
- * @param string $text The 'submit' button label.
469
- * @param string $input_id ID attribute value for the search input field.
470
- *
471
- *
472
- */
473
- public function search_box($text, $input_id)
474
- {
475
- if (empty($_REQUEST['s']) && !$this->has_items()) {
476
- return;
477
- }
478
-
479
- $input_id = $input_id . '-search-input';
480
-
481
- if (!empty($_REQUEST['orderby'])) {
482
- echo '<input type="hidden" name="orderby" value="' . esc_attr(sanitize_text_field($_REQUEST['orderby'])) . '" />';
483
- }
484
- if (!empty($_REQUEST['order'])) {
485
- echo '<input type="hidden" name="order" value="' . esc_attr(sanitize_key($_REQUEST['order'])) . '" />';
486
- }
487
- if (!empty($_REQUEST['page'])) {
488
- echo '<input type="hidden" name="page" value="' . esc_attr(sanitize_key($_REQUEST['page'])) . '" />';
489
- }
490
- if (!empty($_REQUEST['view'])) {
491
- echo '<input type="hidden" name="view" value="' . esc_attr(sanitize_key($_REQUEST['view'])) . '" />';
492
- }
493
- ?>
494
- <p class="search-box">
495
- <label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php echo esc_html($text); ?>:</label>
496
- <input type="search" id="<?php echo esc_attr($input_id); ?>" name="s"
497
- value="<?php _admin_search_query(); ?>"/>
498
- <?php submit_button($text, '', '', false, ['id' => 'search-submit']); ?>
499
- </p>
500
- <?php
501
- }
502
-
503
- /**
504
- * Sets up the items (roles) to list.
505
- */
506
- public function prepare_items()
507
- {
508
- /**
509
- * First, lets decide how many records per page to show
510
- */
511
- $per_page = $this->get_items_per_page(str_replace('-', '_', $this->screen->id . '_per_page'), 999);
512
-
513
- /**
514
- * handle bulk actions.
515
- */
516
- $this->process_bulk_action();
517
-
518
- /**
519
- * Fetch the data
520
- */
521
- if (!empty($this->role_views[$this->role_view]['roles'])) {
522
- $data = $this->role_views[$this->role_view]['roles'];
523
- } else {
524
- $data = [];
525
- }
526
-
527
- /**
528
- * Handle search
529
- */
530
- if ((!empty($_REQUEST['s'])) && $search = sanitize_text_field($_REQUEST['s'])) {
531
- $data_filtered = [];
532
- foreach ($data as $item) {
533
- if ($this->str_contains($item['role'], $search, false) || $this->str_contains($item['name'], $search, false)) {
534
- $data_filtered[] = $item;
535
- }
536
- }
537
- $data = $data_filtered;
538
- }
539
-
540
- /**
541
- * This checks for sorting input and sorts the data in our array accordingly.
542
- */
543
- function usort_reorder($a, $b)
544
- {
545
- $orderby = (!empty($_REQUEST['orderby'])) ? sanitize_text_field($_REQUEST['orderby']) : 'role'; //If no sort, default to role
546
- $order = (!empty($_REQUEST['order'])) ? sanitize_key($_REQUEST['order']) : 'asc'; //If no order, default to asc
547
- $result = strnatcasecmp($a[$orderby], $b[$orderby]); //Determine sort order, case insensitive, natural order
548
-
549
- return ($order === 'asc') ? $result : -$result; //Send final sort direction to usort
550
- }
551
-
552
- usort($data, 'usort_reorder');
553
-
554
- /**
555
- * Pagination.
556
- */
557
- $current_page = $this->get_pagenum();
558
- $total_items = count($data);
559
-
560
-
561
- /**
562
- * The WP_List_Table class does not handle pagination for us, so we need
563
- * to ensure that the data is trimmed to only the current page. We can use
564
- * array_slice() to
565
- */
566
- $data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
567
-
568
- /**
569
- * Now we can add the data to the items property, where it can be used by the rest of the class.
570
- */
571
- $this->items = $data;
572
-
573
- /**
574
- * We also have to register our pagination options & calculations.
575
- */
576
- $this->set_pagination_args([
577
- 'total_items' => $total_items, //calculate the total number of items
578
- 'per_page' => $per_page, //determine how many items to show on a page
579
- 'total_pages' => ceil($total_items / $per_page) //calculate the total number of pages
580
- ]);
581
- }
582
-
583
- /**
584
- * Display the list table.
585
- *
586
- * @access public
587
- * @return void
588
- */
589
- public function display() {
590
-
591
- $this->views();
592
-
593
- parent::display();
594
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  }
1
+ <?php
2
+
3
+ if (!class_exists('WP_List_Table')) {
4
+ require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
5
+ }
6
+
7
+ /**
8
+ * Class PP_Capabilities_Roles_List_Table
9
+ */
10
+ class PP_Capabilities_Roles_List_Table extends WP_List_Table
11
+ {
12
+
13
+ /**
14
+ * The roles manager
15
+ *
16
+ * @var Pp_Roles_Manager
17
+ */
18
+ protected $manager;
19
+ private $default_role = '';
20
+
21
+ /**
22
+ * The current view.
23
+ *
24
+ * @access public
25
+ * @var string
26
+ */
27
+ public $role_view = 'all';
28
+
29
+ /**
30
+ * Array of role views.
31
+ *
32
+ * @access public
33
+ * @var array
34
+ */
35
+ public $role_views = array();
36
+
37
+ /**
38
+ * Allowed role views.
39
+ *
40
+ * @access public
41
+ * @var array
42
+ */
43
+ public $allowed_role_views = array();
44
+
45
+ /**
46
+ * PP_Capabilities_Roles_List_Table constructor.
47
+ *
48
+ * @param array $args
49
+ */
50
+ function __construct($args = [])
51
+ {
52
+ global $status, $page;
53
+
54
+ //Set parent defaults
55
+ parent::__construct([
56
+ 'singular' => 'role', //singular name of the listed records
57
+ 'plural' => 'roles', //plural name of the listed records
58
+ 'ajax' => true //does this table support ajax?
59
+ ]);
60
+
61
+ $this->manager = pp_capabilities_roles()->manager;
62
+
63
+ $this->default_role = get_option('default_role');
64
+
65
+ // Get the role views.
66
+ $this->allowed_role_views = array_keys($this->get_views());
67
+
68
+ // Get the current view.
69
+ if (isset($_GET['view']) && in_array(sanitize_key($_GET['view']), $this->allowed_role_views)) {
70
+ $this->role_view = sanitize_key($_GET['view']);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Returns an array of views for the list table.
76
+ *
77
+ * @access protected
78
+ * @return array
79
+ */
80
+ protected function get_views() {
81
+
82
+ $views = array();
83
+ $current = ' class="current"';
84
+
85
+ $role_view_filters = [
86
+ 'all' => _n_noop('All %s', 'All %s', 'capsman-enhanced'),
87
+ 'mine' => _n_noop('Mine %s', 'Mine %s', 'capsman-enhanced'),
88
+ 'active' => _n_noop('Has Users %s', 'Has Users %s', 'capsman-enhanced'),
89
+ 'inactive' => _n_noop('No Users %s', 'No Users %s', 'capsman-enhanced'),
90
+ 'editable' => _n_noop('Editable %s', 'Editable %s', 'capsman-enhanced'),
91
+ 'uneditable'=> _n_noop('Uneditable %s', 'Uneditable %s', 'capsman-enhanced'),
92
+ 'system' => _n_noop('System %s', 'System %s', 'capsman-enhanced'),
93
+ ];
94
+
95
+ foreach($role_view_filters as $view => $noop){
96
+ $view_roles = $this->manager->get_roles_for_list_table($view, true);
97
+ //add role view
98
+ $this->role_views[$view] = ['roles' => $view_roles];
99
+
100
+ $count = count($view_roles);
101
+
102
+ // Skip any views with 0 roles.
103
+ if ((int)$count === 0) {
104
+ continue;
105
+ }
106
+
107
+ // Add the view link.
108
+ $views[ $view ] = sprintf(
109
+ '<a%s href="%s">%s</a>',
110
+ $view === $this->role_view ? $current : '',
111
+ esc_url(
112
+ add_query_arg(
113
+ [
114
+ 'page' => 'pp-capabilities-roles',
115
+ 'view' => esc_attr($view)
116
+ ],
117
+ admin_url('admin.php')
118
+ )
119
+ ),
120
+ sprintf(
121
+ translate_nooped_plural($noop, $count, $noop['domain']),
122
+ sprintf('<span class="count">(%s)</span>', number_format_i18n($count))
123
+ )
124
+ );
125
+ }
126
+
127
+ return $views;
128
+ }
129
+
130
+ /**
131
+ * Get a list of CSS classes for the WP_List_Table table tag.
132
+ *
133
+ * @return array List of CSS classes for the table tag.
134
+ */
135
+ protected function get_table_classes()
136
+ {
137
+
138
+ return parent::get_table_classes();
139
+ }
140
+
141
+ /**
142
+ * Show single row item
143
+ *
144
+ * @param array $item
145
+ */
146
+ public function single_row($item)
147
+ {
148
+ $class = ['roles-tr'];
149
+
150
+ echo sprintf('<tr id="%s" class="%s">', 'role-' . esc_attr(md5($item['role'])), esc_attr(implode(' ', $class)));
151
+ $this->single_row_columns($item);
152
+ echo '</tr>';
153
+ }
154
+
155
+ /**
156
+ * Get list table columns
157
+ *
158
+ * @return array
159
+ */
160
+ public function get_columns()
161
+ {
162
+ /**
163
+ * Note, the table is currently using column data from
164
+ * initRolesAdmin() in manager.php to display the
165
+ * column.
166
+ */
167
+ $columns = [
168
+ 'cb' => '<input type="checkbox"/>', //Render a checkbox instead of text
169
+ 'name' => esc_html__('Role Name', 'capsman-enhanced'),
170
+ 'count' => esc_html__('Users', 'capsman-enhanced'),
171
+ 'capabilities' => esc_html__('Capabilities', 'capsman-enhanced'),
172
+ 'editor_features' => esc_html__('Editor Features', 'capsman-enhanced'),
173
+ 'admin_features' => esc_html__('Admin Features', 'capsman-enhanced'),
174
+ 'admin_menus' => esc_html__('Admin Menus', 'capsman-enhanced'),
175
+ 'nav_menus' => esc_html__('Nav Menus', 'capsman-enhanced'),
176
+ ];
177
+
178
+ return $columns;
179
+ }
180
+
181
+ /**
182
+ * Get a list of sortable columns.
183
+ *
184
+ * @return array
185
+ *
186
+ */
187
+ protected function get_sortable_columns()
188
+ {
189
+ $sortable_columns = [
190
+ 'name' => ['name', true],
191
+ 'count' => ['count', true],
192
+ ];
193
+
194
+ return $sortable_columns;
195
+ }
196
+
197
+ /**
198
+ * Generates and display row actions links for the list table.
199
+ *
200
+ * @param object $item The item being acted upon.
201
+ * @param string $column_name Current column name.
202
+ * @param string $primary Primary column name.
203
+ *
204
+ * @return string The row actions HTML, or an empty string if the current column is the primary column.
205
+ */
206
+ protected function handle_row_actions($item, $column_name, $primary)
207
+ {
208
+ static $pp_only;
209
+
210
+ //Build row actions
211
+ if (pp_capabilities_is_editable_role($item['role'])) {
212
+
213
+ $actions = [];
214
+
215
+ $actions['edit'] = sprintf(
216
+ '<a href="%s">%s</a>',
217
+ esc_url(
218
+ add_query_arg(
219
+ ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'edit', 'role' => esc_attr($item['role'])],
220
+ admin_url('admin.php')
221
+ )
222
+ ),
223
+ esc_html__('Edit', 'capsman-enhanced')
224
+ );
225
+
226
+ $actions['copy'] = sprintf(
227
+ '<a href="%s">%s</a>',
228
+ esc_url(
229
+ add_query_arg(
230
+ ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'copy', 'role' => esc_attr($item['role'])],
231
+ admin_url('admin.php')
232
+ )
233
+ ),
234
+ esc_html__('Copy', 'capsman-enhanced')
235
+ );
236
+
237
+ } else {
238
+ $actions = [
239
+ 'capabilities' => '<span class="pp-caps-action-note">' . esc_html__('(non-editable role)', 'capsman-enhanced') . '</span>',
240
+ ];
241
+
242
+ if (defined("PRESSPERMIT_ACTIVE")) {
243
+ if (!isset($pp_only)) {
244
+ $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
245
+ }
246
+
247
+ if (in_array($item['role'], $pp_only)) {
248
+ $actions['unhide'] = sprintf(
249
+ '<a href="%s" class="hide-role">%s</a>',
250
+ add_query_arg([
251
+ 'page' => 'pp-capabilities-roles',
252
+ 'action' => 'pp-roles-unhide-role',
253
+ 'role' => esc_attr($item['role']),
254
+ '_wpnonce' => wp_create_nonce('bulk-roles')
255
+ ],
256
+ admin_url('admin.php')),
257
+ esc_html__('Unhide', 'capsman-enhanced')
258
+ );
259
+ }
260
+ }
261
+ }
262
+
263
+ if (!$this->manager->is_system_role($item['role']) && ($this->default_role != $item['role']) && pp_capabilities_is_editable_role($item['role'])) {
264
+ //Dont these actions if it's a system role
265
+ $actions = array_merge($actions, [
266
+ 'delete' => sprintf(
267
+ '<a href="%s" class="delete-role">%s</a>',
268
+ add_query_arg([
269
+ 'page' => 'pp-capabilities-roles',
270
+ 'action' => 'pp-roles-delete-role',
271
+ 'role' => esc_attr($item['role']),
272
+ '_wpnonce' => wp_create_nonce('bulk-roles')
273
+ ],
274
+ admin_url('admin.php')),
275
+ esc_html__('Delete', 'capsman-enhanced')
276
+ ),
277
+ ]);
278
+
279
+ if (defined("PRESSPERMIT_ACTIVE")) {
280
+ if (!isset($pp_only)) {
281
+ $pp_only = (array) pp_capabilities_get_permissions_option('supplemental_role_defs');
282
+ }
283
+
284
+ if (!in_array($item['role'], $pp_only)) {
285
+ $actions['hide'] = sprintf(
286
+ '<a href="%s" class="hide-role">%s</a>',
287
+ add_query_arg([
288
+ 'page' => 'pp-capabilities-roles',
289
+ 'action' => 'pp-roles-hide-role',
290
+ 'role' => esc_attr($item['role']),
291
+ '_wpnonce' => wp_create_nonce('bulk-roles')
292
+ ],
293
+ admin_url('admin.php')),
294
+ esc_html__('Hide', 'capsman-enhanced')
295
+ );
296
+ }
297
+ }
298
+ }
299
+
300
+ return $column_name === $primary ? $this->row_actions($actions, false) : '';
301
+ }
302
+
303
+ /**
304
+ * Add default
305
+ *
306
+ * @param object $item
307
+ * @param string $column_name
308
+ *
309
+ * @return mixed|string|void
310
+ */
311
+ protected function column_default($item, $column_name)
312
+ {
313
+ return !empty($item[$column_name]) ? $item[$column_name] : '&mdash;';
314
+ }
315
+
316
+ /**
317
+ * The checkbox column
318
+ *
319
+ * @param object $item
320
+ *
321
+ * @return string|void
322
+ */
323
+ protected function column_cb($item)
324
+ {
325
+ $disabled = ($this->manager->is_system_role($item['role']) || ($this->default_role == $item['role']) || !pp_capabilities_is_editable_role($item['role'])) ? ' disabled=disabled' : '';
326
+ $out = sprintf('<input type="checkbox" name="%1$s[]" value="%2$s"' . $disabled . ' />', 'role', $item['role']);
327
+
328
+ return $out;
329
+ }
330
+
331
+ /**
332
+ * The role column
333
+ *
334
+ * @param $item
335
+ *
336
+ * @return string
337
+ */
338
+ protected function column_name($item)
339
+ {
340
+ $states = [];
341
+ $role_states = '';
342
+
343
+ // If the role is the default role.
344
+ if ($item['role'] == get_option('default_role')) {
345
+ $states['default'] = esc_html__('Default Role', 'capsman-enhanced');
346
+ }
347
+
348
+ // If the current user has this role.
349
+ if (pp_roles_current_user_has_role($item['role'])) {
350
+ $states['mine'] = esc_html__('Your Role', 'capsman-enhanced');
351
+ }
352
+
353
+ // If we have states, string them together.
354
+ if (!empty($states)) {
355
+
356
+ foreach ($states as $state => $label)
357
+ $states[$state] = sprintf('<span class="role-state">%s</span>', $label);
358
+
359
+ $role_states = '<span class="row-title-divider"> &ndash; </span>' . join(', ', $states);
360
+ }
361
+
362
+ if (pp_capabilities_is_editable_role($item['role'])) {
363
+ $out = sprintf(
364
+ '<a href="%1$s"><strong><span class="row-title">%2$s</span>%3$s</strong></a>',
365
+ add_query_arg(
366
+ ['page' => 'pp-capabilities-roles', 'add' => 'new_item', 'role_action' => 'edit', 'role' => esc_attr($item['role'])],
367
+ admin_url('admin.php')
368
+ ),
369
+ esc_html($item['name']),
370
+ $role_states
371
+ );
372
+ } else {
373
+ $out = esc_html($item['name']);
374
+ }
375
+
376
+ return $out;
377
+ }
378
+
379
+ /**
380
+ * The action column
381
+ *
382
+ * @param $item
383
+ *
384
+ * @return string
385
+ */
386
+ protected function column_text($item)
387
+ {
388
+
389
+ return !empty($item['name']) ? $item['name'] : '&mdash;';
390
+ }
391
+
392
+ /**
393
+ * The action column
394
+ *
395
+ * @param $item
396
+ *
397
+ * @return string
398
+ */
399
+ protected function column_capabilities($item)
400
+ {
401
+
402
+ return sprintf(
403
+ '<a href="%s">%s</a>',
404
+ esc_url(
405
+ add_query_arg(
406
+ [
407
+ 'page' => 'pp-capabilities',
408
+ 'role' => esc_attr($item['role'])
409
+ ],
410
+ admin_url('admin.php')
411
+ )
412
+ ),
413
+ number_format_i18n(count((array)$item['capabilities']))
414
+ );
415
+ }
416
+
417
+ /**
418
+ * The action column
419
+ *
420
+ * @param $item
421
+ *
422
+ * @return string
423
+ */
424
+ protected function column_editor_features($item)
425
+ {
426
+ $role = $item['role'];
427
+ $def_post_types = array_unique(apply_filters('pp_capabilities_feature_post_types', ['post', 'page']));
428
+ $disabled_items = [];
429
+ foreach ($def_post_types as $type_name) {
430
+ $classic_disabled = get_option("capsman_feature_restrict_classic_{$type_name}", []);
431
+ $gutenberg_disabled = get_option("capsman_feature_restrict_{$type_name}", []);
432
+ if (!empty($classic_disabled[$role])) {
433
+ $disabled_items = array_merge($disabled_items, (array) $classic_disabled[$role]);
434
+ }
435
+ if (!empty($gutenberg_disabled[$role])) {
436
+ $disabled_items = array_merge($disabled_items, (array) $gutenberg_disabled[$role]);
437
+ }
438
+ }
439
+ $disabled_items = array_filter($disabled_items);
440
+
441
+ return sprintf(
442
+ '<a href="%s">%s</a>',
443
+ esc_url(
444
+ add_query_arg(
445
+ [
446
+ 'page' => 'pp-capabilities-editor-features',
447
+ 'role' => esc_attr($item['role'])
448
+ ],
449
+ admin_url('admin.php')
450
+ )
451
+ ),
452
+ number_format_i18n(count($disabled_items))
453
+ );
454
+ }
455
+
456
+ /**
457
+ * The action column
458
+ *
459
+ * @param $item
460
+ *
461
+ * @return string
462
+ */
463
+ protected function column_admin_features($item)
464
+ {
465
+ $role = $item['role'];
466
+ $disabled_items = !empty(get_option('capsman_disabled_admin_features')) ? (array)get_option('capsman_disabled_admin_features') : [];
467
+ $disabled_items = array_key_exists($role, $disabled_items) ? (array)$disabled_items[$role] : [];
468
+ $disabled_items = array_filter($disabled_items);
469
+ return sprintf(
470
+ '<a href="%s">%s</a>',
471
+ esc_url(
472
+ add_query_arg(
473
+ [
474
+ 'page' => 'pp-capabilities-admin-features',
475
+ 'role' => esc_attr($item['role'])
476
+ ],
477
+ admin_url('admin.php')
478
+ )
479
+ ),
480
+ number_format_i18n(count($disabled_items))
481
+ );
482
+ }
483
+
484
+ /**
485
+ * The action column
486
+ *
487
+ * @param $item
488
+ *
489
+ * @return string
490
+ */
491
+ protected function column_admin_menus($item)
492
+ {
493
+ $role = $item['role'];
494
+
495
+ $admin_menu_option = !empty(get_option('capsman_admin_menus')) ? get_option('capsman_admin_menus') : [];
496
+ $admin_menu_option = array_key_exists($role, $admin_menu_option) ? (array)$admin_menu_option[$role] : [];
497
+
498
+ $admin_child_menu_option = !empty(get_option('capsman_admin_child_menus')) ? get_option('capsman_admin_child_menus') : [];
499
+ $admin_child_menu_option = array_key_exists($role, $admin_child_menu_option) ? (array)$admin_child_menu_option[$role] : [];
500
+
501
+ $disabled_items = array_filter(array_merge($admin_menu_option, $admin_child_menu_option));
502
+
503
+ return sprintf(
504
+ '<a href="%s">%s</a>',
505
+ esc_url(
506
+ add_query_arg(
507
+ [
508
+ 'page' => 'pp-capabilities-admin-menus',
509
+ 'role' => esc_attr($item['role'])
510
+ ],
511
+ admin_url('admin.php')
512
+ )
513
+ ),
514
+ number_format_i18n(count($disabled_items))
515
+ );
516
+ }
517
+
518
+ /**
519
+ * The action column
520
+ *
521
+ * @param $item
522
+ *
523
+ * @return string
524
+ */
525
+ protected function column_nav_menus($item)
526
+ {
527
+ $role = $item['role'];
528
+
529
+ $nav_menu_item_option = !empty(get_option('capsman_nav_item_menus')) ? get_option('capsman_nav_item_menus') : [];
530
+ $nav_menu_item_option = array_key_exists($role, $nav_menu_item_option) ? (array)$nav_menu_item_option[$role] : [];
531
+
532
+ $disabled_items = array_filter($nav_menu_item_option);
533
+
534
+ return sprintf(
535
+ '<a href="%s">%s</a>',
536
+ esc_url(
537
+ add_query_arg(
538
+ [
539
+ 'page' => 'pp-capabilities-nav-menus',
540
+ 'role' => esc_attr($item['role'])
541
+ ],
542
+ admin_url('admin.php')
543
+ )
544
+ ),
545
+ number_format_i18n(count($disabled_items))
546
+ );
547
+ }
548
+
549
+ /**
550
+ * The action column
551
+ *
552
+ * @param $item
553
+ *
554
+ * @return string
555
+ */
556
+ protected function column_count($item)
557
+ {
558
+ return sprintf('<a href="%s" class="">%s</a>', add_query_arg('role', esc_attr($item['role']), admin_url('users.php')), number_format_i18n($item['count']));
559
+ }
560
+
561
+ /**
562
+ * Get the bulk actions to show in the top page dropdown
563
+ *
564
+ * @return array
565
+ */
566
+ protected function get_bulk_actions()
567
+ {
568
+ $actions = [
569
+ 'pp-roles-delete-role' => esc_html__('Delete', 'capsman-enhanced')
570
+ ];
571
+
572
+ return $actions;
573
+ }
574
+
575
+ /**
576
+ * Process bulk actions
577
+ */
578
+ protected function process_bulk_action()
579
+ {
580
+
581
+ $query_arg = '_wpnonce';
582
+ $action = 'bulk-' . $this->_args['plural'];
583
+ $checked = $result = isset($_REQUEST[$query_arg]) ? wp_verify_nonce(sanitize_key($_REQUEST[$query_arg]), $action) : false;
584
+
585
+ if (!$checked) {
586
+ return;
587
+ }
588
+
589
+ $current_action = $this->current_action();
590
+ //Detect when a bulk action is being triggered...
591
+ switch ($current_action) {
592
+ case 'delete':
593
+ break;
594
+ default:
595
+
596
+ }
597
+ }
598
+
599
+ /**
600
+ * Determine if a given string contains a given substring.
601
+ *
602
+ * @param string $haystack
603
+ * @param string|array $needles
604
+ * @param bool $sensitive Use case sensitive search
605
+ *
606
+ * @return bool
607
+ */
608
+ public function str_contains($haystack, $needles, $sensitive = true)
609
+ {
610
+ foreach ((array)$needles as $needle) {
611
+ $function = $sensitive ? 'mb_strpos' : 'mb_stripos';
612
+ if ($needle !== '' && $function($haystack, $needle) !== false) {
613
+ return true;
614
+ }
615
+ }
616
+
617
+ return false;
618
+ }
619
+
620
+ /**
621
+ * Displays the search box.
622
+ *
623
+ * @param string $text The 'submit' button label.
624
+ * @param string $input_id ID attribute value for the search input field.
625
+ *
626
+ *
627
+ */
628
+ public function search_box($text, $input_id)
629
+ {
630
+ if (empty($_REQUEST['s']) && !$this->has_items()) {
631
+ return;
632
+ }
633
+
634
+ $input_id = $input_id . '-search-input';
635
+
636
+ if (!empty($_REQUEST['orderby'])) {
637
+ echo '<input type="hidden" name="orderby" value="' . esc_attr(sanitize_text_field($_REQUEST['orderby'])) . '" />';
638
+ }
639
+ if (!empty($_REQUEST['order'])) {
640
+ echo '<input type="hidden" name="order" value="' . esc_attr(sanitize_key($_REQUEST['order'])) . '" />';
641
+ }
642
+ if (!empty($_REQUEST['page'])) {
643
+ echo '<input type="hidden" name="page" value="' . esc_attr(sanitize_key($_REQUEST['page'])) . '" />';
644
+ }
645
+ if (!empty($_REQUEST['view'])) {
646
+ echo '<input type="hidden" name="view" value="' . esc_attr(sanitize_key($_REQUEST['view'])) . '" />';
647
+ }
648
+ ?>
649
+ <p class="search-box">
650
+ <label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php echo esc_html($text); ?>:</label>
651
+ <input type="search" id="<?php echo esc_attr($input_id); ?>" name="s"
652
+ value="<?php _admin_search_query(); ?>"/>
653
+ <?php submit_button($text, '', '', false, ['id' => 'search-submit']); ?>
654
+ </p>
655
+ <?php
656
+ }
657
+
658
+ /**
659
+ * Sets up the items (roles) to list.
660
+ */
661
+ public function prepare_items()
662
+ {
663
+ /**
664
+ * First, lets decide how many records per page to show
665
+ */
666
+ $per_page = $this->get_items_per_page(str_replace('-', '_', $this->screen->id . '_per_page'), 999);
667
+
668
+ /**
669
+ * handle bulk actions.
670
+ */
671
+ $this->process_bulk_action();
672
+
673
+ /**
674
+ * Fetch the data
675
+ */
676
+ if (!empty($this->role_views[$this->role_view]['roles'])) {
677
+ $data = $this->role_views[$this->role_view]['roles'];
678
+ } else {
679
+ $data = [];
680
+ }
681
+
682
+ /**
683
+ * Handle search
684
+ */
685
+ if ((!empty($_REQUEST['s'])) && $search = sanitize_text_field($_REQUEST['s'])) {
686
+ $data_filtered = [];
687
+ foreach ($data as $item) {
688
+ if ($this->str_contains($item['role'], $search, false) || $this->str_contains($item['name'], $search, false)) {
689
+ $data_filtered[] = $item;
690
+ }
691
+ }
692
+ $data = $data_filtered;
693
+ }
694
+
695
+ /**
696
+ * This checks for sorting input and sorts the data in our array accordingly.
697
+ */
698
+ function usort_reorder($a, $b)
699
+ {
700
+ $orderby = (!empty($_REQUEST['orderby'])) ? sanitize_text_field($_REQUEST['orderby']) : 'role'; //If no sort, default to role
701
+ $order = (!empty($_REQUEST['order'])) ? sanitize_key($_REQUEST['order']) : 'asc'; //If no order, default to asc
702
+ $result = strnatcasecmp($a[$orderby], $b[$orderby]); //Determine sort order, case insensitive, natural order
703
+
704
+ return ($order === 'asc') ? $result : -$result; //Send final sort direction to usort
705
+ }
706
+
707
+ usort($data, 'usort_reorder');
708
+
709
+ /**
710
+ * Pagination.
711
+ */
712
+ $current_page = $this->get_pagenum();
713
+ $total_items = count($data);
714
+
715
+
716
+ /**
717
+ * The WP_List_Table class does not handle pagination for us, so we need
718
+ * to ensure that the data is trimmed to only the current page. We can use
719
+ * array_slice() to
720
+ */
721
+ $data = array_slice($data, (($current_page - 1) * $per_page), $per_page);
722
+
723
+ /**
724
+ * Now we can add the data to the items property, where it can be used by the rest of the class.
725
+ */
726
+ $this->items = $data;
727
+
728
+ /**
729
+ * We also have to register our pagination options & calculations.
730
+ */
731
+ $this->set_pagination_args([
732
+ 'total_items' => $total_items, //calculate the total number of items
733
+ 'per_page' => $per_page, //determine how many items to show on a page
734
+ 'total_pages' => ceil($total_items / $per_page) //calculate the total number of pages
735
+ ]);
736
+ }
737
+
738
+ /**
739
+ * Display the list table.
740
+ *
741
+ * @access public
742
+ * @return void
743
+ */
744
+ public function display() {
745
+
746
+ $this->views();
747
+
748
+ parent::display();
749
+ }
750
  }
includes/roles/class/class-pp-roles-loader.php CHANGED
@@ -1,156 +1,156 @@
1
- <?php
2
-
3
- class Pp_Roles_Loader
4
- {
5
-
6
- /**
7
- * The array of actions registered with WordPress.
8
- *
9
- * @access protected
10
- * @var array $actions The actions registered with WordPress to fire when the plugin loads.
11
- */
12
- protected $actions;
13
-
14
- /**
15
- * The array of filters registered with WordPress.
16
- *
17
- * @access protected
18
- * @var array $filters The filters registered with WordPress to fire when the plugin loads.
19
- */
20
- protected $filters;
21
-
22
- /**
23
- * All instances registered in the Loader
24
- *
25
- * @var array
26
- */
27
- protected $instances;
28
-
29
- /**
30
- * Initialize the collections used to maintain the actions and filters.
31
- *
32
- */
33
- public function __construct()
34
- {
35
-
36
- $this->actions = [];
37
- $this->filters = [];
38
- $this->instances = [];
39
-
40
- }
41
-
42
- /**
43
- * Gets the value of an instance registered in the loader
44
- *
45
- * @param $key
46
- *
47
- * @return mixed|null
48
- */
49
- public function get($key)
50
- {
51
- return isset($this->instances[$key]) ? $this->instances[$key] : null;
52
- }
53
-
54
- /**
55
- * Sets the value of a instance registered in the loader
56
- *
57
- * @param $key
58
- * @param $value
59
- */
60
- public function set($key, $value)
61
- {
62
- if (is_string($key)) {
63
- $this->instances[$key] = $value;
64
- }
65
-
66
- }
67
-
68
- /**
69
- * Add a new action to the collection to be registered with WordPress.
70
- *
71
- * @param string $hook The name of the WordPress action that is being registered.
72
- * @param object $component A reference to the instance of the object on which the action is defined.
73
- * @param string $callback The name of the function definition on the $component.
74
- * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
75
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default
76
- * is 1.
77
- *
78
- */
79
- public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1)
80
- {
81
- $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
82
- }
83
-
84
- /**
85
- * Add a new filter to the collection to be registered with WordPress.
86
- *
87
- * @param string $hook The name of the WordPress filter that is being registered.
88
- * @param object $component A reference to the instance of the object on which the filter is defined.
89
- * @param string $callback The name of the function definition on the $component.
90
- * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
91
- * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default
92
- * is 1
93
- *
94
- */
95
- public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
96
- {
97
- $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
98
- }
99
-
100
- /**
101
- * A utility function that is used to register the actions and hooks into a single
102
- * collection.
103
- *
104
- * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
105
- * @param string $hook The name of the WordPress filter that is being registered.
106
- * @param object $component A reference to the instance of the object on which the filter is defined.
107
- * @param string $callback The name of the function definition on the $component.
108
- * @param int $priority The priority at which the function should be fired.
109
- * @param int $accepted_args The number of arguments that should be passed to the $callback.
110
- *
111
- * @return array The collection of actions and filters registered with WordPress.
112
- * @access private
113
- */
114
- private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
115
- {
116
-
117
- $hooks[] = [
118
- 'hook' => $hook,
119
- 'component' => $component,
120
- 'callback' => $callback,
121
- 'priority' => $priority,
122
- 'accepted_args' => $accepted_args
123
- ];
124
-
125
- return $hooks;
126
-
127
- }
128
-
129
- /**
130
- * Register the filters and actions with WordPress.
131
- *
132
- */
133
- public function run()
134
- {
135
-
136
- foreach ($this->filters as $hook) {
137
- add_filter(
138
- $hook['hook'],
139
- [$hook['component'], $hook['callback']],
140
- $hook['priority'],
141
- $hook['accepted_args']
142
- );
143
- }
144
-
145
- foreach ($this->actions as $hook) {
146
- add_action(
147
- $hook['hook'],
148
- [$hook['component'], $hook['callback']],
149
- $hook['priority'],
150
- $hook['accepted_args']
151
- );
152
- }
153
-
154
- }
155
-
156
- }
1
+ <?php
2
+
3
+ class Pp_Roles_Loader
4
+ {
5
+
6
+ /**
7
+ * The array of actions registered with WordPress.
8
+ *
9
+ * @access protected
10
+ * @var array $actions The actions registered with WordPress to fire when the plugin loads.
11
+ */
12
+ protected $actions;
13
+
14
+ /**
15
+ * The array of filters registered with WordPress.
16
+ *
17
+ * @access protected
18
+ * @var array $filters The filters registered with WordPress to fire when the plugin loads.
19
+ */
20
+ protected $filters;
21
+
22
+ /**
23
+ * All instances registered in the Loader
24
+ *
25
+ * @var array
26
+ */
27
+ protected $instances;
28
+
29
+ /**
30
+ * Initialize the collections used to maintain the actions and filters.
31
+ *
32
+ */
33
+ public function __construct()
34
+ {
35
+
36
+ $this->actions = [];
37
+ $this->filters = [];
38
+ $this->instances = [];
39
+
40
+ }
41
+
42
+ /**
43
+ * Gets the value of an instance registered in the loader
44
+ *
45
+ * @param $key
46
+ *
47
+ * @return mixed|null
48
+ */
49
+ public function get($key)
50
+ {
51
+ return isset($this->instances[$key]) ? $this->instances[$key] : null;
52
+ }
53
+
54
+ /**
55
+ * Sets the value of a instance registered in the loader
56
+ *
57
+ * @param $key
58
+ * @param $value
59
+ */
60
+ public function set($key, $value)
61
+ {
62
+ if (is_string($key)) {
63
+ $this->instances[$key] = $value;
64
+ }
65
+
66
+ }
67
+
68
+ /**
69
+ * Add a new action to the collection to be registered with WordPress.
70
+ *
71
+ * @param string $hook The name of the WordPress action that is being registered.
72
+ * @param object $component A reference to the instance of the object on which the action is defined.
73
+ * @param string $callback The name of the function definition on the $component.
74
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
75
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default
76
+ * is 1.
77
+ *
78
+ */
79
+ public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1)
80
+ {
81
+ $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
82
+ }
83
+
84
+ /**
85
+ * Add a new filter to the collection to be registered with WordPress.
86
+ *
87
+ * @param string $hook The name of the WordPress filter that is being registered.
88
+ * @param object $component A reference to the instance of the object on which the filter is defined.
89
+ * @param string $callback The name of the function definition on the $component.
90
+ * @param int $priority Optional. The priority at which the function should be fired. Default is 10.
91
+ * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default
92
+ * is 1
93
+ *
94
+ */
95
+ public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1)
96
+ {
97
+ $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
98
+ }
99
+
100
+ /**
101
+ * A utility function that is used to register the actions and hooks into a single
102
+ * collection.
103
+ *
104
+ * @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
105
+ * @param string $hook The name of the WordPress filter that is being registered.
106
+ * @param object $component A reference to the instance of the object on which the filter is defined.
107
+ * @param string $callback The name of the function definition on the $component.
108
+ * @param int $priority The priority at which the function should be fired.
109
+ * @param int $accepted_args The number of arguments that should be passed to the $callback.
110
+ *
111
+ * @return array The collection of actions and filters registered with WordPress.
112
+ * @access private
113
+ */
114
+ private function add($hooks, $hook, $component, $callback, $priority, $accepted_args)
115
+ {
116
+
117
+ $hooks[] = [
118
+ 'hook' => $hook,
119
+ 'component' => $component,
120
+ 'callback' => $callback,
121
+ 'priority' => $priority,
122
+ 'accepted_args' => $accepted_args
123
+ ];
124
+
125
+ return $hooks;
126
+
127
+ }
128
+
129
+ /**
130
+ * Register the filters and actions with WordPress.
131
+ *
132
+ */
133
+ public function run()
134
+ {
135
+
136
+ foreach ($this->filters as $hook) {
137
+ add_filter(
138
+ $hook['hook'],
139
+ [$hook['component'], $hook['callback']],
140
+ $hook['priority'],
141
+ $hook['accepted_args']
142
+ );
143
+ }
144
+
145
+ foreach ($this->actions as $hook) {
146
+ add_action(
147
+ $hook['hook'],
148
+ [$hook['component'], $hook['callback']],
149
+ $hook['priority'],
150
+ $hook['accepted_args']
151
+ );
152
+ }
153
+
154
+ }
155
+
156
+ }
includes/roles/class/class-pp-roles-manager.php CHANGED
@@ -1,232 +1,232 @@
1
- <?php
2
-
3
- class Pp_Roles_Manager
4
- {
5
-
6
- /**
7
- * Pp_Roles_Manager constructor.
8
- */
9
- public function __construct()
10
- {
11
-
12
- }
13
-
14
- /**
15
- * Returns an array of all the available roles.
16
- * This method is used to show the roles list table.
17
- *
18
- * @param $view string
19
- * @param $capabilities bool whether to add capabilities to result or not
20
- *
21
- * @return array[]
22
- */
23
- public function get_roles_for_list_table($view = 'all', $capabilities = false)
24
- {
25
- global $wp_roles;
26
-
27
- $roles = wp_roles()->roles;
28
- $current_user = wp_get_current_user();
29
- $editable = function_exists('get_editable_roles') ?
30
- array_keys(get_editable_roles()) :
31
- array_keys(apply_filters('editable_roles', $roles));
32
- $count = count_users();
33
- $res = [];
34
-
35
- foreach ($roles as $role => $detail) {
36
-
37
- //mine role filter
38
- if ($view === 'mine' && !in_array($role, $current_user->roles)) {
39
- continue;
40
- //active role filter
41
- } elseif ($view === 'active'
42
- && (!isset($count['avail_roles'][$role])
43
- || (isset($count['avail_roles'][$role]) && (int)$count['avail_roles'][$role] === 0))
44
- ) {
45
- continue;
46
- //inactive role filter
47
- } elseif ($view === 'inactive'
48
- && (isset($count['avail_roles'][$role])
49
- && (isset($count['avail_roles'][$role]) && (int)$count['avail_roles'][$role] > 0))
50
- ) {
51
- continue;
52
- //editable role filter
53
- } elseif ($view === 'editable' && !in_array($role, $editable)) {
54
- continue;
55
- //uneditable role filter
56
- } elseif ($view === 'uneditable' && in_array($role, $editable)) {
57
- continue;
58
- //system role filter
59
- } elseif ($view === 'system' && !$this->is_system_role($role)) {
60
- continue;
61
- }
62
-
63
- $res[] = [
64
- 'role' => $role,
65
- 'name' => $detail['name'],
66
- 'count' => isset($count['avail_roles'][$role]) ? $count['avail_roles'][$role] : 0,
67
- 'is_system' => $this->is_system_role($role),
68
- 'capabilities' => ($capabilities) ? $detail['capabilities'] : [],
69
- ];
70
- }
71
-
72
- return $res;
73
- }
74
-
75
- /**
76
- * Array containing all default wordpress roles
77
- *
78
- * @return array
79
- */
80
- public function get_system_roles()
81
- {
82
-
83
- $roles = [
84
- 'administrator',
85
- 'editor',
86
- 'author',
87
- 'contributor',
88
- 'subscriber',
89
- 'revisor'
90
- ];
91
-
92
- $roles = apply_filters('pp-roles-get-system-roles', $roles);
93
-
94
- return $roles;
95
- }
96
-
97
- /**
98
- * Checks if the given role is a system role
99
- *
100
- * @param $role
101
- *
102
- * @return bool
103
- */
104
- public function is_system_role($role)
105
- {
106
-
107
- $is = in_array($role, $this->get_system_roles());
108
-
109
- $is = apply_filters('pp-roles-is-system-role', $is, $role);
110
-
111
- return $is;
112
- }
113
-
114
- /**
115
- * Checks if he provided role exist
116
- *
117
- * @param $role
118
- *
119
- * @return bool
120
- */
121
- public function is_role($role)
122
- {
123
- return wp_roles()->is_role($role);
124
- }
125
-
126
- /**
127
- * Get role object from role
128
- *
129
- * @param $role
130
- *
131
- * @return WP_Role|null
132
- */
133
- public function get_role($role)
134
- {
135
- return wp_roles()->get_role($role);
136
- }
137
-
138
- /**
139
- * Get role name string form a role
140
- *
141
- * @param $role
142
- *
143
- * @return string
144
- */
145
- public function get_role_name($role)
146
- {
147
- if ($this->is_role($role)) {
148
- return wp_roles()->role_names[$role];
149
- }
150
-
151
- return $role;
152
- }
153
-
154
- /**
155
- * Add role to the system
156
- *
157
- * @param $role
158
- * @param $name
159
- *
160
- * @return WP_Role|null
161
- */
162
- public function add_role($role, $name)
163
- {
164
- $result = add_role($role, $name);
165
-
166
- return $result;
167
- }
168
-
169
- /**
170
- * Deletes a role from the system
171
- *
172
- * @param $role
173
- *
174
- * @return bool
175
- */
176
- public function delete_role($role, $args = [])
177
- {
178
- global $wpdb, $wp_roles;
179
-
180
- $default = get_option('default_role');
181
-
182
- if ($default == $role) {
183
- return false;
184
- }
185
-
186
- $like = '%' . $wpdb->esc_like( $role ) . '%';
187
-
188
- $users = $wpdb->get_results($wpdb->prepare(
189
- "SELECT ID FROM $wpdb->usermeta INNER JOIN $wpdb->users "
190
- . "ON $wpdb->usermeta.user_id = $wpdb->users.ID "
191
- . "WHERE meta_key='{$wpdb->prefix}capabilities' AND meta_value LIKE %s",
192
-
193
- $like
194
- )
195
- );
196
-
197
- // Array of all roles except the one being deleted, for use below
198
- $role_names = array_diff_key( $wp_roles->role_names, [$role => true] );
199
-
200
- $count = 0;
201
- foreach ( $users as $u ) {
202
- $skip_role_set = false;
203
-
204
- $user = new WP_User($u->ID);
205
- if ( $user->has_cap($role) ) { // Check again the user has the deleting role
206
- // Role may have been assigned supplementally. Don't move a user to default role if they still have one or more roles following the deletion.
207
- foreach( array_keys($role_names) as $_role_name ) {
208
- if ( $user->has_cap($_role_name) ) {
209
- $skip_role_set = true;
210
- break;
211
- }
212
- }
213
-
214
- if ( ! $skip_role_set ) {
215
- $user->set_role($default);
216
- $count++;
217
- }
218
- }
219
- }
220
-
221
- remove_role($role);
222
-
223
- if ( $customized_roles = get_option( 'pp_customized_roles' ) ) {
224
- if ( isset( $customized_roles[$role] ) ) {
225
- unset( $customized_roles[$role] );
226
- update_option( 'pp_customized_roles', $customized_roles );
227
- }
228
- }
229
-
230
- return $count;
231
- }
232
- }
1
+ <?php
2
+
3
+ class Pp_Roles_Manager
4
+ {
5
+
6
+ /**
7
+ * Pp_Roles_Manager constructor.
8
+ */
9
+ public function __construct()
10
+ {
11
+
12
+ }
13
+
14
+ /**
15
+ * Returns an array of all the available roles.
16
+ * This method is used to show the roles list table.
17
+ *
18
+ * @param $view string
19
+ * @param $capabilities bool whether to add capabilities to result or not
20
+ *
21
+ * @return array[]
22
+ */
23
+ public function get_roles_for_list_table($view = 'all', $capabilities = false)
24
+ {
25
+ global $wp_roles;
26
+
27
+ $roles = wp_roles()->roles;
28
+ $current_user = wp_get_current_user();
29
+ $editable = function_exists('get_editable_roles') ?
30
+ array_keys(get_editable_roles()) :
31
+ array_keys(apply_filters('editable_roles', $roles));
32
+ $count = count_users();
33
+ $res = [];
34
+
35
+ foreach ($roles as $role => $detail) {
36
+
37
+ //mine role filter
38
+ if ($view === 'mine' && !in_array($role, $current_user->roles)) {
39
+ continue;
40
+ //active role filter
41
+ } elseif ($view === 'active'
42
+ && (!isset($count['avail_roles'][$role])
43
+ || (isset($count['avail_roles'][$role]) && (int)$count['avail_roles'][$role] === 0))
44
+ ) {
45
+ continue;
46
+ //inactive role filter
47
+ } elseif ($view === 'inactive'
48
+ && (isset($count['avail_roles'][$role])
49
+ && (isset($count['avail_roles'][$role]) && (int)$count['avail_roles'][$role] > 0))
50
+ ) {
51
+ continue;
52
+ //editable role filter
53
+ } elseif ($view === 'editable' && !in_array($role, $editable)) {
54
+ continue;
55
+ //uneditable role filter
56
+ } elseif ($view === 'uneditable' && in_array($role, $editable)) {
57
+ continue;
58
+ //system role filter
59
+ } elseif ($view === 'system' && !$this->is_system_role($role)) {
60
+ continue;
61
+ }
62
+
63
+ $res[] = [
64
+ 'role' => $role,
65
+ 'name' => $detail['name'],
66
+ 'count' => isset($count['avail_roles'][$role]) ? $count['avail_roles'][$role] : 0,
67
+ 'is_system' => $this->is_system_role($role),
68
+ 'capabilities' => ($capabilities) ? $detail['capabilities'] : [],
69
+ ];
70
+ }
71
+
72
+ return $res;
73
+ }
74
+
75
+ /**
76
+ * Array containing all default wordpress roles
77
+ *
78
+ * @return array
79
+ */
80
+ public function get_system_roles()
81
+ {
82
+
83
+ $roles = [
84
+ 'administrator',
85
+ 'editor',
86
+ 'author',
87
+ 'contributor',
88
+ 'subscriber',
89
+ 'revisor'
90
+ ];
91
+
92
+ $roles = apply_filters('pp-roles-get-system-roles', $roles);
93
+
94
+ return $roles;
95
+ }
96
+
97
+ /**
98
+ * Checks if the given role is a system role
99
+ *
100
+ * @param $role
101
+ *
102
+ * @return bool
103
+ */
104
+ public function is_system_role($role)
105
+ {
106
+
107
+ $is = in_array($role, $this->get_system_roles());
108
+
109
+ $is = apply_filters('pp-roles-is-system-role', $is, $role);
110
+
111
+ return $is;
112
+ }
113
+
114
+ /**
115
+ * Checks if he provided role exist
116
+ *
117
+ * @param $role
118
+ *
119
+ * @return bool
120
+ */
121
+ public function is_role($role)
122
+ {
123
+ return wp_roles()->is_role($role);
124
+ }
125
+
126
+ /**
127
+ * Get role object from role
128
+ *
129
+ * @param $role
130
+ *
131
+ * @return WP_Role|null
132
+ */
133
+ public function get_role($role)
134
+ {
135
+ return wp_roles()->get_role($role);
136
+ }
137
+
138
+ /**
139
+ * Get role name string form a role
140
+ *
141
+ * @param $role
142
+ *
143
+ * @return string
144
+ */
145
+ public function get_role_name($role)
146
+ {
147
+ if ($this->is_role($role)) {
148
+ return wp_roles()->role_names[$role];
149
+ }
150
+
151
+ return $role;
152
+ }
153
+
154
+ /**
155
+ * Add role to the system
156
+ *
157
+ * @param $role
158
+ * @param $name
159
+ *
160
+ * @return WP_Role|null
161
+ */
162
+ public function add_role($role, $name)
163
+ {
164
+ $result = add_role($role, $name);
165
+
166
+ return $result;
167
+ }
168
+
169
+ /**
170
+ * Deletes a role from the system
171
+ *
172
+ * @param $role
173
+ *
174
+ * @return bool
175
+ */
176
+ public function delete_role($role, $args = [])
177
+ {
178
+ global $wpdb, $wp_roles;
179
+
180
+ $default = get_option('default_role');
181
+
182
+ if ($default == $role) {
183
+ return false;
184
+ }
185
+
186
+ $like = '%' . $wpdb->esc_like( $role ) . '%';
187
+
188
+ $users = $wpdb->get_results($wpdb->prepare(
189
+ "SELECT ID FROM $wpdb->usermeta INNER JOIN $wpdb->users "
190
+ . "ON $wpdb->usermeta.user_id = $wpdb->users.ID "
191
+ . "WHERE meta_key='{$wpdb->prefix}capabilities' AND meta_value LIKE %s",
192
+
193
+ $like
194
+ )
195
+ );
196
+
197
+ // Array of all roles except the one being deleted, for use below
198
+ $role_names = array_diff_key( $wp_roles->role_names, [$role => true] );
199
+
200
+ $count = 0;
201
+ foreach ( $users as $u ) {
202
+ $skip_role_set = false;
203
+
204
+ $user = new WP_User($u->ID);
205
+ if ( $user->has_cap($role) ) { // Check again the user has the deleting role
206
+ // Role may have been assigned supplementally. Don't move a user to default role if they still have one or more roles following the deletion.
207
+ foreach( array_keys($role_names) as $_role_name ) {
208
+ if ( $user->has_cap($_role_name) ) {
209
+ $skip_role_set = true;
210
+ break;
211
+ }
212
+ }
213
+
214
+ if ( ! $skip_role_set ) {
215
+ $user->set_role($default);
216
+ $count++;
217
+ }
218
+ }
219
+ }
220
+
221
+ remove_role($role);
222
+
223
+ if ( $customized_roles = get_option( 'pp_customized_roles' ) ) {
224
+ if ( isset( $customized_roles[$role] ) ) {
225
+ unset( $customized_roles[$role] );
226
+ update_option( 'pp_customized_roles', $customized_roles );
227
+ }
228
+ }
229
+
230
+ return $count;
231
+ }
232
+ }
includes/roles/class/class-pp-roles.php CHANGED
@@ -1,163 +1,163 @@
1
- <?php
2
-
3
- class PP_Capabilities_Roles
4
- {
5
-
6
- /**
7
- * The loader that's responsible for maintaining and registering all roles hooks
8
- *
9
- * @access protected
10
- * @var Pp_Roles_Loader $loader Maintains and registers all roles hooks
11
- */
12
- protected $loader;
13
-
14
- /**
15
- * Singleton instance
16
- *
17
- * @var null
18
- */
19
- protected static $instance = null;
20
-
21
- /**
22
- * The Singleton method
23
- *
24
- * @return self
25
- */
26
- public static function instance()
27
- {
28
- if (self::$instance === null) {
29
- self::$instance = new self();
30
- }
31
-
32
- return self::$instance;
33
- }
34
-
35
- protected function __construct()
36
- {
37
-
38
- }
39
-
40
- /**
41
- * Load the required dependencies.
42
- *
43
- * - Pp_Roles_Loader. Orchestrates the hooks.
44
- * - Pp_Roles_Admin. Defines all hooks for the admin area.
45
- *
46
- * Create an instance of the loader which will be used to register the hooks
47
- * with WordPress.
48
- *
49
- * @access private
50
- */
51
- private function load_dependencies()
52
- {
53
- /**
54
- * The class responsible for orchestrating the actions and filters of the
55
- * core plugin.
56
- */
57
- require_once 'class-pp-roles-loader.php';
58
-
59
- if (is_admin()) {
60
- /**
61
- * The class responsible for manage roles and capabilities.
62
- */
63
- require_once 'class-pp-roles-manager.php';
64
- /**
65
- * The class responsible for defining all actions that occur in the admin area.
66
- */
67
- require_once 'class-pp-roles-admin.php';
68
- /**
69
- * The class responsible for handling form submissions
70
- */
71
- require_once 'class-pp-roles-actions.php';
72
- }
73
-
74
- $this->loader = new Pp_Roles_Loader();
75
-
76
- }
77
-
78
- /**
79
- * Register all of the hooks related to the admin area functionality.
80
- *
81
- * @access private
82
- */
83
- private function define_admin_hooks()
84
- {
85
-
86
- if (is_admin()) {
87
- /**
88
- * Roles manager
89
- */
90
- $manager = new Pp_Roles_Manager();
91
- $this->loader->set('manager', $manager);
92
-
93
- /**
94
- * Roles admin
95
- */
96
- $role_admin = new Pp_Roles_Admin();
97
- $this->loader->set('admin', $role_admin);
98
-
99
- /**
100
- * Actions to handle
101
- */
102
- $actions = new Pp_Roles_Actions();
103
- $this->loader->set('actions', $actions);
104
-
105
- /**
106
- * Notifications
107
- */
108
- $notifications = new PP_Capabilities_Notices();
109
- $this->loader->set('notify', $notifications);
110
- }
111
- }
112
-
113
- /**
114
- * Run the loader to execute all of the hooks with WordPress.
115
- *
116
- */
117
- public function run()
118
- {
119
- $this->load_dependencies();
120
- $this->define_admin_hooks();
121
- $this->loader->run();
122
- }
123
-
124
- /**
125
- * The reference to the class that orchestrates the hooks.
126
- *
127
- * @return Pp_Roles_Loader Orchestrates the hooks.
128
- */
129
- public function get_loader()
130
- {
131
- return $this->loader;
132
- }
133
-
134
- /**
135
- * Gets an instance from the loader
136
- *
137
- * @param string $key
138
- *
139
- * @return mixed|null The instance
140
- *
141
- * @access public
142
- *
143
- */
144
- public function __get($key)
145
- {
146
- return $this->get_loader()->get($key);
147
- }
148
-
149
- /**
150
- * Sets an instance in the loader
151
- *
152
- * @param string $key
153
- * @param mixed $value
154
- *
155
- * @access public
156
- *
157
- */
158
- public function __set($key, $value)
159
- {
160
- $this->get_loader()->set($key, $value);
161
- }
162
-
163
- }
1
+ <?php
2
+
3
+ class PP_Capabilities_Roles
4
+ {
5
+
6
+ /**
7
+ * The loader that's responsible for maintaining and registering all roles hooks
8
+ *
9
+ * @access protected
10
+ * @var Pp_Roles_Loader $loader Maintains and registers all roles hooks
11
+ */
12
+ protected $loader;
13
+
14
+ /**
15
+ * Singleton instance
16
+ *
17
+ * @var null
18
+ */
19
+ protected static $instance = null;
20
+
21
+ /**
22
+ * The Singleton method
23
+ *
24
+ * @return self
25
+ */
26
+ public static function instance()
27
+ {
28
+ if (self::$instance === null) {
29
+ self::$instance = new self();
30
+ }
31
+
32
+ return self::$instance;
33
+ }
34
+
35
+ protected function __construct()
36
+ {
37
+
38
+ }
39
+
40
+ /**
41
+ * Load the required dependencies.
42
+ *
43
+ * - Pp_Roles_Loader. Orchestrates the hooks.
44
+ * - Pp_Roles_Admin. Defines all hooks for the admin area.
45
+ *
46
+ * Create an instance of the loader which will be used to register the hooks
47
+ * with WordPress.
48
+ *
49
+ * @access private
50
+ */
51
+ private function load_dependencies()
52
+ {
53
+ /**
54
+ * The class responsible for orchestrating the actions and filters of the
55
+ * core plugin.
56
+ */
57
+ require_once 'class-pp-roles-loader.php';
58
+
59
+ if (is_admin()) {
60
+ /**
61
+ * The class responsible for manage roles and capabilities.
62
+ */
63
+ require_once 'class-pp-roles-manager.php';
64
+ /**
65
+ * The class responsible for defining all actions that occur in the admin area.
66
+ */
67
+ require_once 'class-pp-roles-admin.php';
68
+ /**
69
+ * The class responsible for handling form submissions
70
+ */
71
+ require_once 'class-pp-roles-actions.php';
72
+ }
73
+
74
+ $this->loader = new Pp_Roles_Loader();
75
+
76
+ }
77
+
78
+ /**
79
+ * Register all of the hooks related to the admin area functionality.
80
+ *
81
+ * @access private
82
+ */
83
+ private function define_admin_hooks()
84
+ {
85
+
86
+ if (is_admin()) {
87
+ /**
88
+ * Roles manager
89
+ */
90
+ $manager = new Pp_Roles_Manager();
91
+ $this->loader->set('manager', $manager);
92
+
93
+ /**
94
+ * Roles admin
95
+ */
96
+ $role_admin = new Pp_Roles_Admin();
97
+ $this->loader->set('admin', $role_admin);
98
+
99
+ /**
100
+ * Actions to handle
101
+ */
102
+ $actions = new Pp_Roles_Actions();
103
+ $this->loader->set('actions', $actions);
104
+
105
+ /**
106
+ * Notifications
107
+ */
108
+ $notifications = new PP_Capabilities_Notices();
109
+ $this->loader->set('notify', $notifications);
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Run the loader to execute all of the hooks with WordPress.
115
+ *
116
+ */
117
+ public function run()
118
+ {
119
+ $this->load_dependencies();
120
+ $this->define_admin_hooks();
121
+ $this->loader->run();
122
+ }
123
+
124
+ /**
125
+ * The reference to the class that orchestrates the hooks.
126
+ *
127
+ * @return Pp_Roles_Loader Orchestrates the hooks.
128
+ */
129
+ public function get_loader()
130
+ {
131
+ return $this->loader;
132
+ }
133
+
134
+ /**
135
+ * Gets an instance from the loader
136
+ *
137
+ * @param string $key
138
+ *
139
+ * @return mixed|null The instance
140
+ *
141
+ * @access public
142
+ *
143
+ */
144
+ public function __get($key)
145
+ {
146
+ return $this->get_loader()->get($key);
147
+ }
148
+
149
+ /**
150
+ * Sets an instance in the loader
151
+ *
152
+ * @param string $key
153
+ * @param mixed $value
154
+ *
155
+ * @access public
156
+ *
157
+ */
158
+ public function __set($key, $value)
159
+ {
160
+ $this->get_loader()->set($key, $value);
161
+ }
162
+
163
+ }
includes/roles/css/pp-roles-admin.css CHANGED
@@ -1,26 +1,40 @@
1
- .pp-capability-roles-wrapper table th.column-count,
2
- .pp-capability-roles-wrapper table td.column-count {
3
- width: 74px;
4
- text-align: center;
5
- }
6
-
7
- .pp-capability-roles-wrapper .role-state,
8
- .pp-capability-roles-wrapper .role-title-divider {
9
- color: #555;
10
- }
11
-
12
- div.pp-capability-roles-wrapper #col-left {
13
- width: 25%;
14
- }
15
-
16
- div.pp-capability-roles-wrapper #col-right {
17
- width: 75%;
18
- }
19
-
20
- table.roles #role {
21
- width: 45%;
22
- }
23
-
24
- span.pp-caps-action-note {
25
- color: #444;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
1
+ .pp-capability-roles-wrapper table th.column-capabilities,
2
+ .pp-capability-roles-wrapper table th.column-editor_features,
3
+ .pp-capability-roles-wrapper table th.column-admin_features,
4
+ .pp-capability-roles-wrapper table th.column-admin_menus,
5
+ .pp-capability-roles-wrapper table th.column-nav_menus,
6
+
7
+ .pp-capability-roles-wrapper table td.column-capabilities,
8
+ .pp-capability-roles-wrapper table td.column-editor_features,
9
+ .pp-capability-roles-wrapper table td.column-admin_features,
10
+ .pp-capability-roles-wrapper table td.column-admin_menus,
11
+ .pp-capability-roles-wrapper table td.column-nav_menus {
12
+ text-align: center;
13
+ }
14
+
15
+ .pp-capability-roles-wrapper table th.column-count,
16
+ .pp-capability-roles-wrapper table td.column-count {
17
+ width: 74px;
18
+ text-align: center;
19
+ }
20
+
21
+ .pp-capability-roles-wrapper table td.column-count a {
22
+ margin-right: 20px;
23
+ }
24
+
25
+ .pp-capability-roles-wrapper .role-state,
26
+ .pp-capability-roles-wrapper .role-title-divider {
27
+ color: #555;
28
+ }
29
+
30
+ div.pp-capability-roles-wrapper #col-left {
31
+ width: 25%;
32
+ }
33
+
34
+ div.pp-capability-roles-wrapper #col-right {
35
+ width: 75%;
36
+ }
37
+
38
+ span.pp-caps-action-note {
39
+ color: #444;
40
  }
includes/roles/js/pp-roles-admin.js CHANGED
@@ -1,114 +1,114 @@
1
- /**
2
- * Contains logic for deleting and adding roles.
3
- *
4
- * For deleting roles it makes a request to the server to delete the tag.
5
- * For adding roles it makes a request to the server to add the tag.
6
- *
7
- */
8
-
9
- /* global ajaxurl, validateForm */
10
-
11
- jQuery(document).ready(function ($) {
12
- $('input[name="role_name"]').keyup(function(k){
13
- // Indicate how default role slug will be generated from Role Name: PHP save handler will convert certain special characters to underscore, strip out others.
14
- var role_slug = $('input[name="role_name"]').val().toLowerCase().replace(/[ \(\)\&\#\@\+\,\-]/gi, "_").replace(/[^0-9a-zA-Z\_]/g, '');
15
- $('input[name="role_slug"]').attr('placeholder', role_slug);
16
- });
17
-
18
- $('input[name="role_slug"]').keypress(function (e) {
19
- // Don't allow forbidden characters to be entered. Note that dash is not normally allowed, but ban be allowed if constant is defined.
20
-
21
- // underscore, numeric, lowercase
22
- if (95 != e.which && (e.which < 48 || e.which > 57) && (e.which < 97 || e.which > 122)) {
23
- return false;
24
- }
25
- });
26
-
27
- /**
28
- * Adds an event handler to the delete role link on the role overview page.
29
- *
30
- * Cancels default event handling and event bubbling.
31
- *
32
- *
33
- * @returns boolean Always returns false to cancel the default event handling.
34
- */
35
- $('#the-list').on('click', '.delete-role', function () {
36
-
37
- if (confirm(pp_roles_i18n.confirm_delete)) {
38
- var t = $(this), tr = t.parents('tr'), r = true, data;
39
-
40
- data = t.attr('href').replace(/[^?]*\?/, '');
41
-
42
- /**
43
- * Makes a request to the server to delete the role that corresponds to the delete role button.
44
- *
45
- * @param {string} r The response from the server.
46
- *
47
- * @returns {void}
48
- */
49
- $.post(ajaxurl, data, function (r) {
50
- if (r) {
51
- if (r.success === true) {
52
- $('#ajax-response').empty();
53
- tr.fadeOut('normal', function () {
54
- tr.remove();
55
- });
56
- } else {
57
- $('#ajax-response').empty().append(r.data);
58
- tr.children().css('backgroundColor', '');
59
- }
60
- }
61
- });
62
-
63
- tr.children().css('backgroundColor', '#f33');
64
- }
65
-
66
- return false;
67
- });
68
-
69
- /**
70
- * Adds an event handler to the form submit on the role overview page.
71
- *
72
- * Cancels default event handling and event bubbling.
73
- *
74
- *
75
- * @returns boolean Always returns false to cancel the default event handling.
76
- */
77
- $('#submit').click(function () {
78
- var form = $(this).parents('form');
79
-
80
- if (!validateForm(form))
81
- return false;
82
-
83
- /**
84
- * Does a request to the server to add a new role to the system
85
- *
86
- * @param {string} r The response from the server.
87
- *
88
- * @returns {void}
89
- */
90
-
91
- $.post(ajaxurl, $('#addrole').serialize(), function (r) {
92
- var res, parent, role, indent, i;
93
-
94
- $('#ajax-response').empty();
95
- res = typeof r !== 'undefined' ? r : null;
96
- if (res) {
97
- if (res.success === false) {
98
- $('#ajax-response').append(res.data);
99
-
100
- } else if (res.success === true) {
101
-
102
- $('.roles').prepend(res.data); // add to the table
103
-
104
- $('.roles .no-items').remove();
105
-
106
- $('input[type="text"]:visible, textarea:visible', form).val('');
107
- }
108
- }
109
- });
110
-
111
- return false;
112
- });
113
-
114
- });
1
+ /**
2
+ * Contains logic for deleting and adding roles.
3
+ *
4
+ * For deleting roles it makes a request to the server to delete the tag.
5
+ * For adding roles it makes a request to the server to add the tag.
6
+ *
7
+ */
8
+
9
+ /* global ajaxurl, validateForm */
10
+
11
+ jQuery(document).ready(function ($) {
12
+ $('input[name="role_name"]').keyup(function(k){
13
+ // Indicate how default role slug will be generated from Role Name: PHP save handler will convert certain special characters to underscore, strip out others.
14
+ var role_slug = $('input[name="role_name"]').val().toLowerCase().replace(/[ \(\)\&\#\@\+\,\-]/gi, "_").replace(/[^0-9a-zA-Z\_]/g, '');
15
+ $('input[name="role_slug"]').attr('placeholder', role_slug);
16
+ });
17
+
18
+ $('input[name="role_slug"]').keypress(function (e) {
19
+ // Don't allow forbidden characters to be entered. Note that dash is not normally allowed, but ban be allowed if constant is defined.
20
+
21
+ // underscore, numeric, lowercase
22
+ if (95 != e.which && (e.which < 48 || e.which > 57) && (e.which < 97 || e.which > 122)) {
23
+ return false;
24
+ }
25
+ });
26
+
27
+ /**
28
+ * Adds an event handler to the delete role link on the role overview page.
29
+ *
30
+ * Cancels default event handling and event bubbling.
31
+ *
32
+ *
33
+ * @returns boolean Always returns false to cancel the default event handling.
34
+ */
35
+ $('#the-list').on('click', '.delete-role', function () {
36
+
37
+ if (confirm(pp_roles_i18n.confirm_delete)) {
38
+ var t = $(this), tr = t.parents('tr'), r = true, data;
39
+
40
+ data = t.attr('href').replace(/[^?]*\?/, '');
41
+
42
+ /**
43
+ * Makes a request to the server to delete the role that corresponds to the delete role button.
44
+ *
45
+ * @param {string} r The response from the server.
46
+ *
47
+ * @returns {void}
48
+ */
49
+ $.post(ajaxurl, data, function (r) {
50
+ if (r) {
51
+ if (r.success === true) {
52
+ $('#ajax-response').empty();
53
+ tr.fadeOut('normal', function () {
54
+ tr.remove();
55
+ });
56
+ } else {
57
+ $('#ajax-response').empty().append(r.data);
58
+ tr.children().css('backgroundColor', '');
59
+ }
60
+ }
61
+ });
62
+
63
+ tr.children().css('backgroundColor', '#f33');
64
+ }
65
+
66
+ return false;
67
+ });
68
+
69
+ /**
70
+ * Adds an event handler to the form submit on the role overview page.
71
+ *
72
+ * Cancels default event handling and event bubbling.
73
+ *
74
+ *
75
+ * @returns boolean Always returns false to cancel the default event handling.
76
+ */
77
+ $('#submit').click(function () {
78
+ var form = $(this).parents('form');
79
+
80
+ if (!validateForm(form))
81
+ return false;
82
+
83
+ /**
84
+ * Does a request to the server to add a new role to the system
85
+ *
86
+ * @param {string} r The response from the server.
87
+ *
88
+ * @returns {void}
89
+ */
90
+
91
+ $.post(ajaxurl, $('#addrole').serialize(), function (r) {
92
+ var res, parent, role, indent, i;
93
+
94
+ $('#ajax-response').empty();
95
+ res = typeof r !== 'undefined' ? r : null;
96
+ if (res) {
97
+ if (res.success === false) {
98
+ $('#ajax-response').append(res.data);
99
+
100
+ } else if (res.success === true) {
101
+
102
+ $('.roles').prepend(res.data); // add to the table
103
+
104
+ $('.roles .no-items').remove();
105
+
106
+ $('input[type="text"]:visible, textarea:visible', form).val('');
107
+ }
108
+ }
109
+ });
110
+
111
+ return false;
112
+ });
113
+
114
+ });
includes/roles/roles-functions.php CHANGED
@@ -1,120 +1,120 @@
1
- <?php
2
-
3
- /**
4
- * Helper method to get the main role instance
5
- *
6
- * @return PP_Capabilities_Roles
7
- * @access global
8
- */
9
- function pp_capabilities_roles()
10
- {
11
- if (!class_exists('PP_Capabilities_Roles')) {
12
- require_once (dirname(__FILE__) . '/class/class-pp-roles.php');
13
- $roles = pp_capabilities_roles()->run();
14
- }
15
-
16
- return PP_Capabilities_Roles::instance();
17
- }
18
-
19
- /**
20
- * Roles page load
21
- */
22
- function admin_roles_page_load()
23
- {
24
- $plugin_name = 'capsman';
25
- //enqueue styles
26
- wp_enqueue_style($plugin_name, plugin_dir_url(CME_FILE) . 'includes/roles/css/pp-roles-admin.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
27
-
28
- //enqueue scripts
29
- wp_enqueue_script($plugin_name . '_table_edit', plugin_dir_url(CME_FILE) . 'includes/roles/js/pp-roles-admin.js', ['jquery'], PUBLISHPRESS_CAPS_VERSION, false);
30
-
31
- //Localize
32
- wp_localize_script($plugin_name . '_table_edit', 'pp_roles_i18n', ['confirm_delete' => __('Are you sure you want to delete this role?', 'capsman-enhanced')]);
33
-
34
- //initialize table here to be able to register default WP_List_Table screen options
35
- pp_capabilities_roles()->admin->get_roles_list_table();
36
-
37
- //Handle actions
38
- pp_capabilities_roles()->admin->handle_actions();
39
-
40
- //Add screen options
41
- add_screen_option('per_page', ['default' => 999]);
42
- }
43
-
44
-
45
- /**
46
- * Conditional tag to check whether the currently logged-in user has a specific role.
47
- *
48
- * @access public
49
- * @param string|array $roles
50
- * @return bool
51
- */
52
- function pp_roles_current_user_has_role($roles)
53
- {
54
-
55
- return is_user_logged_in() ? pp_roles_user_has_role(get_current_user_id(), $roles) : false;
56
- }
57
-
58
-
59
- /**
60
- * Conditional tag to check whether a user has a specific role.
61
- *
62
- * @access public
63
- * @param int $user_id
64
- * @param string|array $roles
65
- * @return bool
66
- */
67
- function pp_roles_user_has_role($user_id, $roles)
68
- {
69
-
70
- $user = new WP_User($user_id);
71
-
72
- foreach ((array)$roles as $role) {
73
-
74
- if (in_array($role, (array)$user->roles))
75
- return true;
76
- }
77
-
78
- return false;
79
- }
80
-
81
- /**
82
- * Check if role exist and return it data
83
- *
84
- * @param string $role_name
85
- * @return bool|WP_Role
86
- */
87
- function pp_roles_get_role_data($role_name)
88
- {
89
-
90
- $role = false;
91
- $all_roles = pp_capabilities_roles()->manager->get_roles_for_list_table('all', true);
92
-
93
- foreach ($all_roles as $role_data) {
94
- if ($role_name === $role_data['role']) {
95
- $role = $role_data;
96
- break;
97
- }
98
- }
99
-
100
- return $role;
101
- }
102
-
103
-
104
- /**
105
- * Remove capabilities role levels
106
- *
107
- * @param array $capabilities
108
- * @return array
109
- */
110
- function pp_roles_remove_capabilities_role_level($capabilities)
111
- {
112
-
113
- for($i = 0; $i<=10; $i++) {
114
- if (array_key_exists("level_{$i}", $capabilities)) {
115
- unset($capabilities["level_{$i}"]);
116
- }
117
- }
118
-
119
- return $capabilities;
120
- }
1
+ <?php
2
+
3
+ /**
4
+ * Helper method to get the main role instance
5
+ *
6
+ * @return PP_Capabilities_Roles
7
+ * @access global
8
+ */
9
+ function pp_capabilities_roles()
10
+ {
11
+ if (!class_exists('PP_Capabilities_Roles')) {
12
+ require_once (dirname(__FILE__) . '/class/class-pp-roles.php');
13
+ $roles = pp_capabilities_roles()->run();
14
+ }
15
+
16
+ return PP_Capabilities_Roles::instance();
17
+ }
18
+
19
+ /**
20
+ * Roles page load
21
+ */
22
+ function admin_roles_page_load()
23
+ {
24
+ $plugin_name = 'capsman';
25
+ //enqueue styles
26
+ wp_enqueue_style($plugin_name, plugin_dir_url(CME_FILE) . 'includes/roles/css/pp-roles-admin.css', [], PUBLISHPRESS_CAPS_VERSION, 'all');
27
+
28
+ //enqueue scripts
29
+ wp_enqueue_script($plugin_name . '_table_edit', plugin_dir_url(CME_FILE) . 'includes/roles/js/pp-roles-admin.js', ['jquery'], PUBLISHPRESS_CAPS_VERSION, false);
30
+
31
+ //Localize
32
+ wp_localize_script($plugin_name . '_table_edit', 'pp_roles_i18n', ['confirm_delete' => __('Are you sure you want to delete this role?', 'capsman-enhanced')]);
33
+
34
+ //initialize table here to be able to register default WP_List_Table screen options
35
+ pp_capabilities_roles()->admin->get_roles_list_table();
36
+
37
+ //Handle actions
38
+ pp_capabilities_roles()->admin->handle_actions();
39
+
40
+ //Add screen options
41
+ add_screen_option('per_page', ['default' => 999]);
42
+ }
43
+
44
+
45
+ /**
46
+ * Conditional tag to check whether the currently logged-in user has a specific role.
47
+ *
48
+ * @access public
49
+ * @param string|array $roles
50
+ * @return bool
51
+ */
52
+ function pp_roles_current_user_has_role($roles)
53
+ {
54
+
55
+ return is_user_logged_in() ? pp_roles_user_has_role(get_current_user_id(), $roles) : false;
56
+ }
57
+
58
+
59
+ /**
60
+ * Conditional tag to check whether a user has a specific role.
61
+ *
62
+ * @access public
63
+ * @param int $user_id
64
+ * @param string|array $roles
65
+ * @return bool
66
+ */
67
+ function pp_roles_user_has_role($user_id, $roles)
68
+ {
69
+
70
+ $user = new WP_User($user_id);
71
+
72
+ foreach ((array)$roles as $role) {
73
+
74
+ if (in_array($role, (array)$user->roles))
75
+ return true;
76
+ }
77
+
78
+ return false;
79
+ }
80
+
81
+ /**
82
+ * Check if role exist and return it data
83
+ *
84
+ * @param string $role_name
85
+ * @return bool|WP_Role
86
+ */
87
+ function pp_roles_get_role_data($role_name)
88
+ {
89
+
90
+ $role = false;
91
+ $all_roles = pp_capabilities_roles()->manager->get_roles_for_list_table('all', true);
92
+
93
+ foreach ($all_roles as $role_data) {
94
+ if ($role_name === $role_data['role']) {
95
+ $role = $role_data;
96
+ break;
97
+ }
98
+ }
99
+
100
+ return $role;
101
+ }
102
+
103
+
104
+ /**
105
+ * Remove capabilities role levels
106
+ *
107
+ * @param array $capabilities
108
+ * @return array
109
+ */
110
+ function pp_roles_remove_capabilities_role_level($capabilities)
111
+ {
112
+
113
+ for($i = 0; $i<=10; $i++) {
114
+ if (array_key_exists("level_{$i}", $capabilities)) {
115
+ unset($capabilities["level_{$i}"]);
116
+ }
117
+ }
118
+
119
+ return $capabilities;
120
+ }
includes/roles/roles.php CHANGED
@@ -1,51 +1,51 @@
1
- <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-roles-wrapper">
2
-
3
- <?php
4
- if (isset($_GET['add']) && $_GET['add'] === 'new_item') {
5
- pp_capabilities_roles()->admin->get_roles_edit_ui();
6
- }else{ ?>
7
- <div class="wrap">
8
- <h1 class="wp-heading-inline"><?php esc_html_e('Roles', 'capsman-enhanced') ?> </h1>
9
- <a href="<?php echo esc_url(admin_url('admin.php?page=pp-capabilities-roles&add=new_item')); ?>" class="page-title-action">
10
- <?php esc_html_e('Add New', 'capsman-enhanced'); ?>
11
- </a>
12
- <?php
13
- if (isset($_REQUEST['s']) && $search_str = esc_attr(wp_unslash(sanitize_text_field($_REQUEST['s'])))) {
14
- /* translators: %s: search keywords */
15
- printf(' <span class="subtitle">' . esc_html__('Search results for &#8220;%s&#8221;', 'capsman-enhanced') . '</span>', esc_html($search_str));
16
- }
17
-
18
- //the roles table instance
19
- $table = pp_capabilities_roles()->admin->get_roles_list_table();
20
- $table->prepare_items();
21
- pp_capabilities_roles()->notify->display();
22
- ?>
23
- <hr class="wp-header-end">
24
- <div id="ajax-response"></div>
25
- <form class="search-form wp-clearfix" method="get">
26
- <?php $table->search_box(esc_html__('Search Roles', 'capsman-enhanced'), 'roles'); ?>
27
- </form>
28
- <div id="col-container" class="wp-clearfix">
29
- <div class="col-wrap">
30
- <form action="" method="post">
31
- <?php $table->display(); //Display the table ?>
32
- </form>
33
- <div class="form-wrap edit-term-notes">
34
- <p><?php esc_html__('Description here.', 'capsman-enhanced') ?></p>
35
- </div>
36
- </div>
37
- </div>
38
- <form method="get">
39
- <?php $table->inline_edit() ?>
40
- </form>
41
-
42
- </div>
43
- <?php } ?>
44
-
45
-
46
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
47
- cme_publishpressFooter();
48
- }
49
- ?>
50
- </div>
51
- <?php
1
+ <div class="wrap publishpress-caps-manage pressshack-admin-wrapper pp-capability-roles-wrapper">
2
+
3
+ <?php
4
+ if (isset($_GET['add']) && $_GET['add'] === 'new_item') {
5
+ pp_capabilities_roles()->admin->get_roles_edit_ui();
6
+ }else{ ?>
7
+ <div class="wrap">
8
+ <h1 class="wp-heading-inline"><?php esc_html_e('Roles', 'capsman-enhanced') ?> </h1>
9
+ <a href="<?php echo esc_url(admin_url('admin.php?page=pp-capabilities-roles&add=new_item')); ?>" class="page-title-action">
10
+ <?php esc_html_e('Add New', 'capsman-enhanced'); ?>
11
+ </a>
12
+ <?php
13
+ if (isset($_REQUEST['s']) && $search_str = esc_attr(wp_unslash(sanitize_text_field($_REQUEST['s'])))) {
14
+ /* translators: %s: search keywords */
15
+ printf(' <span class="subtitle">' . esc_html__('Search results for &#8220;%s&#8221;', 'capsman-enhanced') . '</span>', esc_html($search_str));
16
+ }
17
+
18
+ //the roles table instance
19
+ $table = pp_capabilities_roles()->admin->get_roles_list_table();
20
+ $table->prepare_items();
21
+ pp_capabilities_roles()->notify->display();
22
+ ?>
23
+ <hr class="wp-header-end">
24
+ <div id="ajax-response"></div>
25
+ <form class="search-form wp-clearfix" method="get">
26
+ <?php $table->search_box(esc_html__('Search Roles', 'capsman-enhanced'), 'roles'); ?>
27
+ </form>
28
+ <div id="col-container" class="wp-clearfix">
29
+ <div class="col-wrap">
30
+ <form action="" method="post">
31
+ <?php $table->display(); //Display the table ?>
32
+ </form>
33
+ <div class="form-wrap edit-term-notes">
34
+ <p><?php esc_html__('Description here.', 'capsman-enhanced') ?></p>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ <form method="get">
39
+ <?php $table->inline_edit() ?>
40
+ </form>
41
+
42
+ </div>
43
+ <?php } ?>
44
+
45
+
46
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
47
+ cme_publishpressFooter();
48
+ }
49
+ ?>
50
+ </div>
51
+ <?php
includes/settings-handler.php CHANGED
@@ -1,26 +1,26 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Process updates to plugin settings
6
- *
7
- */
8
-
9
- add_action('init', function() {
10
- if (check_admin_referer('pp-capabilities-settings') && current_user_can('manage_capabilities')) {
11
- if (!empty($_POST['all_options'])) {
12
- foreach(array_map('sanitize_key', explode(',', sanitize_text_field($_POST['all_options']))) as $option_name) {
13
- foreach (['cme_', 'capsman', 'pp_capabilities'] as $prefix) {
14
- if (0 === strpos($option_name, $prefix)) {
15
-
16
- // Free plugin doesn't currently have any settings, so disable this code for now to avoid sanitization concerns.
17
-
18
- // Leave upstream conditionals in place to ensure access is properly regulated in any future implementation.
19
- }
20
- }
21
- }
22
- }
23
-
24
- do_action('pp-capabilities-update-settings');
25
- }
26
- });
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Process updates to plugin settings
6
+ *
7
+ */
8
+
9
+ add_action('init', function() {
10
+ if (check_admin_referer('pp-capabilities-settings') && current_user_can('manage_capabilities')) {
11
+ if (!empty($_POST['all_options'])) {
12
+ foreach(array_map('sanitize_key', explode(',', sanitize_text_field($_POST['all_options']))) as $option_name) {
13
+ foreach (['cme_', 'capsman', 'pp_capabilities'] as $prefix) {
14
+ if (0 === strpos($option_name, $prefix)) {
15
+
16
+ // Free plugin doesn't currently have any settings, so disable this code for now to avoid sanitization concerns.
17
+
18
+ // Leave upstream conditionals in place to ensure access is properly regulated in any future implementation.
19
+ }
20
+ }
21
+ }
22
+ }
23
+
24
+ do_action('pp-capabilities-update-settings');
25
+ }
26
+ });
includes/settings.php CHANGED
@@ -1,63 +1,63 @@
1
- <?php
2
- /*
3
- * PublishPress Capabilities [Free]
4
- *
5
- * Settings UI
6
- *
7
- */
8
-
9
- global $wpdb;
10
- $all_options = [];
11
- ?>
12
-
13
- <div class="wrap publishpress-caps-manage publishpress-caps-settings pressshack-admin-wrapper">
14
- <h1><?php printf(esc_html__('Capabilities Settings', 'capsman-enhanced'), '<a href="admin.php?page=pp-capabilities">', '</a>'); ?></h1>
15
-
16
- <form class="basic-settings" method="post" action="">
17
- <?php wp_nonce_field('pp-capabilities-settings'); ?>
18
-
19
- <br />
20
-
21
- <?php do_action('pp-capabilities-settings-ui');?>
22
-
23
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) :?>
24
- <h3><?php esc_html_e('Related Permissions Plugins', 'capsman-enhanced');?></h3>
25
- <ul>
26
- <?php $_url = "plugin-install.php?tab=plugin-information&plugin=publishpress&TB_iframe=true&width=640&height=678";
27
- $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
28
- ?>
29
- <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress', 'capsman-enhanced');?></a></li>
30
-
31
- <?php $_url = "plugin-install.php?tab=plugin-information&plugin=publishpress-authors&TB_iframe=true&width=640&height=678";
32
- $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
33
- ?>
34
- <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Authors', 'capsman-enhanced');?></a></li>
35
- </li>
36
-
37
- <?php $_url = "plugin-install.php?tab=plugin-information&plugin=press-permit-core&TB_iframe=true&width=640&height=678";
38
- $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
39
- ?>
40
- <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Permissions', 'capsman-enhanced');?></a></li>
41
- </li>
42
-
43
- <?php $_url = "plugin-install.php?tab=plugin-information&plugin=revisionary&TB_iframe=true&width=640&height=678";
44
- $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
45
- ?>
46
- <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Revisions', 'capsman-enhanced');?></a></li>
47
-
48
- <li class="publishpress-contact"><a href="https://publishpress.com/contact" target="_blank"><?php esc_html_e('Help / Contact Form', 'capsman-enhanced');?></a></li>
49
- </ul>
50
- <?php endif;?>
51
-
52
- <?php
53
- echo "<input type='hidden' name='all_options' value='" . implode(',', array_map('esc_attr', $all_options)) . "' />";
54
- ?>
55
-
56
- <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e('Save Changes', 'capsman-enhanced');?>">
57
- </form>
58
-
59
- <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
60
- cme_publishpressFooter();
61
- }
62
- ?>
63
  </div>
1
+ <?php
2
+ /*
3
+ * PublishPress Capabilities [Free]
4
+ *
5
+ * Settings UI
6
+ *
7
+ */
8
+
9
+ global $wpdb;
10
+ $all_options = [];
11
+ ?>
12
+
13
+ <div class="wrap publishpress-caps-manage publishpress-caps-settings pressshack-admin-wrapper">
14
+ <h1><?php printf(esc_html__('Capabilities Settings', 'capsman-enhanced'), '<a href="admin.php?page=pp-capabilities">', '</a>'); ?></h1>
15
+
16
+ <form class="basic-settings" method="post" action="">
17
+ <?php wp_nonce_field('pp-capabilities-settings'); ?>
18
+
19
+ <br />
20
+
21
+ <?php do_action('pp-capabilities-settings-ui');?>
22
+
23
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION')) :?>
24
+ <h3><?php esc_html_e('Related Permissions Plugins', 'capsman-enhanced');?></h3>
25
+ <ul>
26
+ <?php $_url = "plugin-install.php?tab=plugin-information&plugin=publishpress&TB_iframe=true&width=640&height=678";
27
+ $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
28
+ ?>
29
+ <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress', 'capsman-enhanced');?></a></li>
30
+
31
+ <?php $_url = "plugin-install.php?tab=plugin-information&plugin=publishpress-authors&TB_iframe=true&width=640&height=678";
32
+ $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
33
+ ?>
34
+ <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Authors', 'capsman-enhanced');?></a></li>
35
+ </li>
36
+
37
+ <?php $_url = "plugin-install.php?tab=plugin-information&plugin=press-permit-core&TB_iframe=true&width=640&height=678";
38
+ $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
39
+ ?>
40
+ <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Permissions', 'capsman-enhanced');?></a></li>
41
+ </li>
42
+
43
+ <?php $_url = "plugin-install.php?tab=plugin-information&plugin=revisionary&TB_iframe=true&width=640&height=678";
44
+ $url = ( is_multisite() ) ? network_admin_url($_url) : admin_url($_url);
45
+ ?>
46
+ <li><a class="thickbox" href="<?php echo (esc_url_raw($url));?>"><?php esc_html_e('PublishPress Revisions', 'capsman-enhanced');?></a></li>
47
+
48
+ <li class="publishpress-contact"><a href="https://publishpress.com/contact" target="_blank"><?php esc_html_e('Help / Contact Form', 'capsman-enhanced');?></a></li>
49
+ </ul>
50
+ <?php endif;?>
51
+
52
+ <?php
53
+ echo "<input type='hidden' name='all_options' value='" . implode(',', array_map('esc_attr', $all_options)) . "' />";
54
+ ?>
55
+
56
+ <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e('Save Changes', 'capsman-enhanced');?>">
57
+ </form>
58
+
59
+ <?php if (!defined('PUBLISHPRESS_CAPS_PRO_VERSION') || get_option('cme_display_branding')) {
60
+ cme_publishpressFooter();
61
+ }
62
+ ?>
63
  </div>
languages/capsman-enhanced-ca.mo CHANGED
Binary file
languages/capsman-enhanced-ca.po CHANGED
@@ -2,7 +2,7 @@ msgid ""
2
  msgstr ""
3
  "Project-Id-Version: PublishPress Capabilities\n"
4
  "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2021-02-03 15:42-0500\n"
6
  "PO-Revision-Date: \n"
7
  "Last-Translator: Kevin Behrens <kevin@publishpress.com>\n"
8
  "Language-Team: PublishPress <help@publishpress.com>\n"
@@ -12,33 +12,36 @@ msgstr ""
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
  "X-Poedit-SourceCharset: UTF-8\n"
15
- "X-Generator: Poedit 2.4.2\n"
16
- "X-Poedit-KeywordsList: __;_e;_c;_x;__ngettext\n"
17
  "X-Poedit-Basepath: ..\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPath-1: includes\n"
20
  "X-Poedit-SearchPath-2: includes-core\n"
21
 
22
  #: capsman-enhanced.php:40
 
23
  msgid ""
24
- "<strong>Error:</strong> PublishPress Capabilities cannot function because "
25
- "another copy of Capability Manager is active."
26
  msgstr ""
27
 
28
- #: capsman-enhanced.php:71
29
- msgid "<strong>This plugin can be deleted.</strong>"
30
- msgstr ""
 
 
31
 
32
- #: capsman-enhanced.php:102
33
  msgid "Warning:"
34
  msgstr "Atenció:"
35
 
36
- #: capsman-enhanced.php:103
37
  #, php-format
38
  msgid "The active plugin %s is not compatible with your PHP version."
39
  msgstr "L'extensió activa %s no és compatible amb la teva versió de PHP."
40
 
41
- #: capsman-enhanced.php:105
42
  #, php-format
43
  msgid "%s is required for this plugin."
44
  msgstr "Es requereix %s per aquesta extensió."
@@ -47,33 +50,95 @@ msgstr "Es requereix %s per aquesta extensió."
47
  msgid "Settings saved."
48
  msgstr "Opcions desades."
49
 
50
- #: includes-core/CoreAdmin.php:55 includes/functions-admin.php:37
51
  msgid "Admin Menus"
52
  msgstr ""
53
 
54
- #: includes-core/CoreAdmin.php:56 includes/functions-admin.php:38
55
  msgid "Nav Menus"
56
  msgstr ""
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  #: includes-core/admin-menus-promo.php:29
59
  msgid "Admin Menu Restrictions"
60
  msgstr ""
61
 
62
- #: includes-core/admin-menus-promo.php:48 includes-core/nav-menus-promo.php:52
63
- #: includes/admin.php:99 includes/admin.php:1079 includes/settings.php:54
64
- msgid "Save Changes"
65
- msgstr "Desa els canvis"
66
-
67
  #: includes-core/admin-menus-promo.php:58
68
  msgid ""
69
  "You can restrict access to admin menu screens. This feature is available in "
70
  "PublishPress Capabilities Pro"
71
  msgstr ""
72
 
73
- #: includes-core/admin-menus-promo.php:62 includes-core/nav-menus-promo.php:67
74
- #: includes/functions-admin.php:45 includes/functions-admin.php:46
75
- #: includes/manager.php:334 includes/manager.php:335
76
- msgid "Upgrade to Pro"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  msgstr ""
78
 
79
  #: includes-core/nav-menus-promo.php:29
@@ -86,709 +151,1119 @@ msgid ""
86
  "PublishPress Capabilities Pro"
87
  msgstr ""
88
 
89
- #: includes/admin.php:38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  #, php-format
91
  msgid ""
92
  "Warning: This role cannot access the dashboard without the read capability. "
93
  "%1$sClick here to fix this now%2$s."
94
  msgstr ""
95
 
96
- #: includes/admin.php:64
97
  msgid "Role Capabilities"
98
  msgstr "Competències"
99
 
100
- #: includes/admin.php:109
 
 
 
 
 
 
 
 
 
 
 
 
101
  msgid ""
102
  "<strong>Note:</strong> Capability changes <strong>remain in the database</"
103
  "strong> after plugin deactivation."
104
  msgstr ""
105
 
106
- #: includes/admin.php:114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  #, php-format
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  msgid ""
109
- "<strong>Note:</strong> Capability changes <strong>remain in the database</"
110
- "strong> after plugin deactivation. You can also configure this role as a "
111
- "%sPermission Group%s."
112
  msgstr ""
113
 
114
- #: includes/admin.php:148 includes/settings.php:38
115
- msgid "PublishPress Permissions"
 
 
 
 
 
 
 
 
 
 
 
 
116
  msgstr ""
117
 
118
- #: includes/admin.php:150
119
  msgid ""
120
  "Automatically define type-specific capabilities for your custom post types "
121
  "and taxonomies"
122
  msgstr ""
123
 
124
- #: includes/admin.php:154
125
  msgid "Assign standard WP roles supplementally for a specific post type"
126
  msgstr ""
127
 
128
- #: includes/admin.php:158
129
  msgid ""
130
  "Assign custom WP roles supplementally for a specific post type <em>(Pro)</em>"
131
  msgstr ""
132
 
133
- #: includes/admin.php:162
134
  msgid "Customize reading permissions per-category or per-post"
135
  msgstr ""
136
 
137
- #: includes/admin.php:166
138
  msgid "Customize editing permissions per-category or per-post <em>(Pro)</em>"
139
  msgstr ""
140
 
141
- #: includes/admin.php:170
142
  msgid ""
143
  "Custom Post Visibility statuses, fully implemented throughout wp-admin "
144
  "<em>(Pro)</em>"
145
  msgstr ""
146
 
147
- #: includes/admin.php:174
148
  msgid ""
149
  "Custom Moderation statuses for access-controlled, multi-step publishing "
150
  "workflow <em>(Pro)</em>"
151
  msgstr ""
152
 
153
- #: includes/admin.php:178
154
  msgid "Regulate permissions for Edit Flow post statuses <em>(Pro)</em>"
155
  msgstr ""
156
 
157
- #: includes/admin.php:182
158
  msgid ""
159
  "Customize the moderated editing of published content with Revisionary or "
160
  "Post Forking <em>(Pro)</em>"
161
  msgstr ""
162
 
163
- #: includes/admin.php:186
164
  msgid ""
165
  "Grant Spectator, Participant or Moderator access to specific bbPress forums "
166
  "<em>(Pro)</em>"
167
  msgstr ""
168
 
169
- #: includes/admin.php:190
170
  msgid ""
171
  "Grant supplemental content permissions to a BuddyPress group <em>(Pro)</em>"
172
  msgstr ""
173
 
174
- #: includes/admin.php:194
175
  msgid "WPML integration to mirror permissions to translations <em>(Pro)</em>"
176
  msgstr ""
177
 
178
- #: includes/admin.php:198
179
  msgid "Member support forum"
180
  msgstr "Forum d'Ajuda"
181
 
182
- #: includes/admin.php:205
183
  #, php-format
184
  msgid "%1$sgrab%2$s %3$s"
185
  msgstr ""
186
 
187
- #: includes/admin.php:205
188
  #, php-format
189
- msgid "%s (free install)"
2
  msgstr ""
3
  "Project-Id-Version: PublishPress Capabilities\n"
4
  "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2022-04-19 13:48-0400\n"
6
  "PO-Revision-Date: \n"
7
  "Last-Translator: Kevin Behrens <kevin@publishpress.com>\n"
8
  "Language-Team: PublishPress <help@publishpress.com>\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
  "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Generator: Poedit 2.4.3\n"
16
+ "X-Poedit-KeywordsList: __;_e;_c;_x;__ngettext;_n;_ex;esc_html__;esc_html_e\n"
17
  "X-Poedit-Basepath: ..\n"
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPath-1: includes\n"
20
  "X-Poedit-SearchPath-2: includes-core\n"
21
 
22
  #: capsman-enhanced.php:40
23
+ #, php-format
24
  msgid ""
25
+ "%1s Error: %2s PublishPress Capabilities cannot function because another "
26
+ "copy of Capability Manager is active."
27
  msgstr ""
28
 
29
+ #: capsman-enhanced.php:70
30
+ #, fuzzy
31
+ #| msgid "MIME type can't be detected."
32
+ msgid "This plugin can be deleted."
33
+ msgstr "No es pot detectar el tipus MIME."
34
 
35
+ #: capsman-enhanced.php:97
36
  msgid "Warning:"
37
  msgstr "Atenció:"
38
 
39
+ #: capsman-enhanced.php:98
40
  #, php-format
41
  msgid "The active plugin %s is not compatible with your PHP version."
42
  msgstr "L'extensió activa %s no és compatible amb la teva versió de PHP."
43
 
44
+ #: capsman-enhanced.php:100
45
  #, php-format
46
  msgid "%s is required for this plugin."
47
  msgstr "Es requereix %s per aquesta extensió."
50
  msgid "Settings saved."
51
  msgstr "Opcions desades."
52
 
53
+ #: includes-core/CoreAdmin.php:62 includes/admin-load.php:311
54
  msgid "Admin Menus"
55
  msgstr ""
56
 
57
+ #: includes-core/CoreAdmin.php:63 includes/admin-load.php:312
58
  msgid "Nav Menus"
59
  msgstr ""
60
 
61
+ #: includes-core/admin-features-promo.php:74
62
+ msgid ""
63
+ "You can block pages by URL or hide Admin elements by entering a CSS class or "
64
+ "ID. This feature is available in PublishPress Capabilities Pro."
65
+ msgstr ""
66
+
67
+ #: includes-core/admin-features-promo.php:79
68
+ #: includes-core/admin-menus-promo.php:62
69
+ #: includes-core/editor-features-promo.php:91
70
+ #: includes-core/nav-menus-promo.php:67 includes/admin-load.php:322
71
+ #: includes/admin-load.php:323 includes/manager.php:388
72
+ #: includes/manager.php:389
73
+ msgid "Upgrade to Pro"
74
+ msgstr ""
75
+
76
  #: includes-core/admin-menus-promo.php:29
77
  msgid "Admin Menu Restrictions"
78
  msgstr ""
79
 
 
 
 
 
 
80
  #: includes-core/admin-menus-promo.php:58
81
  msgid ""
82
  "You can restrict access to admin menu screens. This feature is available in "
83
  "PublishPress Capabilities Pro"
84
  msgstr ""
85
 
86
+ #: includes-core/editor-features-promo.php:24
87
+ msgid "Metaboxes"
88
+ msgstr ""
89
+
90
+ #: includes-core/editor-features-promo.php:32
91
+ msgid "Checklist"
92
+ msgstr ""
93
+
94
+ #: includes-core/editor-features-promo.php:45
95
+ msgid "Editorial Comments"
96
+ msgstr ""
97
+
98
+ #: includes-core/editor-features-promo.php:58
99
+ msgid "Notifications"
100
+ msgstr ""
101
+
102
+ #: includes-core/editor-features-promo.php:71
103
+ msgid "TaxoPress - Settings"
104
+ msgstr ""
105
+
106
+ #: includes-core/editor-features-promo.php:86
107
+ msgid ""
108
+ "You can hide plugin metaboxes. You can also hide specific items by entering "
109
+ "their CSS class or ID. This feature is available in PublishPress "
110
+ "Capabilities Pro."
111
+ msgstr ""
112
+
113
+ #: includes-core/editor-features-promo.php:101
114
+ msgid "Custom Items"
115
+ msgstr ""
116
+
117
+ #: includes-core/editor-features-promo.php:107
118
+ msgid "Custom item one"
119
+ msgstr ""
120
+
121
+ #: includes-core/editor-features-promo.php:108
122
+ #: includes-core/editor-features-promo.php:122
123
+ #: includes-core/editor-features-promo.php:135
124
+ #: includes/features/admin-features.php:190
125
+ #: includes/features/editor-features-classic.php:80
126
+ #: includes/features/editor-features-gutenberg.php:79
127
+ #: includes/roles/class/class-pp-roles-admin.php:116
128
+ #: includes/roles/class/class-pp-roles-list-table.php:277
129
+ #: includes/roles/class/class-pp-roles-list-table.php:414
130
+ #, fuzzy
131
+ msgid "Delete"
132
+ msgstr ""
133
+ "Estàs apunt d'eliminar el rol %s.\n"
134
+ " 'Cancel·la' per sortir, 'D'acord' per eliminar."
135
+
136
+ #: includes-core/editor-features-promo.php:121
137
+ msgid "Permalink: Descriptive Caption"
138
+ msgstr ""
139
+
140
+ #: includes-core/editor-features-promo.php:135
141
+ msgid "Page Attributes: Order"
142
  msgstr ""
143
 
144
  #: includes-core/nav-menus-promo.php:29
151
  "PublishPress Capabilities Pro"
152
  msgstr ""
153
 
154
+ #: includes/admin-load.php:286 includes/manager.php:339
155
+ #: includes/roles/class/class-pp-roles-admin.php:416
156
+ #: includes/roles/class/class-pp-roles-list-table.php:213
157
+ msgid "Capabilities"
158
+ msgstr "Competències"
159
+
160
+ #: includes/admin-load.php:308 includes/manager.php:361
161
+ #: includes/roles/roles.php:8
162
+ msgid "Roles"
163
+ msgstr "Rols"
164
+
165
+ #: includes/admin-load.php:309 includes/manager.php:373
166
+ msgid "Editor Features"
167
+ msgstr ""
168
+
169
+ #: includes/admin-load.php:310 includes/manager.php:375
170
+ msgid "Admin Features"
171
+ msgstr ""
172
+
173
+ #: includes/admin-load.php:313 includes/backup.php:49 includes/manager.php:379
174
+ msgid "Backup"
175
+ msgstr "Copia"
176
+
177
+ #: includes/admin-load.php:316
178
+ #: includes/features/restrict-editor-features.php:309 includes/manager.php:382
179
+ #, fuzzy
180
+ #| msgid "Settings saved."
181
+ msgid "Settings"
182
+ msgstr "Opcions desades."
183
+
184
+ #: includes/admin.php:40
185
  #, php-format
186
  msgid ""
187
  "Warning: This role cannot access the dashboard without the read capability. "
188
  "%1$sClick here to fix this now%2$s."
189
  msgstr ""
190
 
191
+ #: includes/admin.php:59
192
  msgid "Role Capabilities"
193
  msgstr "Competències"
194
 
195
+ #: includes/admin.php:113 includes/admin.php:1348
196
+ msgid "Save Changes"
197
+ msgstr "Desa els canvis"
198
+
199
+ #: includes/admin.php:132
200
+ #, php-format
201
+ msgid ""
202
+ "<strong>Note:</strong> Capability changes <strong>remain in the database</"
203
+ "strong> after plugin deactivation. You can also configure this role as a "
204
+ "%sPermission Group%s."
205
+ msgstr ""
206
+
207
+ #: includes/admin.php:140
208
  msgid ""
209
  "<strong>Note:</strong> Capability changes <strong>remain in the database</"
210
  "strong> after plugin deactivation."
211
  msgstr ""
212
 
213
+ #: includes/admin.php:221
214
+ msgid "&nbsp;"
215
+ msgstr ""
216
+
217
+ #: includes/admin.php:222
218
+ msgid "Reading"
219
+ msgstr ""
220
+
221
+ #: includes/admin.php:223
222
+ msgid "Editing"
223
+ msgstr ""
224
+
225
+ #: includes/admin.php:224
226
+ #, fuzzy
227
+ #| msgid "Select action:"
228
+ msgid "Deletion"
229
+ msgstr "Selecciona una acció:"
230
+
231
+ #: includes/admin.php:316
232
+ msgid "WordPress Core"
233
+ msgstr ""
234
+
235
+ #: includes/admin.php:490 includes/admin.php:978
236
+ msgid "Invalid Capabilities"
237
+ msgstr ""
238
+
239
+ #: includes/admin.php:495
240
+ msgid "Additional"
241
+ msgstr ""
242
+
243
+ #: includes/admin.php:539
244
+ #, fuzzy, php-format
245
+ #| msgid "%s Capabilities"
246
+ msgid "Term %s Capabilities"
247
+ msgstr "%s Competències"
248
+
249
+ #: includes/admin.php:539
250
+ #, fuzzy, php-format
251
+ #| msgid "%s Capabilities"
252
+ msgid "Post %s Capabilities"
253
+ msgstr "%s Competències"
254
+
255
+ #: includes/admin.php:545
256
+ msgid "Filter by taxonomy"
257
+ msgstr ""
258
+
259
+ #: includes/admin.php:545
260
+ msgid "Filter by post type"
261
+ msgstr ""
262
+
263
+ #: includes/admin.php:548 includes/admin.php:736 includes/admin.php:874
264
+ #: includes/admin.php:1080
265
+ msgid "Clear"
266
+ msgstr ""
267
+
268
+ #: includes/admin.php:640 includes/admin.php:782 includes/admin.php:922
269
+ #: includes/admin.php:1153
270
+ #, php-format
271
+ msgid "%s: assigned by Permission Group"
272
+ msgstr ""
273
+
274
+ #: includes/admin.php:652
275
  #, php-format
276
+ msgid "shared capability: %s"
277
+ msgstr ""
278
+
279
+ #: includes/admin.php:732
280
+ #, fuzzy
281
+ #| msgid "Role Capabilities"
282
+ msgid "WordPress Core Capabilities"
283
+ msgstr "Competències"
284
+
285
+ #: includes/admin.php:738 includes/admin.php:876 includes/admin.php:1082
286
+ msgid "No results found. Please try again with a different word."
287
+ msgstr ""
288
+
289
+ #: includes/admin.php:749 includes/admin.php:843 includes/admin.php:887
290
+ #: includes/admin.php:960 includes/admin.php:1088 includes/admin.php:1205
291
+ #, fuzzy
292
+ #| msgid "Capability Manager"
293
+ msgid "Capability Name"
294
+ msgstr "Administrador de Compoetències"
295
+
296
+ #: includes/admin.php:801
297
  msgid ""
298
+ "Lockout Prevention: To remove read capability, first remove WordPress "
299
+ "admin / editing capabilities, or add \"dashboard_lockout_ok\" capability"
 
300
  msgstr ""
301
 
302
+ #: includes/admin.php:870
303
+ #, fuzzy, php-format
304
+ #| msgid "Capabilities for %s"
305
+ msgid "Plugin Capabilities &ndash; %s"
306
+ msgstr "Competències per %s"
307
+
308
+ #: includes/admin.php:991
309
+ msgid ""
310
+ "The following entries have no effect. Please assign desired capabilities in "
311
+ "the Read / Edit / Delete grid above."
312
+ msgstr ""
313
+
314
+ #: includes/admin.php:1076
315
+ msgid "Additional Capabilities"
316
  msgstr ""
317
 
318
+ #: includes/admin.php:1237
319
  msgid ""
320
  "Automatically define type-specific capabilities for your custom post types "
321
  "and taxonomies"
322
  msgstr ""
323
 
324
+ #: includes/admin.php:1241
325
  msgid "Assign standard WP roles supplementally for a specific post type"
326
  msgstr ""
327
 
328
+ #: includes/admin.php:1245
329
  msgid ""
330
  "Assign custom WP roles supplementally for a specific post type <em>(Pro)</em>"
331
  msgstr ""
332
 
333
+ #: includes/admin.php:1249
334
  msgid "Customize reading permissions per-category or per-post"
335
  msgstr ""
336
 
337
+ #: includes/admin.php:1253
338
  msgid "Customize editing permissions per-category or per-post <em>(Pro)</em>"
339
  msgstr ""
340
 
341
+ #: includes/admin.php:1257
342
  msgid ""
343
  "Custom Post Visibility statuses, fully implemented throughout wp-admin "
344
  "<em>(Pro)</em>"
345
  msgstr ""
346
 
347
+ #: includes/admin.php:1261
348
  msgid ""
349
  "Custom Moderation statuses for access-controlled, multi-step publishing "
350
  "workflow <em>(Pro)</em>"
351
  msgstr ""
352
 
353
+ #: includes/admin.php:1265
354
  msgid "Regulate permissions for Edit Flow post statuses <em>(Pro)</em>"
355
  msgstr ""
356
 
357
+ #: includes/admin.php:1269
358
  msgid ""
359
  "Customize the moderated editing of published content with Revisionary or "
360
  "Post Forking <em>(Pro)</em>"
361
  msgstr ""
362
 
363
+ #: includes/admin.php:1273
364
  msgid ""
365
  "Grant Spectator, Participant or Moderator access to specific bbPress forums "
366
  "<em>(Pro)</em>"
367
  msgstr ""
368
 
369
+ #: includes/admin.php:1277
370
  msgid ""
371
  "Grant supplemental content permissions to a BuddyPress group <em>(Pro)</em>"
372
  msgstr ""
373
 
374
+ #: includes/admin.php:1281
375
  msgid "WPML integration to mirror permissions to translations <em>(Pro)</em>"
376
  msgstr ""
377
 
378
+ #: includes/admin.php:1285
379
  msgid "Member support forum"
380
  msgstr "Forum d'Ajuda"
381
 
382
+ #: includes/admin.php:1292
383
  #, php-format
384
  msgid "%1$sgrab%2$s %3$s"
385
  msgstr ""
386
 
387
+ #: includes/admin.php:1294
388
  #, php-format
389
+ msgid "%1$sbuy%2$s