User Role Editor Pro version 4.66 was pulished at August 25, 2026. It mainly technical update, which better follows PHP and WordPress coding and security standards.
Changes List
- Core version: 4.66.1
- Update: Marked as compatible with WordPress 7.1
- Update: Required PHP version increased up to 7.4
- Update: Plugin loading code is enhanced.
- Update: Plugin does not use self-defined PHP global constants. Needed data moved inside classes.
- Update: “Admin menu access” add-on: White list of URL arguments allowed by default for WooCommerce products and shop orders list pages was updated.
- Fix: URE_Assign_Role_Pro::get_users_queued() referenced an undefined constant instead of self::CRON_ACTION_HOOK.
- Fix: URE_Assign_Role_Pro::assign_role_to_user() used a loose in_array() check against $user->caps that was always true, so the background role-assignment feature never actually assigned the role; now correctly checks $user->roles.
- Fix: “Posts Edit Access” bulk action’s user ID list could contain stray whitespace instead of clean integers; user IDs are now properly cast to int.
- Update: URE_Uninstall_Pro::init_options_list() now references addon classes own *_KEY constants instead of duplicating their option name strings.
- Fix: Activating Pro while the free plugin was already active still left both active in some load orders, because URE_Core_Pro::init() (which registered the fix above) was itself skipped when the free plugin had already defined URE_Loader/URE_Core earlier in the same request; the activation-hook registration now happens unconditionally via a standalone function in the main plugin file.
- Update: Core version was updated to 4.66.1
- Update: URE_Admin_Notice class output was escaped with esc_attr(), wp_kses_post() functions.
- Security Fix: SQL queries in URE_Editor::direct_network_roles_update() and leave_roles_for_blog() are passed to $wpdb->prepare() with real %s placeholders.
- Security Fix: URE_Editor::get_caps_columns_quant() now requires a valid nonce before writing a display-preference transient from $_POST, closing a minor CSRF gap.
- Fix: URE_Protect_Admin used a bitwise “&” instead of a logical “&&” when checking a capabilities array, which could throw a PHP 8 TypeError; fixed to use “&&”, and the related IN() SQL clause is now hardened with array_map(‘absint’, …).
- Update: Nonce actions used on the Settings/Tools pages are now scoped per form (ure_settings_update, ure_addons_settings_update, ure_default_roles_update, ure_settings_ms_update, ure_settings_tools_exec) instead of one shared string.
- Update: Additional output escaping was added across URE_View, URE_Role_View and URE_Role_Additional_Options (role/capability slugs, wp_json_encode() instead of json_encode(), esc_url() on form actions), plus a defense-in-depth capability check in URE_Role_Additional_Options::save().
- Update: rel=”noopener noreferrer” was added to external links opened with target=”_new”.
- Update: Hardcoded text strings in the role editor toolbar are now translatable.
- Fix: URE_Assign_Role used the %i SQL placeholder, which needs WordPress 6.2+, below the plugin’s declared minimum; replaced with direct interpolation of internal table names.
- Fix: URE_Editor::reset_user_roles() had an unescaped wp_die() message; further output escaping (esc_url(), esc_html(), absint()) was added across URE_Base_Lib, URE_Editor, URE_User_Other_Roles and URE_User_View.
- Fix: Several request-var/database-result comparisons that could be bypassed by PHP type juggling are now strict, including URE_Grant_Roles::is_try_remove_admin_from_himself()’s “can’t remove your own admin role” check.
- Fix: URE_Base_Lib::set() now correctly rejects unknown properties instead of silently creating them; URE_View declares its $advert property explicitly.
- Update: $_SERVER[‘REQUEST_URI’] is now validated and unslashed before sanitizing in URE_Lib::is_right_admin_path() and URE_User_Other_Roles::is_user_profile_extention_allowed().
- Update: Posted role IDs are now sanitized (sanitize_key(), wp_unslash()) in URE_Editor, and its ‘object’/role-selection request parameters are constrained to known values.
- Update: URE_Base_Lib::get_blog_ids() now uses get_sites() instead of a raw database query.
- Update: URE_Capability::revoke_caps() now uses get_users() instead of a raw database query.
- Update: URE_Protect_Admin::has_administrator_role() now uses user_can() instead of a raw database query.
- Fix: URE_Assign_Role::$lib property was changed to protected.
- Fix: URE_Uninstall::delete_options() private function changed to protected.
- Fix: URE_Uninstall::init_options_list() referenced ‘ure_task_queue’, which never matched URE_Task_Queue::OPTION_NAME (‘ure_tasks_queue’), so that option was never deleted on uninstall.
- Fix: URE_Core::define_files() – class URE_Uninstall was not added correctly, null was written instead of class name.
- Fix: Activating Pro while the free version was already active caused a fatal “Cannot redeclare ure_log_error()” error; the function declaration is now guarded with function_exists().
- Fix: Activating this plugin while the paired Pro plugin was already active silently left both active instead of deactivating the paired one, because the register_activation_hook() call never ran in that request; it’s now registered as a standalone function directly in the main plugin file, ahead of the class_exists(‘URE_Loader’) guard that was skipping it.