PluginProbe
Polylang / 2.9
Polylang v2.9
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / install / upgrade.php

upgrade.php in Polylang 2.9, at install/upgrade.php

652 lines 20.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * Manages Polylang upgrades
8 *
9 * @since 1.2
10 */
11 class PLL_Upgrade {
12 public $options;
13
14 /**
15 * Constructor
16 *
17 * @since 1.2
18 *
19 * @param array $options Polylang options
20 */
21 public function __construct( &$options ) {
22 $this->options = &$options;
23 }
24
25 /**
26 * Check if upgrade is possible otherwise die to avoid activation
27 *
28 * @since 1.2
29 */
30 public function can_activate() {
31 if ( ! $this->can_upgrade() ) {
32 ob_start();
33 $this->admin_notices(); // FIXME the error message is displayed two times
34 die( ob_get_contents() ); // phpcs:ignore WordPress.Security.EscapeOutput
35 }
36 }
37
38 /**
39 * Upgrades if possible otherwise returns false to stop Polylang loading
40 *
41 * @since 1.2
42 *
43 * @return bool true if upgrade is possible, false otherwise
44 */
45 public function upgrade() {
46 if ( ! $this->can_upgrade() ) {
47 add_action( 'all_admin_notices', array( $this, 'admin_notices' ) );
48 return false;
49 }
50
51 add_action( 'admin_init', array( $this, '_upgrade' ) );
52 return true;
53 }
54
55
56 /**
57 * Check if we the previous version is not too old
58 * Upgrades if OK
59 * /!\ never start any upgrade before admin_init as it is likely to conflict with some other plugins
60 *
61 * @since 1.2
62 *
63 * @return bool true if upgrade is possible, false otherwise
64 */
65 public function can_upgrade() {
66 // Don't manage upgrade from version < 0.8
67 return version_compare( $this->options['version'], '0.8', '>=' );
68 }
69
70 /**
71 * Displays a notice when ugrading from a too old version
72 *
73 * @since 1.0
74 */
75 public function admin_notices() {
76 load_plugin_textdomain( 'polylang' );
77 printf(
78 '<div class="error"><p>%s</p><p>%s</p></div>',
79 esc_html__( 'Polylang has been deactivated because you upgraded from a too old version.', 'polylang' ),
80 sprintf(
81 /* translators: %1$s and %2$s are Polylang version numbers */
82 esc_html__( 'Before upgrading to %2$s, please upgrade to %1$s.', 'polylang' ),
83 '<strong>0.9.8</strong>',
84 POLYLANG_VERSION // phpcs:ignore WordPress.Security.EscapeOutput
85 )
86 );
87 }
88
89 /**
90 * Upgrades the plugin depending on the previous version
91 *
92 * @since 1.2
93 */
94 public function _upgrade() {
95 foreach ( array( '0.9', '1.0', '1.1', '1.2', '1.2.1', '1.2.3', '1.3', '1.4', '1.4.1', '1.4.4', '1.5', '1.6', '1.7.4', '1.8', '2.0.8', '2.1', '2.7', '2.8.1' ) as $version ) {
96 if ( version_compare( $this->options['version'], $version, '<' ) ) {
97 call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
98 }
99 }
100
101 $delete_pre_1_2_data = get_transient( 'pll_upgrade_1_4' );
102 if ( false !== $delete_pre_1_2_data && absint( $delete_pre_1_2_data ) < time() ) {
103 $this->delete_pre_1_2_data();
104 }
105
106 $this->options['previous_version'] = $this->options['version']; // Remember the previous version of Polylang since v1.7.7
107 $this->options['version'] = POLYLANG_VERSION;
108 update_option( 'polylang', $this->options );
109 }
110
111 /**
112 * Upgrades if the previous version is < 0.9
113 *
114 * @since 1.2
115 */
116 protected function upgrade_0_9() {
117 $this->options['sync'] = defined( 'PLL_SYNC' ) && ! PLL_SYNC ? 0 : 1; // The option replaces PLL_SYNC in 0.9
118 }
119
120 /**
121 * Upgrades if the previous version is < 1.0
122 *
123 * @since 1.2
124 */
125 protected function upgrade_1_0() {
126 // The option replaces PLL_MEDIA_SUPPORT in 1.0
127 $this->options['media_support'] = defined( 'PLL_MEDIA_SUPPORT' ) && ! PLL_MEDIA_SUPPORT ? 0 : 1;
128
129 // Split the synchronization options in 1.0
130 $this->options['sync'] = empty( $this->options['sync'] ) ? array() : array_keys( PLL_Settings_Sync::list_metas_to_sync() );
131
132 // Set default values for post types and taxonomies to translate
133 $this->options['post_types'] = array_values( get_post_types( array( '_builtin' => false, 'show_ui' => true ) ) );
134 $this->options['taxonomies'] = array_values( get_taxonomies( array( '_builtin' => false, 'show_ui' => true ) ) );
135 update_option( 'polylang', $this->options );
136
137 flush_rewrite_rules(); // Rewrite rules have been modified in 1.0
138 }
139
140 /**
141 * Upgrades if the previous version is < 1.1
142 *
143 * @since 1.2
144 */
145 protected function upgrade_1_1() {
146 // Update strings register with icl_register_string
147 $strings = get_option( 'polylang_wpml_strings' );
148 if ( $strings ) {
149 foreach ( array_keys( $strings ) as $key ) {
150 $strings[ $key ]['icl'] = 1;
151 }
152 update_option( 'polylang_wpml_strings', $strings );
153 }
154
155 // Move polylang_widgets options
156 if ( $widgets = get_option( 'polylang_widgets' ) ) {
157 $this->options['widgets'] = $widgets;
158 delete_option( 'polylang_widgets' );
159 }
160 }
161
162 /**
163 * Upgrades if the previous version is < 1.2
164 *
165 * @since 1.2
166 */
167 protected function upgrade_1_2() {
168 $this->options['domains'] = array(); // Option added in 1.2
169
170 // Need to register the taxonomies
171 foreach ( array( 'language', 'term_language', 'post_translations', 'term_translations' ) as $taxonomy ) {
172 register_taxonomy( $taxonomy, null, array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false ) );
173 }
174
175 // Abort if the db upgrade has already been done previously
176 if ( get_terms( 'term_language', array( 'hide_empty' => 0 ) ) ) {
177 return;
178 }
179
180 set_time_limit( 0 ); // In case we upgrade a huge site
181
182 // Upgrade old model based on metas to new model based on taxonomies
183 global $wpdb;
184 $wpdb->termmeta = $wpdb->prefix . 'termmeta'; // Registers the termmeta table in wpdb
185 $languages = get_terms( 'language', array( 'hide_empty' => 0 ) ); // Don't use get_languages_list which can't work with the old model
186 $lang_tt_ids = array();
187
188 foreach ( $languages as $lang ) {
189 // First update language with new storage for locale and text direction
190 $text_direction = get_metadata( 'term', $lang->term_id, '_rtl', true );
191 $desc = maybe_serialize( array( 'locale' => $lang->description, 'rtl' => $text_direction ) );
192 wp_update_term( (int) $lang->term_id, 'language', array( 'description' => $desc ) );
193
194 // Add language to new 'term_language' taxonomy
195 $term_lang = wp_insert_term( $lang->name, 'term_language', array( 'slug' => 'pll_' . $lang->slug ) );
196 $lang_tt_ids[ $lang->term_id ] = $term_lang['term_taxonomy_id']; // Keep the term taxonomy id for future
197 }
198
199 // Get all terms with a language defined
200 $terms = $wpdb->get_results( "SELECT term_id, meta_value FROM {$wpdb->termmeta} WHERE meta_key = '_language'" );
201 foreach ( $terms as $key => $term ) {
202 $terms[ $key ] = $wpdb->prepare( '( %d, %d )', $term->term_id, $lang_tt_ids[ $term->meta_value ] );
203 }
204
205 $terms = array_unique( $terms );
206
207 // Assign language to each term
208 if ( ! empty( $terms ) ) {
209 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
210 $wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $terms ) );
211 }
212
213 // Translations
214 foreach ( array( 'post', 'term' ) as $type ) {
215 $table = $type . 'meta';
216 $terms = array();
217 $slugs = array();
218 $tts = array();
219 $trs = array();
220 $description = array();
221
222 // Get all translated objects
223 // PHPCS:ignore WordPress.DB.PreparedSQL
224 $objects = $wpdb->get_col( "SELECT DISTINCT meta_value FROM {$wpdb->$table} WHERE meta_key = '_translations'" );
225
226 if ( empty( $objects ) ) {
227 continue;
228 }
229
230 foreach ( $objects as $obj ) {
231 $term = uniqid( 'pll_' ); // The term name
232 $terms[] = $wpdb->prepare( '( %s, %s )', $term, $term );
233 $slugs[] = $wpdb->prepare( '%s', $term );
234 $translations = maybe_unserialize( maybe_unserialize( $obj ) ); // 2 maybe_unserialize due to an old storage bug
235 $description[ $term ] = maybe_serialize( $translations );
236 }
237
238 $terms = array_unique( $terms );
239
240 // Insert terms
241 if ( ! empty( $terms ) ) {
242 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
243 $wpdb->query( "INSERT INTO {$wpdb->terms} ( slug, name ) VALUES " . implode( ',', $terms ) );
244 }
245
246 // Get all terms with their term_id
247 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
248 $terms = $wpdb->get_results( "SELECT term_id, slug FROM $wpdb->terms WHERE slug IN ( " . implode( ',', $slugs ) . ' )' );
249
250 // Prepare terms taxonomy relationship
251 foreach ( $terms as $term ) {
252 $tts[] = $wpdb->prepare( '( %d, %s, %s )', $term->term_id, $type . '_translations', $description[ $term->slug ] );
253 }
254
255 $tts = array_unique( $tts );
256
257 // Insert term_taxonomy
258 if ( ! empty( $tts ) ) {
259 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
260 $wpdb->query( "INSERT INTO {$wpdb->term_taxonomy} ( term_id, taxonomy, description ) VALUES " . implode( ',', $tts ) );
261 }
262
263 // Get all terms with term_taxonomy_id
264 $terms = get_terms( $type . '_translations', array( 'hide_empty' => false ) );
265
266 // Prepare objects relationships
267 foreach ( $terms as $term ) {
268 $translations = maybe_unserialize( $term->description );
269 foreach ( $translations as $object_id ) {
270 if ( ! empty( $object_id ) ) {
271 $trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
272 }
273 }
274 }
275
276 $trs = array_unique( $trs );
277
278 // Insert term_relationships
279 if ( ! empty( $trs ) ) {
280 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
281 $wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $trs ) );
282 }
283 }
284
285 // Upgrade of string translations is now in upgrade_1_2_1
286 // Upgrade of nav menus is now in upgrade_1_2_3
287 }
288
289 /**
290 * Upgrades if the previous version is < 1.2.1
291 *
292 * @since 1.2.1
293 */
294 protected function upgrade_1_2_1() {
295 // Strings translations
296 foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
297 if ( $strings = get_option( 'polylang_mo' . $lang->term_id ) ) {
298 $mo = new PLL_MO();
299 foreach ( $strings as $msg ) {
300 $mo->add_entry( $mo->make_entry( $msg[0], $msg[1] ) );
301 }
302 $mo->export_to_db( $lang );
303 }
304 }
305 }
306
307 /**
308 * Upgrades if the previous version is < 1.2.3
309 * Uprades multilingual menus depending on the old version due to multiple changes in menus management
310 *
311 * @since 1.2.3
312 */
313 public function upgrade_1_2_3() {
314 // Old version < 1.1
315 // Multilingal locations and switcher item were stored in a dedicated option
316 if ( version_compare( $this->options['version'], '1.1', '<' ) ) {
317 if ( $menu_lang = get_option( 'polylang_nav_menus' ) ) {
318 $locations = array();
319
320 foreach ( $menu_lang as $location => $arr ) {
321 if ( ! in_array( $location, array_keys( get_registered_nav_menus() ) ) ) {
322 continue;
323 }
324
325 $switch_options = array_slice( $arr, -5, 5 );
326 $translations = array_diff_key( $arr, $switch_options );
327 $has_switcher = array_shift( $switch_options );
328
329 foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
330 // Move nav menus locations
331 if ( ! empty( $translations[ $lang->slug ] ) ) {
332 $locations[ $location ][ $lang->slug ] = $translations[ $lang->slug ];
333 }
334
335 // Create the menu items for the language switcher
336 if ( ! empty( $has_switcher ) ) {
337 $menu_item_db_id = wp_update_nav_menu_item(
338 $translations[ $lang->slug ],
339 0,
340 array(
341 'menu-item-title' => __( 'Language switcher', 'polylang' ),
342 'menu-item-url' => '#pll_switcher',
343 'menu-item-status' => 'publish',
344 )
345 );
346
347 update_post_meta( $menu_item_db_id, '_pll_menu_item', $switch_options );
348 }
349 }
350 }
351
352 if ( ! empty( $locations ) ) {
353 $this->options['nav_menus'][ get_option( 'stylesheet' ) ] = $locations;
354 }
355
356 delete_option( 'polylang_nav_menus' );
357 }
358 }
359
360 elseif ( empty( $this->options['nav_menus'] ) ) {
361 $menus = get_theme_mod( 'nav_menu_locations' );
362
363 if ( is_array( $menus ) ) {
364 // If old version < 1.2
365 // Clean the WP option as it was a bad idea to pollute it
366 if ( version_compare( $this->options['version'], '1.2', '<' ) ) {
367 foreach ( $menus as $loc => $menu ) {
368 if ( strpos( $loc, '#' ) ) {
369 unset( $menus[ $loc ] );
370 }
371 }
372
373 set_theme_mod( 'nav_menu_locations', $menus );
374 }
375
376 // Get the multilingual locations
377 foreach ( $menus as $loc => $menu ) {
378 foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
379 $arr[ $loc ][ $lang->slug ] = pll_get_term( $menu, $lang );
380 }
381 }
382
383 if ( ! empty( $arr ) ) {
384 $this->options['nav_menus'][ get_option( 'stylesheet' ) ] = $arr;
385 }
386 }
387 }
388 }
389
390 /**
391 * Upgrades if the previous version is < 1.3
392 * Moves the user biographies in default language to the 'description' user meta
393 *
394 * @since 1.3
395 */
396 protected function upgrade_1_3() {
397 $usermeta = 'description_' . $this->options['default_lang'];
398 $query = new WP_User_Query( array( 'blog_id' => $GLOBALS['blog_id'], 'meta_key' => $usermeta ) );
399
400 foreach ( $query->get_results() as $user ) {
401 $desc = get_user_meta( $user->ID, $usermeta, true );
402 if ( ! empty( $desc ) ) {
403 update_user_meta( $user->ID, 'description', $desc );
404 delete_user_meta( $user->ID, $usermeta );
405 }
406 }
407 }
408
409 /**
410 * Upgrades if the previous version is < 1.4
411 * Sets a transient to delete old model data
412 * Deletes language cache (due to bug correction in home urls in 1.3.1 and added mo_id in 1.4)
413 *
414 * @since 1.4
415 */
416 protected function upgrade_1_4() {
417 set_transient( 'pll_upgrade_1_4', time() + 60 * 24 * 60 * 60 ); // 60 days
418 delete_transient( 'pll_languages_list' );
419 }
420
421 /**
422 * Old data were not deleted in 1.2, just in case...
423 * Delete them at first upgrade at least 60 days after upgrade to 1.4
424 *
425 * @since 1.4
426 */
427 protected function delete_pre_1_2_data() {
428 // Suppress data of the old model < 1.2
429 global $wpdb;
430 $wpdb->termmeta = $wpdb->prefix . 'termmeta'; // registers the termmeta table in wpdb in case WP < 4.4
431
432 // Do nothing if the termmeta table does not exists
433 if ( count( $wpdb->get_results( "SHOW TABLES LIKE '$wpdb->termmeta'" ) ) ) {
434 $wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_translations'" );
435 $wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_language'" );
436 $wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_rtl'" );
437 $wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_translations'" );
438 }
439
440 // Delete the strings translations
441 $languages = get_terms( 'language', array( 'hide_empty' => false ) );
442 foreach ( $languages as $lang ) {
443 delete_option( 'polylang_mo' . $lang->term_id );
444 }
445
446 delete_transient( 'pll_upgrade_1_4' );
447 }
448
449 /**
450 * Upgrades if the previous version is < 1.4.1
451 * Disables the browser detection when using multiple domains
452 *
453 * @since 1.4.1
454 */
455 protected function upgrade_1_4_1() {
456 if ( 3 == $this->options['force_lang'] ) {
457 $this->options['browser'] = $this->options['hide_default'] = 0;
458 }
459 }
460
461 /**
462 * Upgrades if the previous version is < 1.4.4
463 * Uprades widgets options for language filter
464 *
465 * @since 1.4.4
466 */
467 protected function upgrade_1_4_4() {
468 foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
469 if ( ! empty( $this->options['widgets'][ $widget['id'] ] ) && ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
470 $obj = $widget['callback'][0];
471 if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
472 $settings = $obj->get_settings();
473 $settings[ $widget['params'][0]['number'] ]['pll_lang'] = $this->options['widgets'][ $widget['id'] ];
474 $obj->save_settings( $settings );
475 }
476 }
477 }
478 unset( $this->options['widgets'] );
479 }
480
481 /**
482 * Upgrades if the previous version is < 1.5
483 * Deletes language cache (due to host property added and bug on search url)
484 *
485 * @since 1.5
486 */
487 protected function upgrade_1_5() {
488 delete_transient( 'pll_languages_list' );
489 }
490
491 /**
492 * Upgrades if the previous version is < 1.6
493 * Upgrades core language files to get the .po file (only for WP 4.0+)
494 *
495 * @since 1.6
496 */
497 protected function upgrade_1_6() {
498 if ( version_compare( $GLOBALS['wp_version'], '4.0', '>=' ) ) {
499 self::download_language_packs();
500 }
501 }
502
503 /**
504 * Downloads language packs
505 * Intended to be used only one time (at upgrade to Polylang 1.6 or first upgrade of WP 4.0 or later)
506 * Adapted from wp_download_language_pack
507 * Rewritten because wp_download_language_pack checks the existence of .mo and I need to download .po
508 *
509 * @since 1.6
510 */
511 public static function download_language_packs() {
512 $languages = pll_languages_list( array( 'fields' => 'locale' ) );
513
514 // Prevents upgrade if the .po file is already here. Let WP manage the upgrades :)
515 foreach ( $languages as $key => $locale ) {
516 if ( file_exists( WP_LANG_DIR . "/$locale.po" ) ) {
517 unset( $languages[ $key ] );
518 }
519 }
520
521 if ( empty( $languages ) ) {
522 return;
523 }
524
525 require_once ABSPATH . 'wp-admin/includes/translation-install.php';
526 $translations = wp_get_available_translations();
527 if ( ! $translations ) {
528 return;
529 }
530
531 $translations_to_load = array();
532
533 foreach ( $translations as $translation ) {
534 if ( in_array( $translation['language'], $languages ) ) {
535 $translation['type'] = 'core';
536 $translations_to_load[] = (object) $translation;
537 }
538 }
539
540 if ( ! empty( $translations_to_load ) ) {
541 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
542 $upgrader = new Language_Pack_Upgrader( new Automatic_Upgrader_Skin() );
543 $upgrader->bulk_upgrade( $translations_to_load, array( 'clear_update_cache' => false ) );
544 }
545 }
546
547 /**
548 * Upgrades if the previous version is < 1.7.4
549 *
550 * @since 1.7.4
551 */
552 protected function upgrade_1_7_4() {
553 delete_transient( 'pll_languages_list' ); // Deletes language cache (due to flag properties added in 1.7, page on front removed in 1.7.2, home url fixes in 1.7.4)
554 flush_rewrite_rules(); // Flush rewrite rules due to custom taxonomy rewrite rule bug fix
555 }
556
557 /**
558 * Upgrades if the previous version is < 1.8
559 *
560 * @since 1.8
561 */
562 protected function upgrade_1_8() {
563 // Adds the flag code in languages stored in DB
564 $languages = include POLYLANG_DIR . '/settings/languages.php';
565
566 $terms = get_terms( 'language', array( 'hide_empty' => 0 ) );
567
568 foreach ( $terms as $lang ) {
569 $description = maybe_unserialize( $lang->description );
570 if ( isset( $languages[ $description['locale'] ] ) ) {
571 $description['flag_code'] = $languages[ $description['locale'] ]['flag'];
572 $description = maybe_serialize( $description );
573 wp_update_term( (int) $lang->term_id, 'language', array( 'description' => $description ) );
574 }
575 }
576
577 delete_transient( 'pll_languages_list' );
578 }
579
580 /**
581 * Upgrades if the previous version is < 2.0.8
582 * Changes the user meta 'user_lang' to 'locale' to match WP 4.7 choice
583 *
584 * @since 2.0.8
585 */
586 protected function upgrade_2_0_8() {
587 global $wpdb;
588 $wpdb->update( $wpdb->usermeta, array( 'meta_key' => 'locale' ), array( 'meta_key' => 'user_lang' ) );
589 }
590
591 /**
592 * Upgrades if the previous version is < 2.1
593 * Moves strings translations from polylang_mo post_content to post meta _pll_strings_translations
594 *
595 * @since 2.1
596 */
597 protected function upgrade_2_1() {
598 foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
599 $mo_id = PLL_MO::get_id( $lang );
600 $meta = get_post_meta( $mo_id, '_pll_strings_translations', true );
601
602 if ( empty( $meta ) ) {
603 $post = get_post( $mo_id, OBJECT );
604 $strings = maybe_unserialize( $post->post_content );
605 if ( is_array( $strings ) ) {
606 update_post_meta( $mo_id, '_pll_strings_translations', $strings );
607 }
608 }
609 }
610 }
611
612 /**
613 * Upgrades if the previous version is < 2.7
614 * Replace numeric keys by hashes in WPML registered strings
615 * Dismiss the wizard notice for existing sites
616 *
617 * @since 2.7
618 */
619 protected function upgrade_2_7() {
620 $strings = get_option( 'polylang_wpml_strings' );
621 if ( is_array( $strings ) ) {
622 $new_strings = array();
623
624 foreach ( $strings as $string ) {
625 $context = $string['context'];
626 $name = $string['name'];
627
628 $key = md5( "$context | $name" );
629 $new_strings[ $key ] = $string;
630 }
631 update_option( 'polylang_wpml_strings', $new_strings );
632 }
633
634 PLL_Admin_Notices::dismiss( 'wizard' );
635 }
636
637 /**
638 * Upgrades if the previous version is < 2.8.1
639 *
640 * Deletes language cache due to:
641 * - 'redirect_lang' option removed for subdomains and multiple domains in 2.2
642 * - W3C and Facebook locales added to PLL_Language objects in 2.3
643 * - flags moved to a different directory in Polylang Pro 2.8
644 * - bug of flags url returning html fixed in 2.8.1
645 *
646 * @since 2.8.1
647 */
648 protected function upgrade_2_8_1() {
649 delete_transient( 'pll_languages_list' );
650 }
651 }
652