Changeset 3490094
- Timestamp:
- 03/24/2026 02:16:10 PM (5 days ago)
- Location:
- dp-admin-access-menu
- Files:
-
- 3 edited
- 10 copied
-
tags/1.0.2 (copied) (copied from dp-admin-access-menu/trunk)
-
tags/1.0.2/assets (copied) (copied from dp-admin-access-menu/trunk/assets)
-
tags/1.0.2/assets/screenshots/icon-256x256.png (copied) (copied from dp-admin-access-menu/trunk/assets/screenshots/icon-256x256.png)
-
tags/1.0.2/deploy-to-svn.sh (copied) (copied from dp-admin-access-menu/trunk/deploy-to-svn.sh)
-
tags/1.0.2/dp-admin-access-menu.php (copied) (copied from dp-admin-access-menu/trunk/dp-admin-access-menu.php) (2 diffs)
-
tags/1.0.2/includes (copied) (copied from dp-admin-access-menu/trunk/includes)
-
tags/1.0.2/includes/class-dpama-menu-filter.php (copied) (copied from dp-admin-access-menu/trunk/includes/class-dpama-menu-filter.php) (10 diffs)
-
tags/1.0.2/languages (copied) (copied from dp-admin-access-menu/trunk/languages)
-
tags/1.0.2/readme.txt (copied) (copied from dp-admin-access-menu/trunk/readme.txt) (3 diffs)
-
tags/1.0.2/uninstall.php (copied) (copied from dp-admin-access-menu/trunk/uninstall.php)
-
trunk/dp-admin-access-menu.php (modified) (2 diffs)
-
trunk/includes/class-dpama-menu-filter.php (modified) (10 diffs)
-
trunk/readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
dp-admin-access-menu/tags/1.0.2/dp-admin-access-menu.php
r3487377 r3490094 4 4 * Plugin URI: https://wordpress.org/plugins/dp-admin-access-menu 5 5 * Description: Control which WordPress backend menu items are visible to specific users. Perfect for managing user access and customizing admin experience. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Author: devpriyanshu 8 8 * Author URI: https://profiles.wordpress.org/devpriyanshu/ … … 21 21 22 22 // Define plugin constants 23 define('DPAMA_VERSION', '1.0. 1');23 define('DPAMA_VERSION', '1.0.2'); 24 24 define('DPAMA_PLUGIN_DIR', plugin_dir_path(__FILE__)); 25 25 define('DPAMA_PLUGIN_URL', plugin_dir_url(__FILE__)); -
dp-admin-access-menu/tags/1.0.2/includes/class-dpama-menu-filter.php
r3487377 r3490094 44 44 45 45 $allowed_menus = $settings[$current_user_id]; 46 $normalized_allowed_menus = $this->normalize_menu_ids($allowed_menus); 46 47 global $menu, $submenu; 47 48 … … 59 60 60 61 // Only show menus that are explicitly in the allowed list 61 if (! in_array($menu_id, $allowed_menus)) {62 if (!$this->is_menu_allowed($menu_id, $normalized_allowed_menus)) { 62 63 // Mark for removal 63 64 $menus_to_remove[] = $menu_key; … … 76 77 77 78 // Only show child menus that are explicitly in the allowed list 78 if (! in_array($submenu_id, $allowed_menus)) {79 if (!$this->is_menu_allowed($submenu_id, $normalized_allowed_menus)) { 79 80 $children_to_remove[] = $submenu_key; 80 81 } … … 189 190 190 191 $allowed_menus = $settings[$current_user_id]; 192 $normalized_allowed_menus = $this->normalize_menu_ids($allowed_menus); 191 193 192 194 // Get current page being accessed … … 215 217 foreach ($current_page_candidates as $candidate_page) { 216 218 // Direct match 217 if ( in_array($candidate_page, $allowed_menus, true)) {219 if ($this->is_menu_allowed($candidate_page, $normalized_allowed_menus)) { 218 220 $page_allowed = true; 219 221 break; … … 221 223 222 224 // Check for partial matches (for query string variations) 223 foreach ($ allowed_menus as $allowed_menu) {225 foreach ($normalized_allowed_menus as $allowed_menu) { 224 226 // If current page starts with allowed menu or vice versa 225 227 if (strpos($candidate_page, $allowed_menu) === 0 || strpos($allowed_menu, $candidate_page) === 0) { … … 308 310 } 309 311 310 // For taxonomy pages312 // For taxonomy listing/create pages 311 313 if ($pagenow === 'edit-tags.php') { 312 314 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameters … … 315 317 $post_type = isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : 'post'; 316 318 317 if ($post_type === 'post') { 318 return 'edit.php'; 319 } elseif ($post_type === 'page') { 320 return 'edit.php?post_type=page'; 321 } else { 322 return 'edit.php?post_type=' . $post_type; 323 } 319 if (!empty($taxonomy)) { 320 if ($post_type === 'post') { 321 return 'edit-tags.php?taxonomy=' . $taxonomy; 322 } 323 return 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type; 324 } 325 326 // Fallback when taxonomy is missing. 327 return 'edit-tags.php'; 328 } 329 330 // For taxonomy term edit pages (e.g. WooCommerce product category edit). 331 if ($pagenow === 'term.php') { 332 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameter 333 $taxonomy = isset($_GET['taxonomy']) ? sanitize_text_field(wp_unslash($_GET['taxonomy'])) : ''; 334 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameter 335 $post_type = isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : 'post'; 336 337 if (!empty($taxonomy)) { 338 if ($post_type === 'post') { 339 return 'term.php?taxonomy=' . $taxonomy; 340 } 341 return 'term.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type; 342 } 343 344 return 'term.php'; 324 345 } 325 346 … … 373 394 } 374 395 396 // Taxonomy listing/create pages should allow related term edit pages and vice versa. 397 if (strpos($current_page, 'edit-tags.php?taxonomy=') === 0) { 398 $candidates[] = str_replace('edit-tags.php?', 'term.php?', $current_page); 399 } elseif (strpos($current_page, 'term.php?taxonomy=') === 0) { 400 $candidates[] = str_replace('term.php?', 'edit-tags.php?', $current_page); 401 } 402 375 403 return array_values(array_unique($candidates)); 376 404 } … … 393 421 return $target_user_id > 0 && $target_user_id === (int) $superadmin_id; 394 422 } 423 424 /** 425 * Normalize a list of menu IDs for reliable matching. 426 * 427 * @param array $menu_ids Raw menu IDs. 428 * @return array 429 */ 430 private function normalize_menu_ids($menu_ids) { 431 if (!is_array($menu_ids)) { 432 return array(); 433 } 434 435 $normalized = array(); 436 foreach ($menu_ids as $menu_id) { 437 $normalized[] = $this->normalize_menu_id($menu_id); 438 } 439 440 return array_values(array_unique(array_filter($normalized))); 441 } 442 443 /** 444 * Normalize one menu ID (slug + sorted query string). 445 * 446 * @param string $menu_id Raw menu ID. 447 * @return string 448 */ 449 private function normalize_menu_id($menu_id) { 450 $menu_id = html_entity_decode((string) $menu_id, ENT_QUOTES, 'UTF-8'); 451 452 if (strpos($menu_id, '?') === false) { 453 return $menu_id; 454 } 455 456 $parts = wp_parse_url($menu_id); 457 if (!is_array($parts) || empty($parts['path'])) { 458 return $menu_id; 459 } 460 461 if (empty($parts['query'])) { 462 return $parts['path']; 463 } 464 465 $query_args = array(); 466 wp_parse_str($parts['query'], $query_args); 467 ksort($query_args); 468 469 return $parts['path'] . '?' . http_build_query($query_args, '', '&'); 470 } 471 472 /** 473 * Check if menu slug is in the allowed list. 474 * 475 * @param string $menu_id Menu slug to validate. 476 * @param array $normalized_allowed_menus Normalized allowed menu IDs. 477 * @return bool 478 */ 479 private function is_menu_allowed($menu_id, $normalized_allowed_menus) { 480 $normalized_menu_id = $this->normalize_menu_id($menu_id); 481 return in_array($normalized_menu_id, $normalized_allowed_menus, true); 482 } 395 483 } 396 484 -
dp-admin-access-menu/tags/1.0.2/readme.txt
r3487377 r3490094 4 4 Requires at least: 5.0 5 5 Tested up to: 6.9 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 146 146 == Changelog == 147 147 148 = 1.0.2 = 149 * Fixed taxonomy access mapping so allowed Category/Tag permissions correctly allow create and edit term pages (`edit-tags.php` and `term.php`) including WooCommerce product taxonomies. 150 * Improved normalized matching for menu slugs with query parameters to avoid false permission denials. 151 148 152 = 1.0.1 = 149 153 * Fixed user management access mapping so Users menu access correctly allows `user-edit.php` and `user-new.php`. … … 160 164 == Upgrade Notice == 161 165 166 = 1.0.2 = 167 Fixes Category/Tag create-edit permissions for taxonomy pages and improves query-string menu matching. 168 162 169 = 1.0.1 = 163 170 Fixes user edit access behavior for allowed Users menu and adds stricter superadmin account protection. -
dp-admin-access-menu/trunk/dp-admin-access-menu.php
r3487377 r3490094 4 4 * Plugin URI: https://wordpress.org/plugins/dp-admin-access-menu 5 5 * Description: Control which WordPress backend menu items are visible to specific users. Perfect for managing user access and customizing admin experience. 6 * Version: 1.0. 16 * Version: 1.0.2 7 7 * Author: devpriyanshu 8 8 * Author URI: https://profiles.wordpress.org/devpriyanshu/ … … 21 21 22 22 // Define plugin constants 23 define('DPAMA_VERSION', '1.0. 1');23 define('DPAMA_VERSION', '1.0.2'); 24 24 define('DPAMA_PLUGIN_DIR', plugin_dir_path(__FILE__)); 25 25 define('DPAMA_PLUGIN_URL', plugin_dir_url(__FILE__)); -
dp-admin-access-menu/trunk/includes/class-dpama-menu-filter.php
r3487377 r3490094 44 44 45 45 $allowed_menus = $settings[$current_user_id]; 46 $normalized_allowed_menus = $this->normalize_menu_ids($allowed_menus); 46 47 global $menu, $submenu; 47 48 … … 59 60 60 61 // Only show menus that are explicitly in the allowed list 61 if (! in_array($menu_id, $allowed_menus)) {62 if (!$this->is_menu_allowed($menu_id, $normalized_allowed_menus)) { 62 63 // Mark for removal 63 64 $menus_to_remove[] = $menu_key; … … 76 77 77 78 // Only show child menus that are explicitly in the allowed list 78 if (! in_array($submenu_id, $allowed_menus)) {79 if (!$this->is_menu_allowed($submenu_id, $normalized_allowed_menus)) { 79 80 $children_to_remove[] = $submenu_key; 80 81 } … … 189 190 190 191 $allowed_menus = $settings[$current_user_id]; 192 $normalized_allowed_menus = $this->normalize_menu_ids($allowed_menus); 191 193 192 194 // Get current page being accessed … … 215 217 foreach ($current_page_candidates as $candidate_page) { 216 218 // Direct match 217 if ( in_array($candidate_page, $allowed_menus, true)) {219 if ($this->is_menu_allowed($candidate_page, $normalized_allowed_menus)) { 218 220 $page_allowed = true; 219 221 break; … … 221 223 222 224 // Check for partial matches (for query string variations) 223 foreach ($ allowed_menus as $allowed_menu) {225 foreach ($normalized_allowed_menus as $allowed_menu) { 224 226 // If current page starts with allowed menu or vice versa 225 227 if (strpos($candidate_page, $allowed_menu) === 0 || strpos($allowed_menu, $candidate_page) === 0) { … … 308 310 } 309 311 310 // For taxonomy pages312 // For taxonomy listing/create pages 311 313 if ($pagenow === 'edit-tags.php') { 312 314 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameters … … 315 317 $post_type = isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : 'post'; 316 318 317 if ($post_type === 'post') { 318 return 'edit.php'; 319 } elseif ($post_type === 'page') { 320 return 'edit.php?post_type=page'; 321 } else { 322 return 'edit.php?post_type=' . $post_type; 323 } 319 if (!empty($taxonomy)) { 320 if ($post_type === 'post') { 321 return 'edit-tags.php?taxonomy=' . $taxonomy; 322 } 323 return 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type; 324 } 325 326 // Fallback when taxonomy is missing. 327 return 'edit-tags.php'; 328 } 329 330 // For taxonomy term edit pages (e.g. WooCommerce product category edit). 331 if ($pagenow === 'term.php') { 332 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameter 333 $taxonomy = isset($_GET['taxonomy']) ? sanitize_text_field(wp_unslash($_GET['taxonomy'])) : ''; 334 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Not processing form data, just reading URL parameter 335 $post_type = isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : 'post'; 336 337 if (!empty($taxonomy)) { 338 if ($post_type === 'post') { 339 return 'term.php?taxonomy=' . $taxonomy; 340 } 341 return 'term.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type; 342 } 343 344 return 'term.php'; 324 345 } 325 346 … … 373 394 } 374 395 396 // Taxonomy listing/create pages should allow related term edit pages and vice versa. 397 if (strpos($current_page, 'edit-tags.php?taxonomy=') === 0) { 398 $candidates[] = str_replace('edit-tags.php?', 'term.php?', $current_page); 399 } elseif (strpos($current_page, 'term.php?taxonomy=') === 0) { 400 $candidates[] = str_replace('term.php?', 'edit-tags.php?', $current_page); 401 } 402 375 403 return array_values(array_unique($candidates)); 376 404 } … … 393 421 return $target_user_id > 0 && $target_user_id === (int) $superadmin_id; 394 422 } 423 424 /** 425 * Normalize a list of menu IDs for reliable matching. 426 * 427 * @param array $menu_ids Raw menu IDs. 428 * @return array 429 */ 430 private function normalize_menu_ids($menu_ids) { 431 if (!is_array($menu_ids)) { 432 return array(); 433 } 434 435 $normalized = array(); 436 foreach ($menu_ids as $menu_id) { 437 $normalized[] = $this->normalize_menu_id($menu_id); 438 } 439 440 return array_values(array_unique(array_filter($normalized))); 441 } 442 443 /** 444 * Normalize one menu ID (slug + sorted query string). 445 * 446 * @param string $menu_id Raw menu ID. 447 * @return string 448 */ 449 private function normalize_menu_id($menu_id) { 450 $menu_id = html_entity_decode((string) $menu_id, ENT_QUOTES, 'UTF-8'); 451 452 if (strpos($menu_id, '?') === false) { 453 return $menu_id; 454 } 455 456 $parts = wp_parse_url($menu_id); 457 if (!is_array($parts) || empty($parts['path'])) { 458 return $menu_id; 459 } 460 461 if (empty($parts['query'])) { 462 return $parts['path']; 463 } 464 465 $query_args = array(); 466 wp_parse_str($parts['query'], $query_args); 467 ksort($query_args); 468 469 return $parts['path'] . '?' . http_build_query($query_args, '', '&'); 470 } 471 472 /** 473 * Check if menu slug is in the allowed list. 474 * 475 * @param string $menu_id Menu slug to validate. 476 * @param array $normalized_allowed_menus Normalized allowed menu IDs. 477 * @return bool 478 */ 479 private function is_menu_allowed($menu_id, $normalized_allowed_menus) { 480 $normalized_menu_id = $this->normalize_menu_id($menu_id); 481 return in_array($normalized_menu_id, $normalized_allowed_menus, true); 482 } 395 483 } 396 484 -
dp-admin-access-menu/trunk/readme.txt
r3487377 r3490094 4 4 Requires at least: 5.0 5 5 Tested up to: 6.9 6 Stable tag: 1.0. 16 Stable tag: 1.0.2 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 146 146 == Changelog == 147 147 148 = 1.0.2 = 149 * Fixed taxonomy access mapping so allowed Category/Tag permissions correctly allow create and edit term pages (`edit-tags.php` and `term.php`) including WooCommerce product taxonomies. 150 * Improved normalized matching for menu slugs with query parameters to avoid false permission denials. 151 148 152 = 1.0.1 = 149 153 * Fixed user management access mapping so Users menu access correctly allows `user-edit.php` and `user-new.php`. … … 160 164 == Upgrade Notice == 161 165 166 = 1.0.2 = 167 Fixes Category/Tag create-edit permissions for taxonomy pages and improves query-string menu matching. 168 162 169 = 1.0.1 = 163 170 Fixes user edit access behavior for allowed Users menu and adds stricter superadmin account protection.
Note: See TracChangeset
for help on using the changeset viewer.