PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3 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 All 508 releases
← All changes | _inc/lib/class-jetpack-ai-settings.php +8 -113 16.3-a.5 → 16.3-a.1 View file →
@@ -19,11 +19,9 @@
19 19 *
20 20 * @package automattic/jetpack
21 21 */
22 22
23 -use Automattic\Jetpack\Connection\Manager;
24 23 use Automattic\Jetpack\Modules;
25 -use Automattic\Jetpack\Status;
26 24 use Automattic\Jetpack\Status\Host;
27 25
28 26 if ( ! defined( 'ABSPATH' ) ) {
29 27 exit( 0 );
@@ -55,32 +53,8 @@
55 53 */
56 54 const AI_MODULE = 'ai';
57 55
58 56 /**
59 - * The `jetpack_ai_enabled` route custom code can take to hold AI off, as
60 - * reported by {@see self::get_master_forced_off_route()}. Each route names a
61 - * different hook, so each needs its own documentation link.
62 - *
63 - * @var string
64 - */
65 - const FORCED_OFF_ROUTE_FILTER = 'filter';
66 -
67 - /**
68 - * The module-filter route; see {@see self::FORCED_OFF_ROUTE_FILTER}.
69 - *
70 - * @var string
71 - */
72 - const FORCED_OFF_ROUTE_MODULES = 'modules';
73 -
74 - /**
75 - * The filter route on VIP, which documents this filter as its own supported
76 - * off switch and so owns the page to send the reader to.
77 - *
78 - * @var string
79 - */
80 - const FORCED_OFF_ROUTE_FILTER_VIP = 'filter-vip';
81 -
82 - /**
83 57 * Feature key => option name for every toggle on the AI settings page.
84 58 *
85 59 * `ai_search` reuses an option owned by the Search surface; the rest are
86 60 * registered by this class. The automatic-generation option is deliberately
@@ -125,16 +99,8 @@
125 99 */
126 100 private static $initialized = false;
127 101
128 102 /**
129 - * Whether apply_master_gates() should step aside; see
130 - * {@see self::get_master_forced_off_route()}.
131 - *
132 - * @var bool
133 - */
134 - private static $probing_third_party = false;
135 -
136 - /**
137 103 * Hook everything up. Must run on every request (front-end, editor, REST):
138 104 * the filters attached here gate feature loading.
139 105 *
140 106 * @return void
@@ -235,14 +201,8 @@
235 201 * @param bool $enabled The value the call site computed so far.
236 202 * @return bool
237 203 */
238 204 public static function apply_master_gates( $enabled ) {
239 - // Stand aside while get_master_forced_off_route() asks the chain what
240 - // everyone else says; our own verdict would drown theirs out.
241 - if ( self::$probing_third_party ) {
242 - return (bool) $enabled;
243 - }
244 -
245 205 return (bool) $enabled
246 206 && self::host_allows_ai()
247 207 && ( ! self::should_enforce_ai_controls() || self::is_master_enabled() );
248 208 }
@@ -327,79 +287,8 @@
327 287 return ( new Modules() )->is_active( self::AI_MODULE );
328 288 }
329 289
330 290 /**
331 - * Whether the site's WordPress.com connection can carry AI. Offline mode
332 - * counts as disconnected even while the site holds its tokens, and Simple
333 - * sites are always connected.
334 - *
335 - * @return bool
336 - */
337 - public static function site_is_connected() {
338 - return ( new Host() )->is_wpcom_simple()
339 - || ( ( new Manager( 'jetpack' ) )->has_connected_owner()
340 - && ! ( new Status() )->is_offline_mode() );
341 - }
342 -
343 - /**
344 - * Whether the current user's own account is connected. Surfaces that proxy
345 - * as the requesting user need this on top of {@see self::site_is_connected()}.
346 - *
347 - * @return bool
348 - */
349 - public static function user_is_connected() {
350 - return ( new Host() )->is_wpcom_simple()
351 - || ( new Manager( 'jetpack' ) )->is_user_connected();
352 - }
353 -
354 - /**
355 - * Which hook custom code used to hold AI off, so the notice can link to the
356 - * matching documentation. Always empty on WordPress.com Simple, which runs
357 - * no modules.
358 - *
359 - * @return string One of the FORCED_OFF_ROUTE_* constants, or '' when nothing
360 - * holds AI off.
361 - */
362 - public static function get_master_forced_off_route() {
363 - $host = new Host();
364 -
365 - if ( $host->is_wpcom_simple() ) {
366 - return '';
367 - }
368 -
369 - // Ask the chain with our own gates stood down, so a deactivated module
370 - // cannot mask a filter that would keep AI off however the module is set.
371 - $third_party_off = false;
372 - self::$probing_third_party = true;
373 - try {
374 - $third_party_off = ! apply_filters( 'jetpack_ai_enabled', true );
375 - } finally {
376 - self::$probing_third_party = false;
377 - }
378 -
379 - if ( $third_party_off ) {
380 - return $host->is_vip_site()
381 - ? self::FORCED_OFF_ROUTE_FILTER_VIP
382 - : self::FORCED_OFF_ROUTE_FILTER;
383 - }
384 -
385 - if ( self::is_master_enabled() ) {
386 - return '';
387 - }
388 -
389 - // Removed from the available list by `jetpack_get_available_modules`.
390 - if ( ! in_array( self::AI_MODULE, ( new Modules() )->get_available(), true ) ) {
391 - return self::FORCED_OFF_ROUTE_MODULES;
392 - }
393 -
394 - // Forced off through `option_jetpack_active_modules` or `jetpack_active_modules`.
395 - $overridden = class_exists( 'Jetpack_Modules_Overrides' )
396 - && 'inactive' === Jetpack_Modules_Overrides::instance()->get_module_override( self::AI_MODULE );
397 -
398 - return $overridden ? self::FORCED_OFF_ROUTE_MODULES : '';
399 - }
400 -
401 - /**
402 291 * Set the site-wide AI master switch, writing to whichever store backs it on
403 292 * this platform (see {@see self::is_master_enabled()}).
404 293 *
405 294 * On WordPress.com Simple the `jetpack_ai_enabled` option is the master, so
@@ -458,10 +347,16 @@
458 347 return (bool) get_option( $option, self::FEATURE_DEFAULTS[ $feature ] );
459 348 }
460 349
461 350 /**
462 - * Whether AI SEO is enabled after its feature filter and the site-wide AI checks.
351 + * Whether the AI SEO feature (metadata generation, manual and automatic)
352 + * is effectively enabled: its own toggle (gate 4) through the filter, with
353 + * the host and master gates ANDed after the chain so no late-priority
354 + * callback can turn the feature back on — same finality as is_ai_enabled().
463 355 *
356 + * Not {@see self::is_feature_enabled()} with `ai_seo`, which is the stored
357 + * toggle alone. This is the one load points and payloads should read.
358 + *
464 359 * @since 16.2
465 360 *
466 361 * @return bool
467 362 */
@@ -474,9 +369,9 @@
474 369 * @param bool $enabled Whether the SEO feature toggle is on.
475 370 */
476 371 $enabled = (bool) apply_filters( 'jetpack_ai_seo_enabled', self::is_feature_enabled( 'ai_seo' ) );
477 372
478 - return $enabled && self::is_ai_enabled();
373 + return self::apply_master_gates( $enabled );
479 374 }
480 375 }
481 376
482 377 // Self-initialize on load. The consuming AI extension files require this file