PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.2
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.2
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
metasync / includes / class-metasync-access-control.php

class-metasync-access-control.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.7.2, at includes/class-metasync-access-control.php

337 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Access Control Management
4 *
5 * Handles granular access control for plugin features based on user roles and specific users.
6 * Provides methods to check permissions and manage access control settings.
7 *
8 * @package Metasync
9 * @subpackage Metasync/includes
10 */
11
12 class Metasync_Access_Control {
13
14 /**
15 * Feature identifiers and their display names
16 *
17 * @var array
18 */
19 private static $features = array(
20 'hide_dashboard' => 'Dashboard',
21 'hide_settings' => 'Settings',
22 'hide_indexation_control' => 'Indexation Control',
23 'hide_redirections' => 'Redirect Manager',
24 'hide_robots' => 'Robots.txt',
25 'hide_xml_sitemap' => 'XML Sitemap',
26 'hide_import_seo' => 'Import SEO Data',
27 'hide_custom_pages' => 'Custom Pages',
28 'hide_sync_log' => 'Changes Log',
29 'hide_compatibility' => 'Compatibility',
30 'hide_report_issue' => 'Report Issue',
31
32 'hide_advanced' => 'Advanced Settings'
33 );
34
35 /**
36 * Get all available features
37 *
38 * @return array Features array
39 */
40 public static function get_features() {
41 return self::$features;
42 }
43
44 /**
45 * Check if current user has access to a specific feature
46 *
47 * @param string $feature_key Feature identifier (e.g., 'hide_redirections')
48 * @return bool True if user has access, false otherwise
49 */
50 public static function user_can_access($feature_key) {
51 // Get whitelabel settings
52 $whitelabel_settings = Metasync::get_whitelabel_settings();
53
54 // If access control is not set for this feature, check old hide logic
55 if (!isset($whitelabel_settings['access_control'][$feature_key])) {
56 // Fallback to old behavior: if hidden, nobody can access
57 return empty($whitelabel_settings[$feature_key]);
58 }
59
60 $access_config = $whitelabel_settings['access_control'][$feature_key];
61
62 // If access control is disabled, feature is visible to all
63 if (empty($access_config['enabled'])) {
64 return true;
65 }
66
67 // Get current user
68 $current_user = wp_get_current_user();
69
70 // Determine access type
71 $access_type = isset($access_config['type']) ? $access_config['type'] : 'all';
72
73 switch ($access_type) {
74 case 'role':
75 return self::check_role_access($current_user, $access_config);
76
77 case 'user':
78 return self::check_user_access($current_user, $access_config);
79
80 case 'none':
81 // Feature is hidden from everyone
82 return false;
83
84 case 'all':
85 default:
86 // Feature is visible to all logged-in users
87 return true;
88 }
89 }
90
91 /**
92 * Check if user has access based on role
93 *
94 * @param WP_User $user Current user object
95 * @param array $access_config Access configuration
96 * @return bool True if user's role is allowed
97 */
98 private static function check_role_access($user, $access_config) {
99 if (empty($access_config['allowed_roles']) || !is_array($access_config['allowed_roles'])) {
100 return false;
101 }
102
103 // Check if user has any of the allowed roles
104 $user_roles = $user->roles;
105 $allowed_roles = $access_config['allowed_roles'];
106
107 return !empty(array_intersect($user_roles, $allowed_roles));
108 }
109
110 /**
111 * Check if user has access based on user ID
112 *
113 * @param WP_User $user Current user object
114 * @param array $access_config Access configuration
115 * @return bool True if user ID is in allowed users
116 */
117 private static function check_user_access($user, $access_config) {
118 if (empty($access_config['allowed_users']) || !is_array($access_config['allowed_users'])) {
119 return false;
120 }
121
122 return in_array($user->ID, array_map('intval', $access_config['allowed_users']));
123 }
124
125 /**
126 * Get access control configuration for a feature
127 *
128 * @param string $feature_key Feature identifier
129 * @return array Access control configuration
130 */
131 public static function get_feature_config($feature_key) {
132 $whitelabel_settings = Metasync::get_whitelabel_settings();
133
134 $default_config = array(
135 'enabled' => false,
136 'type' => 'all',
137 'allowed_roles' => array(),
138 'allowed_users' => array()
139 );
140
141 // Check if new access control format exists
142 if (!isset($whitelabel_settings['access_control'][$feature_key])) {
143 // Check for old format (legacy hide checkbox) and migrate
144 if (!empty($whitelabel_settings[$feature_key])) {
145 // Old format was enabled (feature was hidden), migrate to new format
146 return array(
147 'enabled' => true,
148 'type' => 'none', // Old hide logic = hide from everyone
149 'allowed_roles' => array(),
150 'allowed_users' => array()
151 );
152 }
153 return $default_config;
154 }
155
156 return wp_parse_args($whitelabel_settings['access_control'][$feature_key], $default_config);
157 }
158
159 /**
160 * Save access control configuration for a feature
161 *
162 * @param string $feature_key Feature identifier
163 * @param array $config Configuration array
164 * @return bool True on success, false on failure
165 */
166 public static function save_feature_config($feature_key, $config) {
167 $options = get_option('metasync_options', array());
168
169 if (!isset($options['whitelabel'])) {
170 $options['whitelabel'] = array();
171 }
172
173 if (!isset($options['whitelabel']['access_control'])) {
174 $options['whitelabel']['access_control'] = array();
175 }
176
177 // Sanitize configuration
178 $sanitized_config = array(
179 'enabled' => !empty($config['enabled']),
180 'type' => in_array($config['type'], array('all', 'role', 'user', 'none')) ? $config['type'] : 'all',
181 'allowed_roles' => isset($config['allowed_roles']) && is_array($config['allowed_roles'])
182 ? array_map('sanitize_text_field', $config['allowed_roles'])
183 : array(),
184 'allowed_users' => isset($config['allowed_users']) && is_array($config['allowed_users'])
185 ? array_map('intval', $config['allowed_users'])
186 : array()
187 );
188
189 $options['whitelabel']['access_control'][$feature_key] = $sanitized_config;
190
191 return update_option('metasync_options', $options);
192 }
193
194 /**
195 * Get all WordPress user roles that can access the plugin
196 *
197 * Only returns roles that have 'manage_options' capability (required for plugin access)
198 *
199 * @return array Array of role slug => role name
200 */
201 public static function get_wordpress_roles() {
202 global $wp_roles;
203
204 if (!isset($wp_roles)) {
205 $wp_roles = new WP_Roles();
206 }
207
208 $all_roles = $wp_roles->get_names();
209 $filtered_roles = array();
210
211 // Only include roles that have manage_options capability
212 foreach ($all_roles as $role_slug => $role_name) {
213 $role = get_role($role_slug);
214 if ($role && $role->has_cap('manage_options')) {
215 $filtered_roles[$role_slug] = $role_name;
216 }
217 }
218
219 return $filtered_roles;
220 }
221
222 /**
223 * Get all users who can access the plugin (for dropdown selection)
224 *
225 * Only returns users with 'manage_options' capability (required for plugin access)
226 *
227 * @param array $args Optional arguments for get_users
228 * @return array Array of user objects
229 */
230 public static function get_users($args = array()) {
231 // Filter at the query level instead of slicing an arbitrary first
232 // 100 users: on sites with more users than that, administrators past
233 // the cap silently disappeared from the per-user access dropdown.
234 // The capability argument needs WP 5.9+; the user_can() loop below
235 // still covers older versions.
236 $default_args = array(
237 'orderby' => 'display_name',
238 'order' => 'ASC',
239 'capability' => 'manage_options',
240 );
241
242 $args = wp_parse_args($args, $default_args);
243 $all_users = get_users($args);
244 $filtered_users = array();
245
246 // Only include users who have manage_options capability
247 foreach ($all_users as $user) {
248 if (user_can($user, 'manage_options')) {
249 $filtered_users[] = $user;
250 }
251 }
252
253 return $filtered_users;
254 }
255
256 /**
257 * Sanitize access control settings from form submission
258 *
259 * @param array $form_data Form data from whitelabel settings (just the access_control array)
260 * @return array Sanitized access control configuration
261 */
262 public static function sanitize_access_control($form_data) {
263 if (!is_array($form_data)) {
264 return array();
265 }
266
267 $sanitized_access_control = array();
268
269 // Process ALL features, not just ones in form_data
270 // This ensures disabled features are properly saved with enabled=false
271 foreach (self::$features as $feature_key => $feature_name) {
272 $config = isset($form_data[$feature_key]) ? $form_data[$feature_key] : array();
273
274 $sanitized_config = array(
275 'enabled' => !empty($config['enabled']),
276 'type' => isset($config['type']) && in_array($config['type'], array('all', 'role', 'user', 'none'))
277 ? $config['type']
278 : 'all',
279 'allowed_roles' => array(),
280 'allowed_users' => array()
281 );
282
283 // Process allowed roles
284 if ($sanitized_config['type'] === 'role' && isset($config['allowed_roles']) && is_array($config['allowed_roles'])) {
285 $sanitized_config['allowed_roles'] = array_map('sanitize_text_field', $config['allowed_roles']);
286 }
287
288 // Process allowed users
289 if ($sanitized_config['type'] === 'user' && isset($config['allowed_users']) && is_array($config['allowed_users'])) {
290 $sanitized_config['allowed_users'] = array_map('intval', $config['allowed_users']);
291 }
292
293 $sanitized_access_control[$feature_key] = $sanitized_config;
294 }
295
296 return $sanitized_access_control;
297 }
298
299 /**
300 * Bulk update access control settings from form submission
301 * (For backward compatibility and direct updates)
302 *
303 * @param array $form_data Form data from whitelabel settings
304 * @return bool True on success
305 */
306 public static function process_bulk_update($form_data) {
307 if (!isset($form_data['access_control']) || !is_array($form_data['access_control'])) {
308 return false;
309 }
310
311 $options = get_option('metasync_options', array());
312
313 if (!isset($options['whitelabel'])) {
314 $options['whitelabel'] = array();
315 }
316
317 $options['whitelabel']['access_control'] = self::sanitize_access_control($form_data['access_control']);
318
319 return update_option('metasync_options', $options);
320 }
321
322 /**
323 * Clear all access control settings
324 *
325 * @return bool True on success
326 */
327 public static function clear_all_settings() {
328 $options = get_option('metasync_options', array());
329
330 if (isset($options['whitelabel']['access_control'])) {
331 unset($options['whitelabel']['access_control']);
332 }
333
334 return update_option('metasync_options', $options);
335 }
336 }
337