PluginProbe
Polylang / 2.7.0.1
Polylang v2.7.0.1
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.7.0.1, at install/upgrade.php

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