Version Description
- Fixed a conflict with Elementor 3.0.0-beta that caused the "Theme Builder" menu item to have the wrong URL.
- Minor performance optimization.
Download this release
Release Info
| Developer | whiteshadow |
| Plugin | |
| Version | 1.9.7 |
| Comparing to | |
| See all releases | |
Code changes from version 1.9.6 to 1.9.7
- includes/menu-editor-core.php +160 -45
- menu-editor.php +1 -1
- readme.txt +6 -2
includes/menu-editor-core.php
CHANGED
|
@@ -81,6 +81,12 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 81 |
*/
|
| 82 |
private $cached_user_roles = array();
|
| 83 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
/**
|
| 85 |
* @var array An index of URLs relative to /wp-admin/. Any menus that match the index will be ignored.
|
| 86 |
*/
|
|
@@ -335,11 +341,15 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 335 |
//Reset plugin access if the only allowed user gets deleted or their ID changes.
|
| 336 |
add_action('wp_login', array($this, 'maybe_reset_plugin_access'), 10, 2);
|
| 337 |
|
| 338 |
-
//
|
| 339 |
-
|
|
|
|
|
|
|
|
|
|
| 340 |
add_action('set_current_user', array($this, 'update_current_user_cache'), 1, 0); //Run before most plugins.
|
| 341 |
-
|
| 342 |
-
add_action('
|
|
|
|
| 343 |
//There's also a "set_user_role" hook, but it's only called by WP_User::set_role and not WP_User::add_role.
|
| 344 |
//It's also redundant - WP_User::set_role updates user meta, so the above hooks already cover it.
|
| 345 |
|
|
@@ -656,7 +666,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 656 |
$submenu = $this->custom_wp_submenu;
|
| 657 |
|
| 658 |
$this->user_cap_cache_enabled = true;
|
| 659 |
-
|
| 660 |
$this->user_cap_cache_enabled = false;
|
| 661 |
|
| 662 |
do_action('admin_menu_editor-menu_replaced');
|
|
@@ -686,11 +696,13 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 686 |
*
|
| 687 |
* - Adds position-dependent CSS classes.
|
| 688 |
*
|
| 689 |
-
* @
|
| 690 |
-
* @
|
| 691 |
-
*
|
|
|
|
| 692 |
*/
|
| 693 |
-
private function
|
|
|
|
| 694 |
global $_wp_menu_nopriv; //Caution: Modifying this array could lead to unexpected consequences.
|
| 695 |
|
| 696 |
//Remove sub-menus which the user shouldn't be able to access,
|
|
@@ -783,8 +795,6 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 783 |
|
| 784 |
//Add display-specific classes like "menu-top-first" and others.
|
| 785 |
$menu = add_menu_classes($menu);
|
| 786 |
-
|
| 787 |
-
return array($menu, $submenu);
|
| 788 |
}
|
| 789 |
|
| 790 |
public function register_base_dependencies() {
|
|
@@ -1652,7 +1662,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 1652 |
}
|
| 1653 |
}
|
| 1654 |
|
| 1655 |
-
if (
|
| 1656 |
//Iterate over submenu items
|
| 1657 |
foreach ($topmenu['items'] as &$item){
|
| 1658 |
if ( !ameMenuItem::get($item, 'custom') ) {
|
|
@@ -2040,7 +2050,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 2040 |
// menu or the top level. We'll need to adjust the file field to point to the correct URL.
|
| 2041 |
// This is required because WP identifies plugin pages using *both* the plugin file
|
| 2042 |
// and the parent file.
|
| 2043 |
-
if ( $item['template_id'] !== '' &&
|
| 2044 |
$template = $this->item_templates[$item['template_id']];
|
| 2045 |
if ( $template['defaults']['is_plugin_page'] ) {
|
| 2046 |
$default_parent = $template['defaults']['parent'];
|
|
@@ -2112,7 +2122,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 2112 |
|
| 2113 |
//Menus without a custom icon image should have it set to "none" (or "div" in older WP versions).
|
| 2114 |
//See /wp-admin/menu-header.php for details on how this works.
|
| 2115 |
-
if ( $item['icon_url'] === '' ) {
|
| 2116 |
$item['icon_url'] = 'none';
|
| 2117 |
}
|
| 2118 |
|
|
@@ -2157,7 +2167,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 2157 |
|
| 2158 |
//WPML support: Use translated menu titles where available.
|
| 2159 |
if (
|
| 2160 |
-
|
| 2161 |
&& !empty($this->options['wpml_support_enabled'])
|
| 2162 |
) {
|
| 2163 |
$item['menu_title'] = icl_t(
|
|
@@ -2985,6 +2995,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 2985 |
$this->cached_virtual_caps = null;
|
| 2986 |
$this->cached_user_caps = array();
|
| 2987 |
$this->cached_user_roles = array();
|
|
|
|
| 2988 |
|
| 2989 |
if ($this->options['menu_config_scope'] === 'site') {
|
| 2990 |
$this->cached_custom_menu = null;
|
|
@@ -2992,27 +3003,6 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 2992 |
}
|
| 2993 |
}
|
| 2994 |
|
| 2995 |
-
/**
|
| 2996 |
-
* Create a virtual 'super_admin' capability that only super admins have.
|
| 2997 |
-
* This function accomplishes that by by filtering 'user_has_cap' calls.
|
| 2998 |
-
*
|
| 2999 |
-
* @param array $allcaps All capabilities belonging to the current user, cap => true/false.
|
| 3000 |
-
* @param array $required_caps The required capabilities.
|
| 3001 |
-
* @param array $args The capability passed to current_user_can, the current user's ID, and other args.
|
| 3002 |
-
* @return array Filtered version of $allcaps
|
| 3003 |
-
*/
|
| 3004 |
-
function hook_user_has_cap($allcaps, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
|
| 3005 |
-
//Be careful not to overwrite a super_admin cap added by other plugins
|
| 3006 |
-
//For example, Advanced Access Manager also adds this capability.
|
| 3007 |
-
if ( is_array($allcaps) && !isset($allcaps['super_admin']) ){
|
| 3008 |
-
$user_id = intval($args[1]);
|
| 3009 |
-
if ( $user_id != 0 ) {
|
| 3010 |
-
$allcaps['super_admin'] = is_multisite() && is_super_admin($user_id);
|
| 3011 |
-
}
|
| 3012 |
-
}
|
| 3013 |
-
return $allcaps;
|
| 3014 |
-
}
|
| 3015 |
-
|
| 3016 |
/**
|
| 3017 |
* AJAX callback for saving screen options (whether to show or to hide advanced menu options).
|
| 3018 |
*
|
|
@@ -3367,8 +3357,16 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 3367 |
* @return array
|
| 3368 |
*/
|
| 3369 |
private function parse_url($url) {
|
| 3370 |
-
$url_defaults =
|
| 3371 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3372 |
|
| 3373 |
$parsed = @parse_url($url);
|
| 3374 |
if ( !is_array($parsed) ) {
|
|
@@ -3377,7 +3375,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 3377 |
$parsed = array_merge($url_defaults, $parsed);
|
| 3378 |
|
| 3379 |
$params = array();
|
| 3380 |
-
if (!empty($parsed['query'])) {
|
| 3381 |
wp_parse_str($parsed['query'], $params);
|
| 3382 |
};
|
| 3383 |
$parsed['params'] = $params;
|
|
@@ -3458,7 +3456,11 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 3458 |
if ( $len == 0 ) {
|
| 3459 |
return true;
|
| 3460 |
}
|
| 3461 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3462 |
}
|
| 3463 |
|
| 3464 |
public function castValuesToBool($capabilities) {
|
|
@@ -4038,14 +4040,95 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 4038 |
}
|
| 4039 |
|
| 4040 |
/**
|
| 4041 |
-
* The current user has changed;
|
| 4042 |
*/
|
| 4043 |
public function update_current_user_cache() {
|
| 4044 |
$user = wp_get_current_user();
|
| 4045 |
if ( empty($user) || !$user->exists() ) {
|
| 4046 |
return;
|
| 4047 |
}
|
|
|
|
|
|
|
|
|
|
| 4048 |
$this->cached_user_roles[$user->ID] = $this->extract_user_roles($user);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4049 |
}
|
| 4050 |
|
| 4051 |
/**
|
|
@@ -4069,19 +4152,51 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
|
|
| 4069 |
}
|
| 4070 |
|
| 4071 |
/**
|
| 4072 |
-
* User metadata was updated or deleted; invalidate the role
|
| 4073 |
*
|
| 4074 |
-
* Not all metadata updates are related to role changes, but filtering them is non-trivial (meta keys change)
|
| 4075 |
-
* and not really necessary for our purposes.
|
| 4076 |
*
|
| 4077 |
* @param int|array $unused_meta_id
|
| 4078 |
* @param int $user_id
|
|
|
|
|
|
|
| 4079 |
*/
|
| 4080 |
-
public function
|
| 4081 |
if ( empty($user_id) || !is_numeric($user_id) ) {
|
| 4082 |
return;
|
| 4083 |
}
|
|
|
|
| 4084 |
unset($this->cached_user_roles[$user_id]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4085 |
}
|
| 4086 |
|
| 4087 |
/**
|
| 81 |
*/
|
| 82 |
private $cached_user_roles = array();
|
| 83 |
|
| 84 |
+
private $cached_virtual_user_caps = array();
|
| 85 |
+
private $virtual_caps_for_this_call = array();
|
| 86 |
+
|
| 87 |
+
public $disable_virtual_caps = false;
|
| 88 |
+
public $virtual_cap_mode = 3; //self::ALL_VIRTUAL_CAPS
|
| 89 |
+
|
| 90 |
/**
|
| 91 |
* @var array An index of URLs relative to /wp-admin/. Any menus that match the index will be ignored.
|
| 92 |
*/
|
| 341 |
//Reset plugin access if the only allowed user gets deleted or their ID changes.
|
| 342 |
add_action('wp_login', array($this, 'maybe_reset_plugin_access'), 10, 2);
|
| 343 |
|
| 344 |
+
//Grant virtual capabilities like "super_user" to users.
|
| 345 |
+
add_filter('user_has_cap', array($this, 'grant_virtual_caps_to_user'), 9, 3);
|
| 346 |
+
add_filter('user_has_cap', array($this, 'regrant_virtual_caps_to_user'), 200, 1);
|
| 347 |
+
|
| 348 |
+
//Update caches when the current user changes.
|
| 349 |
add_action('set_current_user', array($this, 'update_current_user_cache'), 1, 0); //Run before most plugins.
|
| 350 |
+
//Clear or refresh per-user caches when the user's roles or capabilities change.
|
| 351 |
+
add_action('updated_user_meta', array($this, 'on_user_metadata_changed'), 10, 3);
|
| 352 |
+
add_action('deleted_user_meta', array($this, 'on_user_metadata_changed'), 10, 3);
|
| 353 |
//There's also a "set_user_role" hook, but it's only called by WP_User::set_role and not WP_User::add_role.
|
| 354 |
//It's also redundant - WP_User::set_role updates user meta, so the above hooks already cover it.
|
| 355 |
|
| 666 |
$submenu = $this->custom_wp_submenu;
|
| 667 |
|
| 668 |
$this->user_cap_cache_enabled = true;
|
| 669 |
+
$this->filter_global_menu();
|
| 670 |
$this->user_cap_cache_enabled = false;
|
| 671 |
|
| 672 |
do_action('admin_menu_editor-menu_replaced');
|
| 696 |
*
|
| 697 |
* - Adds position-dependent CSS classes.
|
| 698 |
*
|
| 699 |
+
* @global array $menu
|
| 700 |
+
* @global array $submenu
|
| 701 |
+
*
|
| 702 |
+
* @return void
|
| 703 |
*/
|
| 704 |
+
private function filter_global_menu() {
|
| 705 |
+
global $menu, $submenu;
|
| 706 |
global $_wp_menu_nopriv; //Caution: Modifying this array could lead to unexpected consequences.
|
| 707 |
|
| 708 |
//Remove sub-menus which the user shouldn't be able to access,
|
| 795 |
|
| 796 |
//Add display-specific classes like "menu-top-first" and others.
|
| 797 |
$menu = add_menu_classes($menu);
|
|
|
|
|
|
|
| 798 |
}
|
| 799 |
|
| 800 |
public function register_base_dependencies() {
|
| 1662 |
}
|
| 1663 |
}
|
| 1664 |
|
| 1665 |
+
if (!empty($topmenu['items'])) {
|
| 1666 |
//Iterate over submenu items
|
| 1667 |
foreach ($topmenu['items'] as &$item){
|
| 1668 |
if ( !ameMenuItem::get($item, 'custom') ) {
|
| 2050 |
// menu or the top level. We'll need to adjust the file field to point to the correct URL.
|
| 2051 |
// This is required because WP identifies plugin pages using *both* the plugin file
|
| 2052 |
// and the parent file.
|
| 2053 |
+
if ( $item['template_id'] !== '' && empty($item['separator']) ) {
|
| 2054 |
$template = $this->item_templates[$item['template_id']];
|
| 2055 |
if ( $template['defaults']['is_plugin_page'] ) {
|
| 2056 |
$default_parent = $template['defaults']['parent'];
|
| 2122 |
|
| 2123 |
//Menus without a custom icon image should have it set to "none" (or "div" in older WP versions).
|
| 2124 |
//See /wp-admin/menu-header.php for details on how this works.
|
| 2125 |
+
if ( !isset($item['icon_url']) || ($item['icon_url'] === '') ) {
|
| 2126 |
$item['icon_url'] = 'none';
|
| 2127 |
}
|
| 2128 |
|
| 2167 |
|
| 2168 |
//WPML support: Use translated menu titles where available.
|
| 2169 |
if (
|
| 2170 |
+
empty($item['separator']) && $hasCustomMenuTitle && function_exists('icl_t')
|
| 2171 |
&& !empty($this->options['wpml_support_enabled'])
|
| 2172 |
) {
|
| 2173 |
$item['menu_title'] = icl_t(
|
| 2995 |
$this->cached_virtual_caps = null;
|
| 2996 |
$this->cached_user_caps = array();
|
| 2997 |
$this->cached_user_roles = array();
|
| 2998 |
+
$this->cached_virtual_user_caps = array();
|
| 2999 |
|
| 3000 |
if ($this->options['menu_config_scope'] === 'site') {
|
| 3001 |
$this->cached_custom_menu = null;
|
| 3003 |
}
|
| 3004 |
}
|
| 3005 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3006 |
/**
|
| 3007 |
* AJAX callback for saving screen options (whether to show or to hide advanced menu options).
|
| 3008 |
*
|
| 3357 |
* @return array
|
| 3358 |
*/
|
| 3359 |
private function parse_url($url) {
|
| 3360 |
+
static $url_defaults = array(
|
| 3361 |
+
'scheme' => '',
|
| 3362 |
+
'host' => '',
|
| 3363 |
+
'port' => '80',
|
| 3364 |
+
'user' => '',
|
| 3365 |
+
'pass' => '',
|
| 3366 |
+
'path' => '',
|
| 3367 |
+
'query' => '',
|
| 3368 |
+
'fragment' => '',
|
| 3369 |
+
);
|
| 3370 |
|
| 3371 |
$parsed = @parse_url($url);
|
| 3372 |
if ( !is_array($parsed) ) {
|
| 3375 |
$parsed = array_merge($url_defaults, $parsed);
|
| 3376 |
|
| 3377 |
$params = array();
|
| 3378 |
+
if ( !empty($parsed['query']) ) {
|
| 3379 |
wp_parse_str($parsed['query'], $params);
|
| 3380 |
};
|
| 3381 |
$parsed['params'] = $params;
|
| 3456 |
if ( $len == 0 ) {
|
| 3457 |
return true;
|
| 3458 |
}
|
| 3459 |
+
$inputLen = strlen($string);
|
| 3460 |
+
if ( $len > $inputLen ) {
|
| 3461 |
+
return false;
|
| 3462 |
+
}
|
| 3463 |
+
return substr_compare($string, $suffix, $inputLen - $len) === 0;
|
| 3464 |
}
|
| 3465 |
|
| 3466 |
public function castValuesToBool($capabilities) {
|
| 4040 |
}
|
| 4041 |
|
| 4042 |
/**
|
| 4043 |
+
* The current user has changed; update role and capability caches.
|
| 4044 |
*/
|
| 4045 |
public function update_current_user_cache() {
|
| 4046 |
$user = wp_get_current_user();
|
| 4047 |
if ( empty($user) || !$user->exists() ) {
|
| 4048 |
return;
|
| 4049 |
}
|
| 4050 |
+
|
| 4051 |
+
//Workaround for buggy plugins that unintentionally remove user roles.
|
| 4052 |
+
/** @see WPMenuEditor::get_user_roles */
|
| 4053 |
$this->cached_user_roles[$user->ID] = $this->extract_user_roles($user);
|
| 4054 |
+
|
| 4055 |
+
$this->update_virtual_cap_cache($user);
|
| 4056 |
+
}
|
| 4057 |
+
|
| 4058 |
+
/**
|
| 4059 |
+
* @param WP_User $user
|
| 4060 |
+
*/
|
| 4061 |
+
private function update_virtual_cap_cache($user) {
|
| 4062 |
+
if ( $user === null ) {
|
| 4063 |
+
return;
|
| 4064 |
+
}
|
| 4065 |
+
|
| 4066 |
+
$virtual_caps = array(
|
| 4067 |
+
self::ALL_VIRTUAL_CAPS => array(),
|
| 4068 |
+
self::DIRECTLY_GRANTED_VIRTUAL_CAPS => array(),
|
| 4069 |
+
);
|
| 4070 |
+
|
| 4071 |
+
//Create a virtual 'super_admin' capability that only super admins have. Be careful not to overwrite
|
| 4072 |
+
//the same cap added by other plugins. For example, Advanced Access Manager also adds this capability.
|
| 4073 |
+
if ( !isset($user->allcaps['super_admin']) ) {
|
| 4074 |
+
$virtual_caps[self::ALL_VIRTUAL_CAPS]['super_admin'] = is_multisite() && is_super_admin($user->ID);
|
| 4075 |
+
}
|
| 4076 |
+
|
| 4077 |
+
$virtual_caps = apply_filters('admin_menu_editor-virtual_caps', $virtual_caps, $user);
|
| 4078 |
+
$this->cached_virtual_user_caps[$user->ID] = $virtual_caps;
|
| 4079 |
+
}
|
| 4080 |
+
|
| 4081 |
+
/**
|
| 4082 |
+
* Grant virtual caps to the user.
|
| 4083 |
+
*
|
| 4084 |
+
* @param array $capabilities All capabilities belonging to the specified user, cap => true/false.
|
| 4085 |
+
* @param array $required_caps The required capabilities.
|
| 4086 |
+
* @param array $args The capability passed to current_user_can, the user's ID, and other args.
|
| 4087 |
+
* @return array Filtered list of capabilities.
|
| 4088 |
+
*/
|
| 4089 |
+
function grant_virtual_caps_to_user($capabilities, /** @noinspection PhpUnusedParameterInspection */ $required_caps, $args){
|
| 4090 |
+
$this->virtual_caps_for_this_call = array();
|
| 4091 |
+
|
| 4092 |
+
if ( $this->disable_virtual_caps ) {
|
| 4093 |
+
return $capabilities;
|
| 4094 |
+
}
|
| 4095 |
+
|
| 4096 |
+
//The second entry of the $args array should be the user ID
|
| 4097 |
+
if ( count($args) < 2 ) {
|
| 4098 |
+
return $capabilities;
|
| 4099 |
+
}
|
| 4100 |
+
$user_id = intval($args[1]);
|
| 4101 |
+
|
| 4102 |
+
if ( !isset($this->cached_virtual_user_caps[$user_id]) ) {
|
| 4103 |
+
$this->update_virtual_cap_cache($this->get_user_by_id($user_id));
|
| 4104 |
+
}
|
| 4105 |
+
|
| 4106 |
+
if ( empty($this->cached_virtual_user_caps[$user_id][$this->virtual_cap_mode]) ) {
|
| 4107 |
+
return $capabilities;
|
| 4108 |
+
}
|
| 4109 |
+
|
| 4110 |
+
$this->virtual_caps_for_this_call = $this->cached_virtual_user_caps[$user_id][$this->virtual_cap_mode];
|
| 4111 |
+
|
| 4112 |
+
$capabilities = array_merge($capabilities, $this->virtual_caps_for_this_call);
|
| 4113 |
+
return $capabilities;
|
| 4114 |
+
}
|
| 4115 |
+
|
| 4116 |
+
/**
|
| 4117 |
+
* Set the capabilities that were already set by grant_virtual_caps_to_user() again.
|
| 4118 |
+
*
|
| 4119 |
+
* The goal of granting the same capabilities twice at different hook priorities is to:
|
| 4120 |
+
* 1) Make sure meta caps that rely on the granted caps are enabled.
|
| 4121 |
+
* 2) Reduce the risk that the granted caps will be overridden by other plugins.
|
| 4122 |
+
*
|
| 4123 |
+
* @param array $capabilities
|
| 4124 |
+
* @return array
|
| 4125 |
+
*/
|
| 4126 |
+
public function regrant_virtual_caps_to_user($capabilities) {
|
| 4127 |
+
if ( !empty($this->virtual_caps_for_this_call) ) {
|
| 4128 |
+
$capabilities = array_merge($capabilities, $this->virtual_caps_for_this_call);
|
| 4129 |
+
$this->virtual_caps_for_this_call = array();
|
| 4130 |
+
}
|
| 4131 |
+
return $capabilities;
|
| 4132 |
}
|
| 4133 |
|
| 4134 |
/**
|
| 4152 |
}
|
| 4153 |
|
| 4154 |
/**
|
| 4155 |
+
* User metadata was updated or deleted; refresh or invalidate the associated role/capability caches.
|
| 4156 |
*
|
| 4157 |
+
* Not all metadata updates are related to role changes, but filtering them is non-trivial (meta keys change).
|
|
|
|
| 4158 |
*
|
| 4159 |
* @param int|array $unused_meta_id
|
| 4160 |
* @param int $user_id
|
| 4161 |
+
* @param string $meta_key
|
| 4162 |
+
* @noinspection PhpUnusedParameterInspection
|
| 4163 |
*/
|
| 4164 |
+
public function on_user_metadata_changed($unused_meta_id, $user_id, $meta_key) {
|
| 4165 |
if ( empty($user_id) || !is_numeric($user_id) ) {
|
| 4166 |
return;
|
| 4167 |
}
|
| 4168 |
+
//Clear the user role cache.
|
| 4169 |
unset($this->cached_user_roles[$user_id]);
|
| 4170 |
+
|
| 4171 |
+
$this->virtual_caps_for_this_call = array();
|
| 4172 |
+
|
| 4173 |
+
//Did this update change user capabilities or roles? If so, refresh virtual caps.
|
| 4174 |
+
$user = $this->get_user_by_id($user_id);
|
| 4175 |
+
if ( $meta_key === $user->cap_key ) {
|
| 4176 |
+
$this->update_virtual_cap_cache($user);
|
| 4177 |
+
}
|
| 4178 |
+
}
|
| 4179 |
+
|
| 4180 |
+
/**
|
| 4181 |
+
* Get the user object based on a user ID.
|
| 4182 |
+
*
|
| 4183 |
+
* In most cases, when this plugin needs to retrieve a user, it is the current user. This method
|
| 4184 |
+
* attempts to make that common case faster.
|
| 4185 |
+
*
|
| 4186 |
+
* @param int $user_id
|
| 4187 |
+
* @return WP_User|null
|
| 4188 |
+
*/
|
| 4189 |
+
private function get_user_by_id($user_id) {
|
| 4190 |
+
$current_user = wp_get_current_user();
|
| 4191 |
+
if ( $current_user->ID == $user_id ) {
|
| 4192 |
+
$user = $current_user;
|
| 4193 |
+
} else {
|
| 4194 |
+
$user = get_user_by('id', $user_id);
|
| 4195 |
+
if ( $user === false ) {
|
| 4196 |
+
return null;
|
| 4197 |
+
}
|
| 4198 |
+
}
|
| 4199 |
+
return $user;
|
| 4200 |
}
|
| 4201 |
|
| 4202 |
/**
|
menu-editor.php
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
Plugin Name: Admin Menu Editor
|
| 4 |
Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
|
| 5 |
Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
| 6 |
-
Version: 1.9.
|
| 7 |
Author: Janis Elsts
|
| 8 |
Author URI: http://w-shadow.com/blog/
|
| 9 |
*/
|
| 3 |
Plugin Name: Admin Menu Editor
|
| 4 |
Plugin URI: http://w-shadow.com/blog/2008/12/20/admin-menu-editor-for-wordpress/
|
| 5 |
Description: Lets you directly edit the WordPress admin menu. You can re-order, hide or rename existing menus, add custom menus and more.
|
| 6 |
+
Version: 1.9.7
|
| 7 |
Author: Janis Elsts
|
| 8 |
Author URI: http://w-shadow.com/blog/
|
| 9 |
*/
|
readme.txt
CHANGED
|
@@ -3,8 +3,8 @@ Contributors: whiteshadow
|
|
| 3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
|
| 4 |
Tags: admin, dashboard, menu, security, wpmu
|
| 5 |
Requires at least: 4.1
|
| 6 |
-
Tested up to: 5.
|
| 7 |
-
Stable tag: 1.9.
|
| 8 |
|
| 9 |
Lets you edit the WordPress admin menu. You can re-order, hide or rename menus, add custom menus and more.
|
| 10 |
|
|
@@ -63,6 +63,10 @@ Plugins installed in the `mu-plugins` directory are treated as "always on", so y
|
|
| 63 |
|
| 64 |
== Changelog ==
|
| 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
= 1.9.6 =
|
| 67 |
* Added an option to disable WPML support.
|
| 68 |
* Fixed a minor WP 5.5 compatibility issue where some of the boxes shown on the menu settings page were displayed incorrectly.
|
| 3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6P9S6CE3SRSW
|
| 4 |
Tags: admin, dashboard, menu, security, wpmu
|
| 5 |
Requires at least: 4.1
|
| 6 |
+
Tested up to: 5.6
|
| 7 |
+
Stable tag: 1.9.7
|
| 8 |
|
| 9 |
Lets you edit the WordPress admin menu. You can re-order, hide or rename menus, add custom menus and more.
|
| 10 |
|
| 63 |
|
| 64 |
== Changelog ==
|
| 65 |
|
| 66 |
+
= 1.9.7 =
|
| 67 |
+
* Fixed a conflict with Elementor 3.0.0-beta that caused the "Theme Builder" menu item to have the wrong URL.
|
| 68 |
+
* Minor performance optimization.
|
| 69 |
+
|
| 70 |
= 1.9.6 =
|
| 71 |
* Added an option to disable WPML support.
|
| 72 |
* Fixed a minor WP 5.5 compatibility issue where some of the boxes shown on the menu settings page were displayed incorrectly.
|
