PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.7.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.7.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
← All changes | includes/core/class-role-manager.php +48 -0 2.0.02.7.0 View file →
@@ -34,9 +34,57 @@
34 34 * @return void
35 35 */
36 36 public function init(): void {
37 37 add_action('init', [Capability_Manager::class, 'ensure']);
38 + add_filter('user_has_cap', [$this, 'grant_admin_caps'], 10, 2);
38 39 add_filter('rest_pre_dispatch', [$this, 'gate_rest'], 10, 3);
40 + }
41 +
42 + /**
43 + * Give every ThinkRank capability to anyone who can `manage_options`.
44 + *
45 + * The bypass already existed, but only where the plugin could see it.
46 + * Capability_Manager::current_user_can() is a plugin static, invisible to
47 + * WordPress core — and add_menu_page() evaluates its capability argument
48 + * with core's current_user_can(). Meanwhile Capability_Manager::ensure()
49 + * grants the capabilities to the `administrator` role by name.
50 + *
51 + * So a user holding manage_options through some other role — a multisite
52 + * super admin, or a custom admin role from Members / User Role Editor —
53 + * passed every REST check and saw no ThinkRank menu at all: the plugin was
54 + * invisible in wp-admin while fully reachable over the API (#575).
55 + * Expressing the bypass as a core filter closes that split and makes the
56 + * explicit check in Capability_Manager belt-and-braces rather than the only
57 + * path.
58 + *
59 + * Uses `+` rather than array_merge: an entry already present keeps its
60 + * value, so an explicit denial elsewhere is not resurrected here.
61 + *
62 + * @since 2.1.3
63 + *
64 + * @param array $allcaps Capabilities the user holds.
65 + * @param array $caps Capabilities being checked (unused).
66 + * @return array
67 + */
68 + public function grant_admin_caps(array $allcaps, array $caps): array {
69 + if (empty($allcaps['manage_options'])) {
70 + return $allcaps;
71 + }
72 +
73 + // Built once per request. Uses slugs() rather than capabilities():
74 + // core fires this filter from wp_set_current_user() during
75 + // wp-settings.php, before `init`, so the __() calls behind the labelled
76 + // map are both wasted (only the keys are used) and early enough to earn
77 + // a _load_textdomain_just_in_time notice on every request (#580).
78 + static $thinkrank_caps = null;
79 + if (null === $thinkrank_caps) {
80 + $thinkrank_caps = array_fill_keys(
81 + Capability_Manager::slugs(),
82 + true
83 + );
84 + }
85 +
86 + return $allcaps + $thinkrank_caps;
39 87 }
40 88
41 89 /**
42 90 * Central capability gate for all ThinkRank REST routes.