| @@ -61,8 +61,9 @@ | ||
| 61 | 61 | '_metasync_seo_title', |
| 62 | 62 | '_metasync_seo_desc', |
| 63 | 63 | '_metasync_metatitle', |
| 64 | 64 | '_metasync_metadesc', |
| 65 | + '_metasync_metakeywords', | |
| 65 | 66 | '_metasync_robots_index', |
| 66 | 67 | '_metasync_robots_advanced', |
| 67 | 68 | '_metasync_og_title', |
| 68 | 69 | '_metasync_og_description', |
| @@ -80,8 +81,9 @@ | ||
| 80 | 81 | '_metasync_otto_og_description', |
| 81 | 82 | '_metasync_otto_twitter_title', |
| 82 | 83 | '_metasync_otto_twitter_description', |
| 83 | 84 | '_metasync_otto_keywords', |
| 85 | + '_metasync_otto_canonical', | |
| 84 | 86 | ]; |
| 85 | 87 | |
| 86 | 88 | /** |
| 87 | 89 | * Internal OTTO meta keys mapped to the OTTO Persistence setting that |
| @@ -102,8 +104,9 @@ | ||
| 102 | 104 | const OTTO_PERSISTENCE_KEYS = [ |
| 103 | 105 | '_metasync_otto_title' => 'meta_title', |
| 104 | 106 | '_metasync_otto_description' => 'meta_description', |
| 105 | 107 | '_metasync_otto_keywords' => 'meta_keywords', |
| 108 | + '_metasync_metakeywords' => 'meta_keywords', | |
| 106 | 109 | '_metasync_otto_og_title' => 'og_title', |
| 107 | 110 | '_metasync_otto_og_description' => 'og_description', |
| 108 | 111 | '_metasync_otto_twitter_title' => 'twitter_title', |
| 109 | 112 | '_metasync_otto_twitter_description' => 'twitter_description', |
| @@ -253,8 +256,9 @@ | ||
| 253 | 256 | '_metasync_otto_og_description' => 'og_desc', |
| 254 | 257 | '_metasync_otto_twitter_title' => 'twitter_title', |
| 255 | 258 | '_metasync_otto_twitter_description' => 'twitter_desc', |
| 256 | 259 | '_metasync_otto_keywords' => 'focus_keyword', |
| 260 | + '_metasync_metakeywords' => 'focus_keyword', | |
| 257 | 261 | // Legacy meta box keys → rebuild JSON |
| 258 | 262 | 'metasync_common_robots' => '_legacy_robots_to_json', |
| 259 | 263 | 'metasync_advance_robots' => '_legacy_robots_to_json', |
| 260 | 264 | ]; |
| @@ -559,9 +563,13 @@ | ||
| 559 | 563 | // Canonical, focus keyword, breadcrumb |
| 560 | 564 | // Canonical is validated at the source so a corrupted value ("Array") |
| 561 | 565 | // never propagates into Yoast/RankMath/AIOSEO storage. |
| 562 | 566 | $data['canonical'] = Metasync_Canonical_Sanitizer::sanitize($get('_metasync_canonical_url')); |
| 563 | - $data['focus_keyword'] = $first('_metasync_focus_keyword', '_metasync_otto_keywords'); | |
| 567 | + // The keyword takes its order from the resolver — customer value, then | |
| 568 | + // OTTO's volatile tier, then OTTO's persisted tier — so the persistence | |
| 569 | + // gating in $first() reaches the persisted copy too. Previously the | |
| 570 | + // persisted copy sat on the customer key, outranking the live one. | |
| 571 | + $data['focus_keyword'] = $first(...Metasync_Seo_Precedence::keys(Metasync_Seo_Precedence::FIELD_FOCUS_KEYWORD)); | |
| 564 | 572 | $data['breadcrumb_title'] = $get('_metasync_breadcrumb_title'); |
| 565 | 573 | |
| 566 | 574 | return $this->apply_feature_flags_to_payload($data); |
| 567 | 575 | } |