PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 19.0
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v19.0
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / inc / class-upgrade.php

class-upgrade.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 19.0, at inc/class-upgrade.php

1,314 lines 39.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WPSEO plugin file.
4 *
5 * @package WPSEO\Internal
6 */
7
8 use Yoast\WP\Lib\Model;
9
10 /**
11 * This code handles the option upgrades.
12 */
13 class WPSEO_Upgrade {
14
15 /**
16 * The taxonomy helper.
17 *
18 * @var \Yoast\WP\SEO\Helpers\Taxonomy_Helper
19 */
20 private $taxonomy_helper;
21
22 /**
23 * Class constructor.
24 */
25 public function __construct() {
26 $this->taxonomy_helper = YoastSEO()->helpers->taxonomy;
27
28 $version = WPSEO_Options::get( 'version' );
29
30 WPSEO_Options::maybe_set_multisite_defaults( false );
31
32 $routines = [
33 '1.5.0' => 'upgrade_15',
34 '2.0' => 'upgrade_20',
35 '2.1' => 'upgrade_21',
36 '2.2' => 'upgrade_22',
37 '2.3' => 'upgrade_23',
38 '3.0' => 'upgrade_30',
39 '3.3' => 'upgrade_33',
40 '3.6' => 'upgrade_36',
41 '4.0' => 'upgrade_40',
42 '4.4' => 'upgrade_44',
43 '4.7' => 'upgrade_47',
44 '4.9' => 'upgrade_49',
45 '5.0' => 'upgrade_50',
46 '5.5' => 'upgrade_55',
47 '6.3' => 'upgrade_63',
48 '7.0-RC0' => 'upgrade_70',
49 '7.1-RC0' => 'upgrade_71',
50 '7.3-RC0' => 'upgrade_73',
51 '7.4-RC0' => 'upgrade_74',
52 '7.5.3' => 'upgrade_753',
53 '7.7-RC0' => 'upgrade_77',
54 '7.7.2-RC0' => 'upgrade_772',
55 '9.0-RC0' => 'upgrade_90',
56 '10.0-RC0' => 'upgrade_100',
57 '11.1-RC0' => 'upgrade_111',
58 // Reset notifications because we removed the AMP Glue plugin notification.
59 '12.1-RC0' => 'clean_all_notifications',
60 '12.3-RC0' => 'upgrade_123',
61 '12.4-RC0' => 'upgrade_124',
62 '12.8-RC0' => 'upgrade_128',
63 '13.2-RC0' => 'upgrade_132',
64 '14.0.3-RC0' => 'upgrade_1403',
65 '14.1-RC0' => 'upgrade_141',
66 '14.2-RC0' => 'upgrade_142',
67 '14.5-RC0' => 'upgrade_145',
68 '14.9-RC0' => 'upgrade_149',
69 '15.1-RC0' => 'upgrade_151',
70 '15.3-RC0' => 'upgrade_153',
71 '15.5-RC0' => 'upgrade_155',
72 '15.7-RC0' => 'upgrade_157',
73 '15.9.1-RC0' => 'upgrade_1591',
74 '16.2-RC0' => 'upgrade_162',
75 '16.5-RC0' => 'upgrade_165',
76 '17.2-RC0' => 'upgrade_172',
77 '17.7.1-RC0' => 'upgrade_1771',
78 '17.9-RC0' => 'upgrade_179',
79 '18.3-RC3' => 'upgrade_183',
80 '18.6-RC0' => 'upgrade_186',
81 '18.9-RC0' => 'upgrade_189',
82 ];
83
84 array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version );
85
86 if ( version_compare( $version, '12.5-RC0', '<' ) ) {
87 /*
88 * We have to run this by hook, because otherwise:
89 * - the theme support check isn't available.
90 * - the notification center notifications are not filled yet.
91 */
92 add_action( 'init', [ $this, 'upgrade_125' ] );
93 }
94
95 // Since 3.7.
96 $upsell_notice = new WPSEO_Product_Upsell_Notice();
97 $upsell_notice->set_upgrade_notice();
98
99 /**
100 * Filter: 'wpseo_run_upgrade' - Runs the upgrade hook which are dependent on Yoast SEO.
101 *
102 * @api string - The current version of Yoast SEO
103 */
104 do_action( 'wpseo_run_upgrade', $version );
105
106 $this->finish_up( $version );
107 }
108
109 /**
110 * Runs the upgrade routine.
111 *
112 * @param string $routine The method to call.
113 * @param string $version The new version.
114 * @param string $current_version The current set version.
115 *
116 * @return void
117 */
118 protected function run_upgrade_routine( $routine, $version, $current_version ) {
119 if ( version_compare( $current_version, $version, '<' ) ) {
120 $this->$routine( $current_version );
121 }
122 }
123
124 /**
125 * Adds a new upgrade history entry.
126 *
127 * @param string $current_version The old version from which we are upgrading.
128 * @param string $new_version The version we are upgrading to.
129 */
130 protected function add_upgrade_history( $current_version, $new_version ) {
131 $upgrade_history = new WPSEO_Upgrade_History();
132 $upgrade_history->add( $current_version, $new_version, array_keys( WPSEO_Options::$options ) );
133 }
134
135 /**
136 * Runs the needed cleanup after an update, setting the DB version to latest version, flushing caches etc.
137 *
138 * @param string|null $previous_version The previous version.
139 *
140 * @return void
141 */
142 protected function finish_up( $previous_version = null ) {
143 if ( $previous_version ) {
144 WPSEO_Options::set( 'previous_version', $previous_version );
145 }
146 WPSEO_Options::set( 'version', WPSEO_VERSION );
147
148 // Just flush rewrites, always, to at least make them work after an upgrade.
149 add_action( 'shutdown', 'flush_rewrite_rules' );
150
151 // Flush the sitemap cache.
152 WPSEO_Sitemaps_Cache::clear();
153
154 // Make sure all our options always exist - issue #1245.
155 WPSEO_Options::ensure_options_exist();
156 }
157
158 /**
159 * Run the Yoast SEO 1.5 upgrade routine.
160 *
161 * @param string $version Current plugin version.
162 */
163 private function upgrade_15( $version ) {
164 // Clean up options and meta.
165 WPSEO_Options::clean_up( null, $version );
166 WPSEO_Meta::clean_up();
167 }
168
169 /**
170 * Moves options that moved position in WPSEO 2.0.
171 */
172 private function upgrade_20() {
173 /**
174 * Clean up stray wpseo_ms options from the options table, option should only exist in the sitemeta table.
175 * This could have been caused in many version of Yoast SEO, so deleting it for everything below 2.0.
176 */
177 delete_option( 'wpseo_ms' );
178
179 $wpseo = $this->get_option_from_database( 'wpseo' );
180 $this->save_option_setting( $wpseo, 'pinterestverify' );
181
182 // Re-save option to trigger sanitization.
183 $this->cleanup_option_data( 'wpseo' );
184 }
185
186 /**
187 * Detects if taxonomy terms were split and updates the corresponding taxonomy meta's accordingly.
188 */
189 private function upgrade_21() {
190 $taxonomies = get_option( 'wpseo_taxonomy_meta', [] );
191
192 if ( ! empty( $taxonomies ) ) {
193 foreach ( $taxonomies as $taxonomy => $tax_metas ) {
194 foreach ( $tax_metas as $term_id => $tax_meta ) {
195 if ( function_exists( 'wp_get_split_term' ) ) {
196 $new_term_id = wp_get_split_term( $term_id, $taxonomy );
197 if ( $new_term_id !== false ) {
198 $taxonomies[ $taxonomy ][ $new_term_id ] = $taxonomies[ $taxonomy ][ $term_id ];
199 unset( $taxonomies[ $taxonomy ][ $term_id ] );
200 }
201 }
202 }
203 }
204
205 update_option( 'wpseo_taxonomy_meta', $taxonomies );
206 }
207 }
208
209 /**
210 * Performs upgrade functions to Yoast SEO 2.2.
211 */
212 private function upgrade_22() {
213 // Unschedule our tracking.
214 wp_clear_scheduled_hook( 'yoast_tracking' );
215
216 $this->cleanup_option_data( 'wpseo' );
217 }
218
219 /**
220 * Schedules upgrade function to Yoast SEO 2.3.
221 */
222 private function upgrade_23() {
223 add_action( 'wp', [ $this, 'upgrade_23_query' ], 90 );
224 add_action( 'admin_head', [ $this, 'upgrade_23_query' ], 90 );
225 }
226
227 /**
228 * Performs upgrade query to Yoast SEO 2.3.
229 */
230 public function upgrade_23_query() {
231 $wp_query = new WP_Query( 'post_type=any&meta_key=_yoast_wpseo_sitemap-include&meta_value=never&order=ASC' );
232
233 if ( ! empty( $wp_query->posts ) ) {
234 $options = get_option( 'wpseo_xml' );
235
236 $excluded_posts = [];
237 if ( $options['excluded-posts'] !== '' ) {
238 $excluded_posts = explode( ',', $options['excluded-posts'] );
239 }
240
241 foreach ( $wp_query->posts as $post ) {
242 if ( ! in_array( (string) $post->ID, $excluded_posts, true ) ) {
243 $excluded_posts[] = $post->ID;
244 }
245 }
246
247 // Updates the meta value.
248 $options['excluded-posts'] = implode( ',', $excluded_posts );
249
250 // Update the option.
251 update_option( 'wpseo_xml', $options );
252 }
253
254 // Remove the meta fields.
255 delete_post_meta_by_key( '_yoast_wpseo_sitemap-include' );
256 }
257
258 /**
259 * Performs upgrade functions to Yoast SEO 3.0.
260 */
261 private function upgrade_30() {
262 // Remove the meta fields for sitemap prio.
263 delete_post_meta_by_key( '_yoast_wpseo_sitemap-prio' );
264 }
265
266 /**
267 * Performs upgrade functions to Yoast SEO 3.3.
268 */
269 private function upgrade_33() {
270 // Notification dismissals have been moved to User Meta instead of global option.
271 delete_option( Yoast_Notification_Center::STORAGE_KEY );
272 }
273
274 /**
275 * Performs upgrade functions to Yoast SEO 3.6.
276 */
277 private function upgrade_36() {
278 global $wpdb;
279
280 // Between 3.2 and 3.4 the sitemap options were saved with autoloading enabled.
281 $wpdb->query( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE "wpseo_sitemap_%" AND autoload = "yes"' );
282 }
283
284 /**
285 * Removes the about notice when its still in the database.
286 */
287 private function upgrade_40() {
288 $center = Yoast_Notification_Center::get();
289 $center->remove_notification_by_id( 'wpseo-dismiss-about' );
290 }
291
292 /**
293 * Moves the content-analysis-active and keyword-analysis-acive options from wpseo-titles to wpseo.
294 */
295 private function upgrade_44() {
296 $wpseo_titles = $this->get_option_from_database( 'wpseo_titles' );
297
298 $this->save_option_setting( $wpseo_titles, 'content-analysis-active', 'content_analysis_active' );
299 $this->save_option_setting( $wpseo_titles, 'keyword-analysis-active', 'keyword_analysis_active' );
300
301 // Remove irrelevant content from the option.
302 $this->cleanup_option_data( 'wpseo_titles' );
303 }
304
305 /**
306 * Renames the meta name for the cornerstone content. It was a public meta field and it has to be private.
307 */
308 private function upgrade_47() {
309 global $wpdb;
310
311 // The meta key has to be private, so prefix it.
312 $wpdb->query(
313 $wpdb->prepare(
314 'UPDATE ' . $wpdb->postmeta . ' SET meta_key = %s WHERE meta_key = "yst_is_cornerstone"',
315 WPSEO_Cornerstone_Filter::META_NAME
316 )
317 );
318 }
319
320 /**
321 * Removes the 'wpseo-dismiss-about' notice for every user that still has it.
322 */
323 private function upgrade_49() {
324 global $wpdb;
325
326 /*
327 * Using a filter to remove the notification for the current logged in user. The notification center is
328 * initializing the notifications before the upgrade routine has been executedd and is saving the stored
329 * notifications on shutdown. This causes the returning notification. By adding this filter the shutdown
330 * routine on the notification center will remove the notification.
331 */
332 add_filter( 'yoast_notifications_before_storage', [ $this, 'remove_about_notice' ] );
333
334 $meta_key = $wpdb->get_blog_prefix() . Yoast_Notification_Center::STORAGE_KEY;
335
336 $usermetas = $wpdb->get_results(
337 $wpdb->prepare(
338 '
339 SELECT user_id, meta_value
340 FROM ' . $wpdb->usermeta . '
341 WHERE meta_key = %s AND meta_value LIKE %s
342 ',
343 $meta_key,
344 '%wpseo-dismiss-about%'
345 ),
346 ARRAY_A
347 );
348
349 if ( empty( $usermetas ) ) {
350 return;
351 }
352
353 foreach ( $usermetas as $usermeta ) {
354 $notifications = maybe_unserialize( $usermeta['meta_value'] );
355
356 foreach ( $notifications as $notification_key => $notification ) {
357 if ( ! empty( $notification['options']['id'] ) && $notification['options']['id'] === 'wpseo-dismiss-about' ) {
358 unset( $notifications[ $notification_key ] );
359 }
360 }
361
362 update_user_option( $usermeta['user_id'], Yoast_Notification_Center::STORAGE_KEY, array_values( $notifications ) );
363 }
364 }
365
366 /**
367 * Removes the wpseo-dismiss-about notice from a list of notifications.
368 *
369 * @param Yoast_Notification[] $notifications The notifications to filter.
370 *
371 * @return Yoast_Notification[] The filtered list of notifications. Excluding the wpseo-dismiss-about notification.
372 */
373 public function remove_about_notice( $notifications ) {
374 foreach ( $notifications as $notification_key => $notification ) {
375 if ( $notification->get_id() === 'wpseo-dismiss-about' ) {
376 unset( $notifications[ $notification_key ] );
377 }
378 }
379
380 return $notifications;
381 }
382
383 /**
384 * Adds the yoast_seo_links table to the database.
385 */
386 private function upgrade_50() {
387 global $wpdb;
388
389 // Deletes the post meta value, which might created in the RC.
390 $wpdb->query( 'DELETE FROM ' . $wpdb->postmeta . ' WHERE meta_key = "_yst_content_links_processed"' );
391 }
392
393 /**
394 * Register new capabilities and roles.
395 */
396 private function upgrade_55() {
397 // Register roles.
398 do_action( 'wpseo_register_roles' );
399 WPSEO_Role_Manager_Factory::get()->add();
400
401 // Register capabilities.
402 do_action( 'wpseo_register_capabilities' );
403 WPSEO_Capability_Manager_Factory::get()->add();
404 }
405
406 /**
407 * Removes some no longer used options for noindexing subpages and for meta keywords and its associated templates.
408 *
409 * @return void
410 */
411 private function upgrade_63() {
412 $this->cleanup_option_data( 'wpseo_titles' );
413 }
414
415 /**
416 * Perform the 7.0 upgrade, moves settings around, deletes several options.
417 *
418 * @return void
419 */
420 private function upgrade_70() {
421
422 $wpseo_permalinks = $this->get_option_from_database( 'wpseo_permalinks' );
423 $wpseo_xml = $this->get_option_from_database( 'wpseo_xml' );
424 $wpseo_rss = $this->get_option_from_database( 'wpseo_rss' );
425 $wpseo = $this->get_option_from_database( 'wpseo' );
426 $wpseo_internallinks = $this->get_option_from_database( 'wpseo_internallinks' );
427
428 // Move some permalink settings, then delete the option.
429 $this->save_option_setting( $wpseo_permalinks, 'redirectattachment', 'disable-attachment' );
430 $this->save_option_setting( $wpseo_permalinks, 'stripcategorybase' );
431
432 // Move one XML sitemap setting, then delete the option.
433 $this->save_option_setting( $wpseo_xml, 'enablexmlsitemap', 'enable_xml_sitemap' );
434
435
436 // Move the RSS settings to the search appearance settings, then delete the RSS option.
437 $this->save_option_setting( $wpseo_rss, 'rssbefore' );
438 $this->save_option_setting( $wpseo_rss, 'rssafter' );
439
440 $this->save_option_setting( $wpseo, 'company_logo' );
441 $this->save_option_setting( $wpseo, 'company_name' );
442 $this->save_option_setting( $wpseo, 'company_or_person' );
443 $this->save_option_setting( $wpseo, 'person_name' );
444
445 // Remove the website name and altername name as we no longer need them.
446 $this->cleanup_option_data( 'wpseo' );
447
448 // All the breadcrumbs settings have moved to the search appearance settings.
449 foreach ( array_keys( $wpseo_internallinks ) as $key ) {
450 $this->save_option_setting( $wpseo_internallinks, $key );
451 }
452
453 // Convert hidden metabox options to display metabox options.
454 $title_options = get_option( 'wpseo_titles' );
455
456 foreach ( $title_options as $key => $value ) {
457 if ( strpos( $key, 'hideeditbox-tax-' ) === 0 ) {
458 $taxonomy = substr( $key, strlen( 'hideeditbox-tax-' ) );
459 WPSEO_Options::set( 'display-metabox-tax-' . $taxonomy, ! $value );
460 continue;
461 }
462
463 if ( strpos( $key, 'hideeditbox-' ) === 0 ) {
464 $post_type = substr( $key, strlen( 'hideeditbox-' ) );
465 WPSEO_Options::set( 'display-metabox-pt-' . $post_type, ! $value );
466 continue;
467 }
468 }
469
470 // Cleanup removed options.
471 delete_option( 'wpseo_xml' );
472 delete_option( 'wpseo_permalinks' );
473 delete_option( 'wpseo_rss' );
474 delete_option( 'wpseo_internallinks' );
475
476 // Remove possibly present plugin conflict notice for plugin that was removed from the list of conflicting plugins.
477 $yoast_plugin_conflict = WPSEO_Plugin_Conflict::get_instance();
478 $yoast_plugin_conflict->clear_error( 'header-footer/plugin.php' );
479
480 // Moves the user meta for excluding from the XML sitemap to a noindex.
481 global $wpdb;
482 $wpdb->query( "UPDATE $wpdb->usermeta SET meta_key = 'wpseo_noindex_author' WHERE meta_key = 'wpseo_excludeauthorsitemap'" );
483 }
484
485 /**
486 * Perform the 7.1 upgrade.
487 *
488 * @return void
489 */
490 private function upgrade_71() {
491 $this->cleanup_option_data( 'wpseo_social' );
492
493 // Move the breadcrumbs setting and invert it.
494 $title_options = $this->get_option_from_database( 'wpseo_titles' );
495
496 if ( array_key_exists( 'breadcrumbs-blog-remove', $title_options ) ) {
497 WPSEO_Options::set( 'breadcrumbs-display-blog-page', ! $title_options['breadcrumbs-blog-remove'] );
498
499 $this->cleanup_option_data( 'wpseo_titles' );
500 }
501 }
502
503 /**
504 * Perform the 7.3 upgrade.
505 *
506 * @return void
507 */
508 private function upgrade_73() {
509 global $wpdb;
510 // We've moved the cornerstone checkbox to our proper namespace.
511 $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_yoast_wpseo_is_cornerstone' WHERE meta_key = '_yst_is_cornerstone'" );
512
513 // Remove the previous Whip dismissed message, as this is a new one regarding PHP 5.2.
514 delete_option( 'whip_dismiss_timestamp' );
515 }
516
517 /**
518 * Performs the 7.4 upgrade.
519 *
520 * @return void
521 */
522 private function upgrade_74() {
523 $this->remove_sitemap_validators();
524 }
525
526 /**
527 * Performs the 7.5.3 upgrade.
528 *
529 * When upgrading purging media is potentially relevant.
530 *
531 * @return void
532 */
533 private function upgrade_753() {
534 // Only when attachments are not disabled.
535 if ( WPSEO_Options::get( 'disable-attachment' ) === true ) {
536 return;
537 }
538
539 // Only when attachments are not no-indexed.
540 if ( WPSEO_Options::get( 'noindex-attachment' ) === true ) {
541 return;
542 }
543
544 // Set purging relevancy.
545 WPSEO_Options::set( 'is-media-purge-relevant', true );
546 }
547
548 /**
549 * Performs the 7.7 upgrade.
550 *
551 * @return void
552 */
553 private function upgrade_77() {
554 // Remove all OpenGraph content image cache.
555 $this->delete_post_meta( '_yoast_wpseo_post_image_cache' );
556 }
557
558 /**
559 * Performs the 7.7.2 upgrade.
560 *
561 * @return void
562 */
563 private function upgrade_772() {
564 if ( YoastSEO()->helpers->woocommerce->is_active() ) {
565 $this->migrate_woocommerce_archive_setting_to_shop_page();
566 }
567 }
568
569 /**
570 * Performs the 9.0 upgrade.
571 *
572 * @return void
573 */
574 private function upgrade_90() {
575 global $wpdb;
576
577 // Invalidate all sitemap cache transients.
578 WPSEO_Sitemaps_Cache_Validator::cleanup_database();
579
580 // Removes all scheduled tasks for hitting the sitemap index.
581 wp_clear_scheduled_hook( 'wpseo_hit_sitemap_index' );
582
583 $wpdb->query( 'DELETE FROM ' . $wpdb->options . ' WHERE option_name LIKE "wpseo_sitemap_%"' );
584 }
585
586 /**
587 * Performs the 10.0 upgrade.
588 *
589 * @return void
590 */
591 private function upgrade_100() {
592 // Removes recalibration notifications.
593 $this->clean_all_notifications();
594
595 // Removes recalibration options.
596 WPSEO_Options::clean_up( 'wpseo' );
597 delete_option( 'wpseo_recalibration_beta_mailinglist_subscription' );
598 }
599
600 /**
601 * Performs the 11.1 upgrade.
602 *
603 * @return void
604 */
605 private function upgrade_111() {
606 // Set company_or_person to company when it's an invalid value.
607 $company_or_person = WPSEO_Options::get( 'company_or_person', '' );
608
609 if ( ! in_array( $company_or_person, [ 'company', 'person' ], true ) ) {
610 WPSEO_Options::set( 'company_or_person', 'company' );
611 }
612 }
613
614 /**
615 * Performs the 12.3 upgrade.
616 *
617 * Removes the about notice when its still in the database.
618 */
619 private function upgrade_123() {
620 $plugins = [
621 'yoast-seo-premium',
622 'video-seo-for-wordpress-seo-by-yoast',
623 'yoast-news-seo',
624 'local-seo-for-yoast-seo',
625 'yoast-woocommerce-seo',
626 'yoast-acf-analysis',
627 ];
628
629 $center = Yoast_Notification_Center::get();
630 foreach ( $plugins as $plugin ) {
631 $center->remove_notification_by_id( 'wpseo-outdated-yoast-seo-plugin-' . $plugin );
632 }
633 }
634
635 /**
636 * Performs the 12.4 upgrade.
637 *
638 * Removes the Google plus defaults from the database.
639 */
640 private function upgrade_124() {
641 $this->cleanup_option_data( 'wpseo_social' );
642 }
643
644 /**
645 * Performs the 12.5 upgrade.
646 */
647 public function upgrade_125() {
648 // Disables the force rewrite title when the theme supports it through WordPress.
649 if ( WPSEO_Options::get( 'forcerewritetitle', false ) && current_theme_supports( 'title-tag' ) ) {
650 WPSEO_Options::set( 'forcerewritetitle', false );
651 }
652
653 global $wpdb;
654 $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key = 'wp_yoast_promo_hide_premium_upsell_admin_block'" );
655
656 // Removes the WordPress update notification, because it is no longer necessary when WordPress 5.3 is released.
657 $center = Yoast_Notification_Center::get();
658 $center->remove_notification_by_id( 'wpseo-dismiss-wordpress-upgrade' );
659 }
660
661 /**
662 * Performs the 12.8 upgrade.
663 */
664 private function upgrade_128() {
665 // Re-save wpseo to make sure bf_banner_2019_dismissed key is gone.
666 $this->cleanup_option_data( 'wpseo' );
667
668 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-page_comments-notice' );
669 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-wordpress-upgrade' );
670 }
671
672 /**
673 * Performs the 13.2 upgrade.
674 */
675 private function upgrade_132() {
676 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-tagline-notice' );
677 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-permalink-notice' );
678 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-onpageorg' );
679
680 // Transfers the onpage option value to the ryte option.
681 $ryte_option = get_option( 'wpseo_ryte' );
682 $onpage_option = get_option( 'wpseo_onpage' );
683 if ( ! $ryte_option && $onpage_option ) {
684 update_option( 'wpseo_ryte', $onpage_option );
685 delete_option( 'wpseo_onpage' );
686 }
687
688 // Changes onpage_indexability to ryte_indexability.
689 $wpseo_option = get_option( 'wpseo' );
690 if ( isset( $wpseo_option['onpage_indexability'] ) && ! isset( $wpseo_option['ryte_indexability'] ) ) {
691 $wpseo_option['ryte_indexability'] = $wpseo_option['onpage_indexability'];
692 unset( $wpseo_option['onpage_indexability'] );
693 update_option( 'wpseo', $wpseo_option );
694 }
695
696 if ( wp_next_scheduled( 'wpseo_ryte_fetch' ) ) {
697 wp_clear_scheduled_hook( 'wpseo_ryte_fetch' );
698 }
699
700 /*
701 * Re-register capabilities to add the new `view_site_health_checks`
702 * capability to the SEO Manager role.
703 */
704 do_action( 'wpseo_register_capabilities' );
705 WPSEO_Capability_Manager_Factory::get()->add();
706 }
707
708 /**
709 * Perform the 14.0.3 upgrade.
710 */
711 private function upgrade_1403() {
712 WPSEO_Options::set( 'ignore_indexation_warning', false );
713 }
714
715 /**
716 * Performs the 14.1 upgrade.
717 */
718 private function upgrade_141() {
719 /*
720 * These notifications are retrieved from storage on the `init` hook with
721 * priority 1. We need to remove them after they're retrieved.
722 */
723 add_action( 'init', [ $this, 'remove_notifications_for_141' ] );
724 add_action( 'init', [ $this, 'clean_up_private_taxonomies_for_141' ] );
725
726 $this->reset_permalinks_of_attachments_for_141();
727 }
728
729 /**
730 * Performs the 14.2 upgrade.
731 *
732 * Removes the yoast-acf-analysis notice when it's still in the database.
733 */
734 private function upgrade_142() {
735 add_action( 'init', [ $this, 'remove_acf_notification_for_142' ] );
736 }
737
738 /**
739 * Performs the 14.5 upgrade.
740 */
741 private function upgrade_145() {
742 add_action( 'init', [ $this, 'set_indexation_completed_option_for_145' ] );
743 }
744
745 /**
746 * Performs the 14.9 upgrade.
747 */
748 private function upgrade_149() {
749 $version = get_option( 'wpseo_license_server_version', 2 );
750 WPSEO_Options::set( 'license_server_version', $version );
751 delete_option( 'wpseo_license_server_version' );
752 }
753
754 /**
755 * Performs the 15.1 upgrade.
756 *
757 * @return void
758 */
759 private function upgrade_151() {
760 $this->set_home_url_for_151();
761 $this->move_indexables_indexation_reason_for_151();
762
763 add_action( 'init', [ $this, 'set_permalink_structure_option_for_151' ] );
764 add_action( 'init', [ $this, 'store_custom_taxonomy_slugs_for_151' ] );
765 }
766
767 /**
768 * Performs the 15.3 upgrade.
769 *
770 * @return void
771 */
772 private function upgrade_153() {
773 WPSEO_Options::set( 'category_base_url', get_option( 'category_base' ) );
774 WPSEO_Options::set( 'tag_base_url', get_option( 'tag_base' ) );
775
776 // Rename a couple of options.
777 $indexation_started_value = WPSEO_Options::get( 'indexation_started' );
778 WPSEO_Options::set( 'indexing_started', $indexation_started_value );
779
780 $indexables_indexing_completed_value = WPSEO_Options::get( 'indexables_indexation_completed' );
781 WPSEO_Options::set( 'indexables_indexing_completed', $indexables_indexing_completed_value );
782 }
783
784 /**
785 * Performs the 15.5 upgrade.
786 *
787 * @return void
788 */
789 private function upgrade_155() {
790 // Unset the fbadminapp value in the wpseo_social option.
791 $wpseo_social_option = get_option( 'wpseo_social' );
792
793 if ( isset( $wpseo_social_option['fbadminapp'] ) ) {
794 unset( $wpseo_social_option['fbadminapp'] );
795 update_option( 'wpseo_social', $wpseo_social_option );
796 }
797 }
798
799 /**
800 * Performs the 15.7 upgrade.
801 *
802 * @return void
803 */
804 private function upgrade_157() {
805 add_action( 'init', [ $this, 'remove_plugin_updated_notification_for_157' ] );
806 }
807
808 /**
809 * Performs the 15.9.1 upgrade routine.
810 */
811 private function upgrade_1591() {
812 $enabled_auto_updates = \get_option( 'auto_update_plugins' );
813 $addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
814 $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', [], $enabled_auto_updates );
815 }
816
817 /**
818 * Performs the 16.2 upgrade routine.
819 */
820 private function upgrade_162() {
821 $enabled_auto_updates = \get_site_option( 'auto_update_plugins' );
822 $addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
823 $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] );
824 }
825
826 /**
827 * Performs the 16.5 upgrade.
828 *
829 * @return void
830 */
831 private function upgrade_165() {
832 add_action( 'init', [ $this, 'copy_og_settings_from_social_to_titles' ], 99 );
833
834 // Run after the WPSEO_Options::enrich_defaults method which has priority 99.
835 add_action( 'init', [ $this, 'reset_og_settings_to_default_values' ], 100 );
836 }
837
838 /**
839 * Performs the 17.2 upgrade. Cleans out any unnecessary indexables. See $cleanup_integration->get_cleanup_tasks() to see what will be cleaned out.
840 *
841 * @return void
842 */
843 private function upgrade_172() {
844 \wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' );
845 \wp_unschedule_hook( 'wpseo_cleanup_indexables' );
846
847 if ( ! \wp_next_scheduled( \Yoast\WP\SEO\Integrations\Cleanup_Integration::START_HOOK ) ) {
848 \wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), \Yoast\WP\SEO\Integrations\Cleanup_Integration::START_HOOK );
849 }
850 }
851
852 /**
853 * Performs the 17.7.1 upgrade routine.
854 */
855 private function upgrade_1771() {
856 $enabled_auto_updates = \get_site_option( 'auto_update_plugins' );
857 $addon_update_watcher = YoastSEO()->classes->get( \Yoast\WP\SEO\Integrations\Watchers\Addon_Update_Watcher::class );
858 $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] );
859 }
860
861 /**
862 * Performs the 17.9 upgrade routine.
863 */
864 private function upgrade_179() {
865 WPSEO_Options::set( 'wincher_integration_active', true );
866 }
867
868 /**
869 * Performs the 18.3 upgrade routine.
870 */
871 private function upgrade_183() {
872 $this->delete_post_meta( 'yoast-structured-data-blocks-images-cache' );
873 }
874
875 /**
876 * Performs the 18.6 upgrade routine.
877 */
878 private function upgrade_186() {
879 if ( is_multisite() ) {
880 WPSEO_Options::set( 'allow_wincher_integration_active', false );
881 }
882 }
883
884 /**
885 * Performs the 18.9 upgrade routine.
886 */
887 private function upgrade_189() {
888 // Make old users not get the Installation Success page after upgrading.
889 WPSEO_Options::set( 'should_redirect_after_install_free', false );
890 // We're adding a hardcoded time here, so that in the future we can be able to identify whether the user did see the Installation Success page or not.
891 // If they did, they wouldn't have this hardcoded value in that option, but rather (roughly) the timestamp of the moment they saw it.
892 WPSEO_Options::set( 'activation_redirect_timestamp_free', 1652258756 );
893
894 // Transfer the Social URLs.
895 $other = [];
896 $other[] = WPSEO_Options::get( 'instagram_url' );
897 $other[] = WPSEO_Options::get( 'linkedin_url' );
898 $other[] = WPSEO_Options::get( 'myspace_url' );
899 $other[] = WPSEO_Options::get( 'pinterest_url' );
900 $other[] = WPSEO_Options::get( 'youtube_url' );
901 $other[] = WPSEO_Options::get( 'wikipedia_url' );
902
903 WPSEO_Options::set( 'other_social_urls', array_values( array_unique( array_filter( $other ) ) ) );
904
905 // Transfer the progress of the old Configuration Workout.
906 $workout_data = WPSEO_Options::get( 'workouts_data' );
907 $old_conf_progress = isset( $workout_data['configuration']['finishedSteps'] ) ? $workout_data['configuration']['finishedSteps'] : [];
908
909 if ( in_array( 'optimizeSeoData', $old_conf_progress, true ) && in_array( 'siteRepresentation', $old_conf_progress, true ) ) {
910 // If completed ‘SEO optimization’ and ‘Site representation’ step, we assume the workout was completed.
911 $configuration_finished_steps = [
912 'siteRepresentation',
913 'socialProfiles',
914 'personalPreferences',
915 ];
916 WPSEO_Options::set( 'configuration_finished_steps', $configuration_finished_steps );
917 }
918 }
919
920 /**
921 * Sets the home_url option for the 15.1 upgrade routine.
922 *
923 * @return void
924 */
925 protected function set_home_url_for_151() {
926 $home_url = WPSEO_Options::get( 'home_url' );
927
928 if ( empty( $home_url ) ) {
929 WPSEO_Options::set( 'home_url', get_home_url() );
930 }
931 }
932
933 /**
934 * Moves the `indexables_indexation_reason` option to the
935 * renamed `indexing_reason` option.
936 *
937 * @return void
938 */
939 protected function move_indexables_indexation_reason_for_151() {
940 $reason = WPSEO_Options::get( 'indexables_indexation_reason', '' );
941 WPSEO_Options::set( 'indexing_reason', $reason );
942 }
943
944 /**
945 * Checks if the indexable indexation is completed.
946 * If so, sets the `indexables_indexation_completed` option to `true`,
947 * else to `false`.
948 */
949 public function set_indexation_completed_option_for_145() {
950 WPSEO_Options::set( 'indexables_indexation_completed', YoastSEO()->helpers->indexing->get_limited_filtered_unindexed_count( 1 ) === 0 );
951 }
952
953 /**
954 * Cleans up the private taxonomies from the indexables table for the upgrade routine to 14.1.
955 */
956 public function clean_up_private_taxonomies_for_141() {
957 global $wpdb;
958
959 // If migrations haven't been completed successfully the following may give false errors. So suppress them.
960 $show_errors = $wpdb->show_errors;
961 $wpdb->show_errors = false;
962
963 // Clean up indexables of private taxonomies.
964 $private_taxonomies = \get_taxonomies( [ 'public' => false ], 'names' );
965
966 if ( empty( $private_taxonomies ) ) {
967 return;
968 }
969
970 $indexable_table = Model::get_table_name( 'Indexable' );
971
972 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
973 $query = $wpdb->prepare(
974 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: Too hard to fix.
975 "DELETE FROM $indexable_table
976 WHERE object_type = 'term'
977 AND object_sub_type IN ("
978 . \implode( ', ', \array_fill( 0, \count( $private_taxonomies ), '%s' ) )
979 . ')',
980 $private_taxonomies
981 );
982 $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already.
983
984 $wpdb->show_errors = $show_errors;
985 }
986
987 /**
988 * Resets the permalinks of attachments to `null` in the indexable table for the upgrade routine to 14.1.
989 */
990 private function reset_permalinks_of_attachments_for_141() {
991 global $wpdb;
992
993 // If migrations haven't been completed succesfully the following may give false errors. So suppress them.
994 $show_errors = $wpdb->show_errors;
995 $wpdb->show_errors = false;
996
997 // Reset the permalinks of the attachments in the indexable table.
998 $indexable_table = Model::get_table_name( 'Indexable' );
999 $query = "UPDATE $indexable_table SET permalink = NULL WHERE object_type = 'post' AND object_sub_type = 'attachment'";
1000 $wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: There is no user input.
1001
1002 $wpdb->show_errors = $show_errors;
1003 }
1004
1005 /**
1006 * Removes notifications from the Notification center for the 14.1 upgrade.
1007 *
1008 * @return void
1009 */
1010 public function remove_notifications_for_141() {
1011 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-recalculate' );
1012 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-blog-public-notice' );
1013 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-links-table-not-accessible' );
1014 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-post-type-archive-notification' );
1015 }
1016
1017 /**
1018 * Removes the wpseo-suggested-plugin-yoast-acf-analysis notification from the Notification center for the 14.2 upgrade.
1019 *
1020 * @return void
1021 */
1022 public function remove_acf_notification_for_142() {
1023 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-suggested-plugin-yoast-acf-analysis' );
1024 }
1025
1026 /**
1027 * Removes the wpseo-plugin-updated notification from the Notification center for the 15.7 upgrade.
1028 *
1029 * @return void
1030 */
1031 public function remove_plugin_updated_notification_for_157() {
1032 Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-plugin-updated' );
1033 }
1034
1035 /**
1036 * Removes all notifications saved in the database under 'wp_yoast_notifications'.
1037 *
1038 * @return void
1039 */
1040 private function clean_all_notifications() {
1041 global $wpdb;
1042 delete_metadata( 'user', 0, $wpdb->get_blog_prefix() . Yoast_Notification_Center::STORAGE_KEY, '', true );
1043 }
1044
1045 /**
1046 * Removes the post meta fields for a given meta key.
1047 *
1048 * @param string $meta_key The meta key.
1049 *
1050 * @return void
1051 */
1052 private function delete_post_meta( $meta_key ) {
1053 global $wpdb;
1054 $deleted = $wpdb->delete( $wpdb->postmeta, [ 'meta_key' => $meta_key ], [ '%s' ] );
1055
1056 if ( $deleted ) {
1057 wp_cache_set( 'last_changed', microtime(), 'posts' );
1058 }
1059 }
1060
1061 /**
1062 * Removes all sitemap validators.
1063 *
1064 * This should be executed on every upgrade routine until we have removed the sitemap caching in the database.
1065 *
1066 * @return void
1067 */
1068 private function remove_sitemap_validators() {
1069 global $wpdb;
1070
1071 // Remove all sitemap validators.
1072 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'wpseo_sitemap%validator%'" );
1073 }
1074
1075 /**
1076 * Retrieves the option value directly from the database.
1077 *
1078 * @param string $option_name Option to retrieve.
1079 *
1080 * @return array|mixed The content of the option if exists, otherwise an empty array.
1081 */
1082 protected function get_option_from_database( $option_name ) {
1083 global $wpdb;
1084
1085 // Load option directly from the database, to avoid filtering and sanitization.
1086 $sql = $wpdb->prepare( 'SELECT option_value FROM ' . $wpdb->options . ' WHERE option_name = %s', $option_name );
1087 $results = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is is already prepared.
1088 if ( ! empty( $results ) ) {
1089 return maybe_unserialize( $results[0]['option_value'] );
1090 }
1091
1092 return [];
1093 }
1094
1095 /**
1096 * Cleans the option to make sure only relevant settings are there.
1097 *
1098 * @param string $option_name Option name save.
1099 *
1100 * @return void
1101 */
1102 protected function cleanup_option_data( $option_name ) {
1103 $data = get_option( $option_name, [] );
1104 if ( ! is_array( $data ) || $data === [] ) {
1105 return;
1106 }
1107
1108 /*
1109 * Clean up the option by re-saving it.
1110 *
1111 * The option framework will remove any settings that are not configured
1112 * for this option, removing any migrated settings.
1113 */
1114 update_option( $option_name, $data );
1115 }
1116
1117 /**
1118 * Saves an option setting to where it should be stored.
1119 *
1120 * @param array $source_data The option containing the value to be migrated.
1121 * @param string $source_setting Name of the key in the "from" option.
1122 * @param string|null $target_setting Name of the key in the "to" option.
1123 *
1124 * @return void
1125 */
1126 protected function save_option_setting( $source_data, $source_setting, $target_setting = null ) {
1127 if ( $target_setting === null ) {
1128 $target_setting = $source_setting;
1129 }
1130
1131 if ( isset( $source_data[ $source_setting ] ) ) {
1132 WPSEO_Options::set( $target_setting, $source_data[ $source_setting ] );
1133 }
1134 }
1135
1136 /**
1137 * Migrates WooCommerce archive settings to the WooCommerce Shop page meta-data settings.
1138 *
1139 * If no Shop page is defined, nothing will be migrated.
1140 *
1141 * @return void
1142 */
1143 private function migrate_woocommerce_archive_setting_to_shop_page() {
1144 $shop_page_id = wc_get_page_id( 'shop' );
1145
1146 if ( $shop_page_id === -1 ) {
1147 return;
1148 }
1149
1150 $title = WPSEO_Meta::get_value( 'title', $shop_page_id );
1151
1152 if ( empty( $title ) ) {
1153 $option_title = WPSEO_Options::get( 'title-ptarchive-product' );
1154
1155 WPSEO_Meta::set_value(
1156 'title',
1157 $option_title,
1158 $shop_page_id
1159 );
1160
1161 WPSEO_Options::set( 'title-ptarchive-product', '' );
1162 }
1163
1164 $meta_description = WPSEO_Meta::get_value( 'metadesc', $shop_page_id );
1165
1166 if ( empty( $meta_description ) ) {
1167 $option_metadesc = WPSEO_Options::get( 'metadesc-ptarchive-product' );
1168
1169 WPSEO_Meta::set_value(
1170 'metadesc',
1171 $option_metadesc,
1172 $shop_page_id
1173 );
1174
1175 WPSEO_Options::set( 'metadesc-ptarchive-product', '' );
1176 }
1177
1178 $bc_title = WPSEO_Meta::get_value( 'bctitle', $shop_page_id );
1179
1180 if ( empty( $bc_title ) ) {
1181 $option_bctitle = WPSEO_Options::get( 'bctitle-ptarchive-product' );
1182
1183 WPSEO_Meta::set_value(
1184 'bctitle',
1185 $option_bctitle,
1186 $shop_page_id
1187 );
1188
1189 WPSEO_Options::set( 'bctitle-ptarchive-product', '' );
1190 }
1191
1192 $noindex = WPSEO_Meta::get_value( 'meta-robots-noindex', $shop_page_id );
1193
1194 if ( $noindex === '0' ) {
1195 $option_noindex = WPSEO_Options::get( 'noindex-ptarchive-product' );
1196
1197 WPSEO_Meta::set_value(
1198 'meta-robots-noindex',
1199 $option_noindex,
1200 $shop_page_id
1201 );
1202
1203 WPSEO_Options::set( 'noindex-ptarchive-product', false );
1204 }
1205 }
1206
1207 /**
1208 * Stores the initial `permalink_structure` option.
1209 *
1210 * @return void
1211 */
1212 public function set_permalink_structure_option_for_151() {
1213 WPSEO_Options::set( 'permalink_structure', get_option( 'permalink_structure' ) );
1214 }
1215
1216 /**
1217 * Stores the initial slugs of custom taxonomies.
1218 *
1219 * @return void
1220 */
1221 public function store_custom_taxonomy_slugs_for_151() {
1222 $taxonomies = $this->taxonomy_helper->get_custom_taxonomies();
1223
1224 $custom_taxonomies = [];
1225
1226 foreach ( $taxonomies as $taxonomy ) {
1227 $slug = $this->taxonomy_helper->get_taxonomy_slug( $taxonomy );
1228
1229 $custom_taxonomies[ $taxonomy ] = $slug;
1230 }
1231
1232 WPSEO_Options::set( 'custom_taxonomy_slugs', $custom_taxonomies );
1233 }
1234
1235 /**
1236 * Copies the frontpage social settings to the titles options.
1237 *
1238 * @return void
1239 */
1240 public function copy_og_settings_from_social_to_titles() {
1241 $wpseo_social = get_option( 'wpseo_social' );
1242 $wpseo_titles = get_option( 'wpseo_titles' );
1243
1244 $copied_options = [];
1245 // Reset to the correct default value.
1246 $copied_options['open_graph_frontpage_title'] = '%%sitename%%';
1247
1248 $options = [
1249 'og_frontpage_title' => 'open_graph_frontpage_title',
1250 'og_frontpage_desc' => 'open_graph_frontpage_desc',
1251 'og_frontpage_image' => 'open_graph_frontpage_image',
1252 'og_frontpage_image_id' => 'open_graph_frontpage_image_id',
1253 ];
1254
1255 foreach ( $options as $social_option => $titles_option ) {
1256 if ( ! empty( $wpseo_social[ $social_option ] ) ) {
1257 $copied_options[ $titles_option ] = $wpseo_social[ $social_option ];
1258 }
1259 }
1260
1261 $wpseo_titles = array_merge( $wpseo_titles, $copied_options );
1262
1263 update_option( 'wpseo_titles', $wpseo_titles );
1264 }
1265
1266 /**
1267 * Reset the social options with the correct default values.
1268 *
1269 * @return void
1270 */
1271 public function reset_og_settings_to_default_values() {
1272 $wpseo_titles = get_option( 'wpseo_titles' );
1273 $updated_options = [];
1274
1275 $updated_options['social-title-author-wpseo'] = '%%name%%';
1276 $updated_options['social-title-archive-wpseo'] = '%%date%%';
1277
1278 /* translators: %s expands to the name of a post type (plural). */
1279 $post_type_archive_default = sprintf( __( '%s Archive', 'wordpress-seo' ), '%%pt_plural%%' );
1280
1281 /* translators: %s expands to the variable used for term title. */
1282 $term_archive_default = sprintf( __( '%s Archives', 'wordpress-seo' ), '%%term_title%%' );
1283
1284 $post_type_objects = get_post_types( [ 'public' => true ], 'objects' );
1285
1286 if ( $post_type_objects ) {
1287 foreach ( $post_type_objects as $pt ) {
1288 // Post types.
1289 if ( isset( $wpseo_titles[ 'social-title-' . $pt->name ] ) ) {
1290 $updated_options[ 'social-title-' . $pt->name ] = '%%title%%';
1291 }
1292 // Post type archives.
1293 if ( isset( $wpseo_titles[ 'social-title-ptarchive-' . $pt->name ] ) ) {
1294 $updated_options[ 'social-title-ptarchive-' . $pt->name ] = $post_type_archive_default;
1295 }
1296 }
1297 }
1298
1299 $taxonomy_objects = get_taxonomies( [ 'public' => true ], 'object' );
1300
1301 if ( $taxonomy_objects ) {
1302 foreach ( $taxonomy_objects as $tax ) {
1303 if ( isset( $wpseo_titles[ 'social-title-tax-' . $tax->name ] ) ) {
1304 $updated_options[ 'social-title-tax-' . $tax->name ] = $term_archive_default;
1305 }
1306 }
1307 }
1308
1309 $wpseo_titles = array_merge( $wpseo_titles, $updated_options );
1310
1311 update_option( 'wpseo_titles', $wpseo_titles );
1312 }
1313 }
1314