PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | _inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-ai-feature-settings.php +27 -11 16.3-a.3 → 16.3-beta View file →
@@ -9,19 +9,15 @@
9 9 * POST — accepts a partial update ({ master_enabled, features }) and writes
10 10 * the site-local options backing the toggles. Returns the fresh GET
11 11 * shape.
12 12 *
13 - * Unlike the MCP settings endpoint, nothing here proxies to WPCOM: the
14 - * settings are site-local wp_options, so the endpoint works the same on
15 - * Atomic and self-hosted sites. On WordPress.com Simple the route does not
16 - * register at all — Simple keeps the existing wp.com settings contract, and
17 - * with core settings REST also refusing these options there, the new
18 - * per-feature options stay unwritten on Simple while the reused SEO/Search
19 - * options keep their existing owning surfaces.
13 + * Toggles use site-local options; SEO settings access uses the cached WordPress.com site record.
14 + * WordPress.com Simple keeps its existing settings endpoint.
20 15 *
21 16 * @package automattic/jetpack
22 17 */
23 18
19 +use Automattic\Jetpack\Connection\Manager;
24 20 use Automattic\Jetpack\Current_Plan;
25 21 use Automattic\Jetpack\Search\Plan as Search_Plan;
26 22 use Automattic\Jetpack\SEO\Ai_Seo;
27 23 use Automattic\Jetpack\Status\Host;
@@ -227,9 +223,10 @@
227 223 *
228 224 * @return array
229 225 */
230 226 private function build_settings_response() {
231 - $search_plan = class_exists( Search_Plan::class ) ? new Search_Plan() : null;
227 + $search_plan = class_exists( Search_Plan::class ) ? new Search_Plan() : null;
228 + $is_connected = Jetpack_AI_Settings::site_is_connected();
232 229
233 230 // Entitlement: the plan includes some Search product (Classic or Instant).
234 231 $supports_search = $search_plan && $search_plan->supports_search();
235 232
@@ -247,9 +244,9 @@
247 244 }
248 245
249 246 return array(
250 247 'host_allows_ai' => Jetpack_AI_Settings::host_allows_ai(),
251 - 'is_connected' => Jetpack_AI_Settings::site_is_connected(),
248 + 'is_connected' => $is_connected,
252 249 'is_user_connected' => Jetpack_AI_Settings::user_is_connected(),
253 250 'plan' => array(
254 251 'supports_ai' => class_exists( Current_Plan::class ) && Current_Plan::supports( 'ai-assistant' ),
255 252 'supports_search' => $supports_search,
@@ -266,10 +263,11 @@
266 263 'enabled' => $stored['feature_clip'],
267 264 'available' => $this->is_feature_clip_available(),
268 265 ),
269 266 'ai_seo' => array(
270 - 'enabled' => $stored['ai_seo'],
271 - 'available' => $this->is_ai_seo_available(),
267 + 'enabled' => $stored['ai_seo'],
268 + 'available' => $this->is_ai_seo_available(),
269 + 'can_manage' => $is_connected && $this->can_manage_seo(),
272 270 ),
273 271 'ai_search' => array(
274 272 'enabled' => $stored['ai_search'],
275 273 'requires_upgrade' => $ai_search_requires_upgrade,
@@ -275,8 +273,26 @@
275 273 'requires_upgrade' => $ai_search_requires_upgrade,
276 274 ),
277 275 ),
278 276 );
277 + }
278 +
279 + /**
280 + * Whether the site's active features include SEO settings.
281 + *
282 + * The is_ai_seo_available() check accepts plan defaults, which can report SEO
283 + * support even when site-specific restrictions, such as VIP's, block settings.
284 + *
285 + * @return bool
286 + */
287 + private function can_manage_seo() {
288 + $site_data = ( new Manager( 'jetpack' ) )->get_connected_site_data();
289 + if ( is_wp_error( $site_data ) ) {
290 + return false;
291 + }
292 +
293 + $active_features = $site_data->plan->features->active ?? null;
294 + return is_array( $active_features ) && in_array( 'advanced-seo', $active_features, true );
279 295 }
280 296
281 297 /**
282 298 * Whether the AI SEO row is available, so the settings page can hide it. The