← 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 |