PluginProbe
Polylang / 3.7.7
Polylang v3.7.7
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
← All changes | install/upgrade.php +175 -464 2.93.7.7 View file →
@@ -2,8 +2,10 @@
2 2 /**
3 3 * @package Polylang
4 4 */
5 5
6 +use WP_Syntex\Polylang\Options\Options;
7 +
6 8 /**
7 9 * Manages Polylang upgrades
8 10 *
9 11 * @since 1.2
@@ -8,8 +10,13 @@
8 10 *
9 11 * @since 1.2
10 12 */
11 13 class PLL_Upgrade {
14 + /**
15 + * Stores the plugin options.
16 + *
17 + * @var array
18 + */
12 19 public $options;
13 20
14 21 /**
15 22 * Constructor
@@ -25,8 +32,10 @@
25 32 /**
26 33 * Check if upgrade is possible otherwise die to avoid activation
27 34 *
28 35 * @since 1.2
36 + *
37 + * @return void
29 38 */
30 39 public function can_activate() {
31 40 if ( ! $this->can_upgrade() ) {
32 41 ob_start();
@@ -47,8 +56,9 @@
47 56 add_action( 'all_admin_notices', array( $this, 'admin_notices' ) );
48 57 return false;
49 58 }
50 59
60 + delete_transient( 'pll_languages_list' );
51 61 add_action( 'admin_init', array( $this, '_upgrade' ) );
52 62 return true;
53 63 }
54 64
@@ -62,10 +72,10 @@
62 72 *
63 73 * @return bool true if upgrade is possible, false otherwise
64 74 */
65 75 public function can_upgrade() {
66 - // Don't manage upgrade from version < 0.8
67 - return version_compare( $this->options['version'], '0.8', '>=' );
76 + // Don't manage upgrade from version < 1.8
77 + return version_compare( $this->options['version'], '1.8', '>=' );
68 78 }
69 79
70 80 /**
71 81 * Displays a notice when ugrading from a too old version
@@ -70,8 +80,10 @@
70 80 /**
71 81 * Displays a notice when ugrading from a too old version
72 82 *
73 83 * @since 1.0
84 + *
85 + * @return void
74 86 */
75 87 public function admin_notices() {
76 88 load_plugin_textdomain( 'polylang' );
77 89 printf(
@@ -79,9 +91,9 @@
79 91 esc_html__( 'Polylang has been deactivated because you upgraded from a too old version.', 'polylang' ),
80 92 sprintf(
81 93 /* translators: %1$s and %2$s are Polylang version numbers */
82 94 esc_html__( 'Before upgrading to %2$s, please upgrade to %1$s.', 'polylang' ),
83 - '<strong>0.9.8</strong>',
95 + '<strong>2.9</strong>',
84 96 POLYLANG_VERSION // phpcs:ignore WordPress.Security.EscapeOutput
85 97 )
86 98 );
87 99 }
@@ -89,563 +101,262 @@
89 101 /**
90 102 * Upgrades the plugin depending on the previous version
91 103 *
92 104 * @since 1.2
105 + *
106 + * @return void
93 107 */
94 108 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 ) {
109 + foreach ( array( '2.0.8', '2.1', '2.7', '3.4', '3.7' ) as $version ) {
96 110 if ( version_compare( $this->options['version'], $version, '<' ) ) {
97 - call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
111 + $method_to_call = array( $this, 'upgrade_' . str_replace( '.', '_', $version ) );
112 + if ( is_callable( $method_to_call ) ) {
113 + call_user_func( $method_to_call );
114 + }
98 115 }
99 116 }
100 117
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 - }
118 + /**
119 + * Fires after Polylang has been upgraded and before the new version is saved in options.
120 + *
121 + * @since 3.7
122 + */
123 + do_action( 'pll_upgrade' );
105 124
106 125 $this->options['previous_version'] = $this->options['version']; // Remember the previous version of Polylang since v1.7.7
107 126 $this->options['version'] = POLYLANG_VERSION;
108 - update_option( 'polylang', $this->options );
109 127 }
110 128
111 129 /**
112 - * Upgrades if the previous version is < 0.9
130 + * Upgrades if the previous version is < 2.0.8
131 + * Changes the user meta 'user_lang' to 'locale' to match WP 4.7 choice
113 132 *
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
133 + * @since 2.0.8
122 134 *
123 - * @since 1.2
135 + * @return void
124 136 */
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
137 + protected function upgrade_2_0_8() {
138 + global $wpdb;
139 + $wpdb->update( $wpdb->usermeta, array( 'meta_key' => 'locale' ), array( 'meta_key' => 'user_lang' ) );
138 140 }
139 141
140 142 /**
141 - * Upgrades if the previous version is < 1.1
143 + * Upgrades if the previous version is < 2.1.
144 + * Moves strings translations from polylang_mo post_content to post meta _pll_strings_translations.
142 145 *
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
146 + * @since 2.1
164 147 *
165 - * @since 1.2
148 + * @return void
166 149 */
167 - protected function upgrade_1_2() {
168 - $this->options['domains'] = array(); // Option added in 1.2
150 + protected function upgrade_2_1() {
151 + $posts = get_posts(
152 + array(
153 + 'post_type' => 'polylang_mo',
154 + 'post_status' => 'any',
155 + 'numberposts' => -1,
156 + 'nopaging' => true,
157 + )
158 + );
169 159
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 - }
160 + if ( is_array( $posts ) ) {
161 + foreach ( $posts as $post ) {
162 + $meta = get_post_meta( $post->ID, '_pll_strings_translations', true );
174 163
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 );
164 + if ( empty( $meta ) ) {
165 + $strings = maybe_unserialize( $post->post_content );
166 + if ( is_array( $strings ) ) {
167 + update_post_meta( $post->ID, '_pll_strings_translations', $strings );
272 168 }
273 169 }
274 170 }
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 171 }
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 172 }
288 173
289 174 /**
290 - * Upgrades if the previous version is < 1.2.1
175 + * Upgrades if the previous version is < 2.7
176 + * Replace numeric keys by hashes in WPML registered strings
177 + * Dismiss the wizard notice for existing sites
291 178 *
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
179 + * @since 2.7
310 180 *
311 - * @since 1.2.3
181 + * @return void
312 182 */
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();
183 + protected function upgrade_2_7() {
184 + $strings = get_option( 'polylang_wpml_strings' );
185 + if ( is_array( $strings ) ) {
186 + $new_strings = array();
319 187
320 - foreach ( $menu_lang as $location => $arr ) {
321 - if ( ! in_array( $location, array_keys( get_registered_nav_menus() ) ) ) {
322 - continue;
323 - }
188 + foreach ( $strings as $string ) {
189 + $context = $string['context'];
190 + $name = $string['name'];
324 191
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' );
192 + $key = md5( "$context | $name" );
193 + $new_strings[ $key ] = $string;
357 194 }
195 + update_option( 'polylang_wpml_strings', $new_strings );
358 196 }
359 197
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 - }
198 + PLL_Admin_Notices::dismiss( 'wizard' );
388 199 }
389 200
390 201 /**
391 - * Upgrades if the previous version is < 1.3
392 - * Moves the user biographies in default language to the 'description' user meta
202 + * Upgrades if the previous version is < 3.4.0.
393 203 *
394 - * @since 1.3
204 + * @since 3.4
205 + *
206 + * @return void
395 207 */
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 ) );
208 + protected function upgrade_3_4() {
209 + $this->migrate_locale_fallback_to_language_description();
399 210
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 - }
211 + $this->migrate_strings_translations();
407 212 }
408 213
409 214 /**
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)
215 + * Upgrades if the previous version is < 3.7.
216 + * Hides the "The language is set from content" option if it isn't the one selected.
217 + * Cleans up strings translations so we don't store translations duplicated from the source.
413 218 *
414 - * @since 1.4
219 + * @since 3.7
220 + *
221 + * @return void
415 222 */
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' );
223 + protected function upgrade_3_7() {
224 + $this->allow_to_hide_language_from_content();
225 + $this->empty_duplicated_strings_translations();
419 226 }
420 227
421 228 /**
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
229 + * Moves strings translations from post meta to term meta _pll_strings_translations.
424 230 *
425 - * @since 1.4
231 + * @since 3.4
232 + *
233 + * @return void
426 234 */
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
235 + protected function migrate_strings_translations() {
236 + $posts = get_posts(
237 + array(
238 + 'post_type' => 'polylang_mo',
239 + 'post_status' => 'any',
240 + 'numberposts' => -1,
241 + 'nopaging' => true,
242 + )
243 + );
431 244
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'" );
245 + if ( ! is_array( $posts ) ) {
246 + return;
438 247 }
439 248
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 - }
249 + foreach ( $posts as $post ) {
250 + $meta = get_post_meta( $post->ID, '_pll_strings_translations', true );
445 251
446 - delete_transient( 'pll_upgrade_1_4' );
447 - }
252 + $term_id = (int) substr( $post->post_title, 12 );
448 253
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 - }
254 + // Do not delete post metas in case a user needs to rollback to Polylang < 3.4.
460 255
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 - }
256 + if ( empty( $meta ) || ! is_array( $meta ) ) {
257 + continue;
476 258 }
259 +
260 + update_term_meta( $term_id, '_pll_strings_translations', wp_slash( $meta ) );
477 261 }
478 - unset( $this->options['widgets'] );
479 262 }
480 263
481 264 /**
482 - * Upgrades if the previous version is < 1.5
483 - * Deletes language cache (due to host property added and bug on search url)
265 + * Migrate locale fallback to language term description.
484 266 *
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+)
267 + * @since 3.4
494 268 *
495 - * @since 1.6
269 + * @return void
496 270 */
497 - protected function upgrade_1_6() {
498 - if ( version_compare( $GLOBALS['wp_version'], '4.0', '>=' ) ) {
499 - self::download_language_packs();
500 - }
501 - }
271 + protected function migrate_locale_fallback_to_language_description() {
272 + // Migrate locale fallbacks from term metas to language term description.
273 + $terms = get_terms(
274 + array(
275 + 'taxonomy' => 'language',
276 + 'hide_empty' => false,
277 + 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
278 + array(
279 + 'key' => 'fallback',
280 + 'compare_key' => 'EXISTS',
281 + ),
282 + ),
283 + )
284 + );
502 285
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 ) ) {
286 + if ( ! is_array( $terms ) ) {
522 287 return;
523 288 }
524 289
525 - require_once ABSPATH . 'wp-admin/includes/translation-install.php';
526 - $translations = wp_get_available_translations();
527 - if ( ! $translations ) {
528 - return;
529 - }
290 + foreach ( $terms as $term ) {
291 + $fallbacks = get_term_meta( $term->term_id, 'fallback', true );
530 292
531 - $translations_to_load = array();
293 + delete_term_meta( $term->term_id, 'fallback' );
532 294
533 - foreach ( $translations as $translation ) {
534 - if ( in_array( $translation['language'], $languages ) ) {
535 - $translation['type'] = 'core';
536 - $translations_to_load[] = (object) $translation;
295 + if ( empty( $fallbacks ) || ! is_array( $fallbacks ) ) {
296 + // Empty or invalid value, should not happen.
297 + continue;
537 298 }
538 - }
539 299
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 ) );
300 + $description = maybe_unserialize( $term->description );
301 + $description = is_array( $description ) ? $description : array();
302 +
303 + $description['fallbacks'] = $fallbacks;
304 + /** @var string */
305 + $description = maybe_serialize( $description );
306 +
307 + wp_update_term( $term->term_id, 'language', array( 'description' => $description ) );
544 308 }
545 309 }
546 310
547 311 /**
548 - * Upgrades if the previous version is < 1.7.4
312 + * Hides the language from content option if it is not the one selected.
549 313 *
550 - * @since 1.7.4
314 + * @since 3.7
315 + *
316 + * @return void
551 317 */
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
318 + private function allow_to_hide_language_from_content() {
319 + update_option(
320 + 'pll_language_from_content_available',
321 + 0 === $this->options['force_lang'] ? 'yes' : 'no'
322 + );
555 323 }
556 324
557 325 /**
558 - * Upgrades if the previous version is < 1.8
326 + * Cleans up strings translations so we don't store translations duplicated from the source.
559 327 *
560 - * @since 1.8
328 + * @since 3.7
329 + *
330 + * @return void
561 331 */
562 - protected function upgrade_1_8() {
563 - // Adds the flag code in languages stored in DB
564 - $languages = include POLYLANG_DIR . '/settings/languages.php';
332 + private function empty_duplicated_strings_translations() {
333 + $terms = get_terms(
334 + array(
335 + 'taxonomy' => 'language',
336 + 'hide_empty' => false,
337 + )
338 + );
565 339
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 - }
340 + if ( ! is_array( $terms ) ) {
341 + return;
575 342 }
576 343
577 - delete_transient( 'pll_languages_list' );
578 - }
344 + foreach ( $terms as $term ) {
345 + $strings = get_term_meta( $term->term_id, '_pll_strings_translations', true );
579 346
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 - }
347 + if ( empty( $strings ) || ! is_array( $strings ) ) {
348 + continue;
349 + }
590 350
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 );
351 + foreach ( $strings as $i => $tuple ) {
352 + if ( $tuple[0] !== $tuple[1] ) {
353 + continue;
354 + }
601 355
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 - }
356 + $strings[ $i ][1] = '';
608 357 }
609 - }
610 - }
611 358
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 );
359 + update_term_meta( $term->term_id, '_pll_strings_translations', $strings );
632 360 }
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 361 }
651 362 }