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 | jetpack_vendor/automattic/jetpack-seo/src/class-dashboard-data.php +39 -62 16.2 → 16.3-beta View file →
@@ -171,12 +171,9 @@
171 171 return array(
172 172 'site_visibility' => array(
173 173 'search_engines_visible' => (int) get_option( 'blog_public', 1 ) === 1,
174 174 'site_is_private' => self::is_site_private(),
175 - // Read the durable SEO option (seeded/synced from the `sitemaps` module
176 - // by the Jetpack plugin) so the state survives the module's removal. The
177 - // reachable sitemap URL + "View" link live on the Settings tab.
178 - 'sitemap_active' => self::is_sitemap_enabled( $modules ),
175 + 'sitemap_active' => $modules->is_active( 'sitemaps' ),
179 176 'seo_tools_active' => $modules->is_active( 'seo-tools' ),
180 177 ),
181 178 // Per-service booleans (a code is set or not) for the Overview's
182 179 // Site verification card.
@@ -194,8 +191,43 @@
194 191 );
195 192 }
196 193
197 194 /**
195 + * Coerce the stored title formats into one `{ type, value }` token list per page type.
196 + *
197 + * The site-settings API stores a cleared page type as `''` (see JETPACK-2284), so the
198 + * option is looser than the Settings tab's type; anything not a token list becomes `array()`.
199 + *
200 + * @since 0.9.5
201 + *
202 + * @param mixed $stored Raw option value.
203 + * @return array<string, array<int, array{type: string, value: string}>>
204 + */
205 + public static function normalize_title_formats( $stored ) {
206 + if ( ! is_array( $stored ) ) {
207 + return array();
208 + }
209 +
210 + $normalized = array();
211 + foreach ( $stored as $page_type => $format ) {
212 + $tokens = array();
213 + if ( is_array( $format ) ) {
214 + foreach ( $format as $item ) {
215 + if ( is_array( $item ) && isset( $item['type'] ) && isset( $item['value'] ) && is_string( $item['type'] ) && is_string( $item['value'] ) ) {
216 + $tokens[] = array(
217 + 'type' => $item['type'],
218 + 'value' => $item['value'],
219 + );
220 + }
221 + }
222 + }
223 + $normalized[ (string) $page_type ] = $tokens;
224 + }
225 +
226 + return $normalized;
227 + }
228 +
229 + /**
198 230 * Build the editable Settings state the Settings tab hydrates from.
199 231 *
200 232 * Read-only bootstrap only. Most writes go through the existing
201 233 * `/jetpack/v4/settings` REST endpoint, which already validates and
@@ -210,12 +242,9 @@
210 242
211 243 // Read the stored values directly: Jetpack_SEO_Titles::get_custom_title_formats()
212 244 // intentionally hides them while another SEO plugin controls output, but the
213 245 // dashboard must still show the saved values without allowing edits.
214 - $title_formats = get_option( 'advanced_seo_title_formats', array() );
215 - if ( ! is_array( $title_formats ) ) {
216 - $title_formats = array();
217 - }
246 + $title_formats = self::normalize_title_formats( get_option( 'advanced_seo_title_formats', array() ) );
218 247 // @phan-suppress-next-line PhanUndeclaredClassMethod -- Jetpack_SEO_Utils lives in plugins/jetpack and is guarded by class_exists.
219 248 $title_formats_editable = class_exists( 'Jetpack_SEO_Utils' ) && Jetpack_SEO_Utils::is_enabled_jetpack_seo();
220 249 // @phan-suppress-next-line PhanUndeclaredClassMethod -- Jetpack_SEO_Utils lives in plugins/jetpack and is guarded by class_exists.
221 250 $front_page_desc = class_exists( 'Jetpack_SEO_Utils' ) ? Jetpack_SEO_Utils::get_front_page_meta_description() : '';
@@ -231,9 +260,9 @@
231 260 if ( ! is_array( $codes ) ) {
232 261 $codes = array();
233 262 }
234 263
235 - $sitemap_active = self::is_sitemap_enabled( $modules );
264 + $sitemap_active = $modules->is_active( 'sitemaps' );
236 265
237 266 return array(
238 267 'search_engines_visible' => (int) get_option( 'blog_public', 1 ) === 1,
239 268 // A private or coming-soon WordPress.com site isn't hidden from search by an
@@ -238,18 +267,14 @@
238 267 'search_engines_visible' => (int) get_option( 'blog_public', 1 ) === 1,
239 268 // A private or coming-soon WordPress.com site isn't hidden from search by an
240 269 // SEO setting and can't be unhidden by one — see {@see self::block_publishing_a_private_site()}.
241 270 'site_is_private' => self::is_site_private(),
242 - // Read the durable SEO option (seeded/synced from the `sitemaps` module
243 - // by the Jetpack plugin) so the state survives the module's removal.
244 271 'sitemap_active' => $sitemap_active,
245 272 // The reachable sitemap URL (Jetpack serves a valid sitemap here as soon as
246 273 // it's on + the site is public), or '' when sitemaps are off, so the Settings
247 274 // tab shows the "View sitemap" link exactly when there's a sitemap to view.
248 275 'sitemap_url' => self::get_reachable_sitemap_url( $sitemap_active ),
249 - // Read the durable SEO option (seeded/synced from the `canonical-urls` module
250 - // by the Jetpack plugin) so the state survives the module's removal.
251 - 'canonical_active' => self::is_canonical_enabled( $modules ),
276 + 'canonical_active' => $modules->is_active( 'canonical-urls' ),
252 277 // Cast to object so an empty format set serializes as `{}`, not `[]`.
253 278 'title_formats' => (object) $title_formats,
254 279 // Separator WordPress joins default document-title parts with. A page type
255 280 // with no stored format keeps the default title: `get_custom_title()` returns
@@ -390,56 +415,8 @@
390 415 'url' => (string) home_url(),
391 416 'icon' => $icon_url,
392 417 'image' => $image_url,
393 418 );
394 - }
395 -
396 - /**
397 - * Whether sitemap generation is enabled.
398 - *
399 - * Reads the durable {@see Initializer::SITEMAP_ENABLED_OPTION} flag. The default is only
400 - * used when the option is absent (for example before the Jetpack plugin's migration
401 - * has run on a freshly upgraded site), in which case it falls back to the live
402 - * `sitemaps` module state so behavior is unchanged in that gap.
403 - *
404 - * @param Modules $modules Modules instance to read live module state from.
405 - * @return bool
406 - */
407 - private static function is_sitemap_enabled( Modules $modules ) {
408 - $enabled = get_option( Initializer::SITEMAP_ENABLED_OPTION, null );
409 -
410 - // Only fall back to the live module state when the durable option is absent.
411 - // Passing it as get_option()'s default would evaluate it on every call, since
412 - // PHP resolves function arguments eagerly even when the option exists.
413 - if ( null === $enabled ) {
414 - $enabled = $modules->is_active( 'sitemaps' );
415 - }
416 -
417 - return (bool) $enabled;
418 - }
419 -
420 - /**
421 - * Whether canonical URLs are enabled.
422 - *
423 - * Reads the durable {@see Initializer::CANONICAL_ENABLED_OPTION} flag. The default is only
424 - * used when the option is absent (for example before the Jetpack plugin's migration
425 - * has run on a freshly upgraded site), in which case it falls back to the live
426 - * `canonical-urls` module state so behavior is unchanged in that gap.
427 - *
428 - * @param Modules $modules Modules instance to read live module state from.
429 - * @return bool
430 - */
431 - private static function is_canonical_enabled( Modules $modules ) {
432 - $enabled = get_option( Initializer::CANONICAL_ENABLED_OPTION, null );
433 -
434 - // Only fall back to the live module state when the durable option is absent.
435 - // Passing it as get_option()'s default would evaluate it on every call, since
436 - // PHP resolves function arguments eagerly even when the option exists.
437 - if ( null === $enabled ) {
438 - $enabled = $modules->is_active( 'canonical-urls' );
439 - }
440 -
441 - return (bool) $enabled;
442 419 }
443 420
444 421 /**
445 422 * The separator, as rendered, that WordPress joins default document-title parts