PluginProbe
Polylang / 3.0.6
Polylang v3.0.6
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 / admin / admin-model.php

admin-model.php in Polylang 3.0.6, at admin/admin-model.php

623 lines 21.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 * Extends the PLL_Model class with methods needed only in Polylang settings pages.
8 *
9 * @since 1.2
10 */
11 class PLL_Admin_Model extends PLL_Model {
12
13 /**
14 * Adds a new language
15 * and creates a default category for this language.
16 *
17 * @since 1.2
18 *
19 * @param array $args {
20 * @type string $name Language name ( used only for display ).
21 * @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
22 * @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
23 * @type int $rtl 1 if rtl language, 0 otherwise.
24 * @type int $term_group Language order when displayed.
25 * @type string $no_default_cat Optional, if set, no default category will be created for this language.
26 * @type string $flag Optional, country code, @see flags.php.
27 * }
28 * @return WP_Error|true true if success / WP_Error if failed.
29 */
30 public function add_language( $args ) {
31 $errors = $this->validate_lang( $args );
32 if ( $errors->get_error_code() ) { // Using has_errors() would be more meaningful but is available only since WP 5.0
33 return $errors;
34 }
35
36 // First the language taxonomy
37 $description = maybe_serialize( array( 'locale' => $args['locale'], 'rtl' => (int) $args['rtl'], 'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'] ) );
38 $r = wp_insert_term( $args['name'], 'language', array( 'slug' => $args['slug'], 'description' => $description ) );
39 if ( is_wp_error( $r ) ) {
40 // Avoid an ugly fatal error if something went wrong ( reported once in the forum )
41 return new WP_Error( 'pll_add_language', __( 'Impossible to add the language.', 'polylang' ) );
42 }
43 wp_update_term( (int) $r['term_id'], 'language', array( 'term_group' => (int) $args['term_group'] ) ); // can't set the term group directly in wp_insert_term
44
45 // The term_language taxonomy
46 // Don't want shared terms so use a different slug
47 wp_insert_term( $args['name'], 'term_language', array( 'slug' => 'pll_' . $args['slug'] ) );
48
49 $this->clean_languages_cache(); // Update the languages list now !
50
51 if ( ! isset( $this->options['default_lang'] ) ) {
52 // If this is the first language created, set it as default language
53 $this->options['default_lang'] = $args['slug'];
54 update_option( 'polylang', $this->options );
55
56 // And assign default language to default category
57 $this->term->set_language( (int) get_option( 'default_category' ), (int) $r['term_id'] );
58 } elseif ( empty( $args['no_default_cat'] ) ) {
59 $this->create_default_category( $args['slug'] );
60 }
61
62 // Init a mo_id for this language
63 $mo = new PLL_MO();
64 $mo->export_to_db( $this->get_language( $args['slug'] ) );
65
66 /**
67 * Fires when a language is added.
68 *
69 * @since 1.9
70 *
71 * @param array $args Arguments used to create the language. @see PLL_Admin_Model::add_language().
72 */
73 do_action( 'pll_add_language', $args );
74
75 $this->clean_languages_cache(); // Again to set add mo_id in the cached languages list
76 flush_rewrite_rules(); // Refresh rewrite rules
77 return true;
78 }
79
80 /**
81 * Delete a language.
82 *
83 * @since 1.2
84 *
85 * @param int $lang_id Language term_id.
86 * @return bool
87 */
88 public function delete_language( $lang_id ) {
89 $lang = $this->get_language( (int) $lang_id );
90
91 if ( empty( $lang ) ) {
92 return false;
93 }
94
95 // Oops ! we are deleting the default language...
96 // Need to do this before loosing the information for default category translations
97 if ( $this->options['default_lang'] == $lang->slug ) {
98 $slugs = $this->get_languages_list( array( 'fields' => 'slug' ) );
99 $slugs = array_diff( $slugs, array( $lang->slug ) );
100
101 if ( ! empty( $slugs ) ) {
102 $this->update_default_lang( reset( $slugs ) ); // Arbitrary choice...
103 } else {
104 unset( $this->options['default_lang'] );
105 }
106 }
107
108 // Delete the translations
109 $this->update_translations( $lang->slug );
110
111 // Delete language option in widgets
112 foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
113 if ( ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
114 $obj = $widget['callback'][0];
115 $number = $widget['params'][0]['number'];
116 if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
117 $settings = $obj->get_settings();
118 if ( isset( $settings[ $number ]['pll_lang'] ) && $settings[ $number ]['pll_lang'] == $lang->slug ) {
119 unset( $settings[ $number ]['pll_lang'] );
120 $obj->save_settings( $settings );
121 }
122 }
123 }
124 }
125
126 // Delete menus locations
127 if ( ! empty( $this->options['nav_menus'] ) ) {
128 foreach ( $this->options['nav_menus'] as $theme => $locations ) {
129 foreach ( array_keys( $locations ) as $location ) {
130 unset( $this->options['nav_menus'][ $theme ][ $location ][ $lang->slug ] );
131 }
132 }
133 }
134
135 // Delete users options
136 foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
137 delete_user_meta( $user_id, 'pll_filter_content', $lang->slug );
138 delete_user_meta( $user_id, 'description_' . $lang->slug );
139 }
140
141 // Delete the string translations
142 $post = wpcom_vip_get_page_by_title( 'polylang_mo_' . $lang->term_id, OBJECT, 'polylang_mo' );
143 if ( $post instanceof WP_Post ) {
144 wp_delete_post( $post->ID );
145 }
146
147 // Delete domain
148 unset( $this->options['domains'][ $lang->slug ] );
149
150 // Delete the language itself
151 wp_delete_term( $lang->term_id, 'language' );
152 wp_delete_term( $lang->tl_term_id, 'term_language' );
153
154 // Update languages list
155 $this->clean_languages_cache();
156
157 update_option( 'polylang', $this->options );
158 flush_rewrite_rules(); // refresh rewrite rules
159 return true;
160 }
161
162 /**
163 * Updates language properties.
164 *
165 * @since 1.2
166 *
167 * @param array $args {
168 * @type int $lang_id Id of the language to modify.
169 * @type string $name Language name ( used only for display ).
170 * @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
171 * @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
172 * @type int $rtl 1 if rtl language, 0 otherwise.
173 * @type int $term_group Language order when displayed.
174 * @type string $flag Optional, country code, @see flags.php.
175 * }
176 * @return WP_Error|true true if success / WP_Error if failed.
177 */
178 public function update_language( $args ) {
179 $lang = $this->get_language( (int) $args['lang_id'] );
180
181 $errors = $this->validate_lang( $args, $lang );
182 if ( $errors->get_error_code() ) { // Using has_errors() would be more meaningful but is available only since WP 5.0
183 return $errors;
184 }
185
186 // Update links to this language in posts and terms in case the slug has been modified
187 $slug = $args['slug'];
188 $old_slug = $lang->slug;
189
190 if ( $old_slug != $slug ) {
191 // Update the language slug in translations
192 $this->update_translations( $old_slug, $slug );
193
194 // Update language option in widgets
195 foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
196 if ( ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
197 $obj = $widget['callback'][0];
198 $number = $widget['params'][0]['number'];
199 if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
200 $settings = $obj->get_settings();
201 if ( isset( $settings[ $number ]['pll_lang'] ) && $settings[ $number ]['pll_lang'] == $old_slug ) {
202 $settings[ $number ]['pll_lang'] = $slug;
203 $obj->save_settings( $settings );
204 }
205 }
206 }
207 }
208
209 // Update menus locations
210 if ( ! empty( $this->options['nav_menus'] ) ) {
211 foreach ( $this->options['nav_menus'] as $theme => $locations ) {
212 foreach ( array_keys( $locations ) as $location ) {
213 if ( ! empty( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] ) ) {
214 $this->options['nav_menus'][ $theme ][ $location ][ $slug ] = $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ];
215 unset( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] );
216 }
217 }
218 }
219 }
220
221 // Update domains
222 if ( ! empty( $this->options['domains'][ $old_slug ] ) ) {
223 $this->options['domains'][ $slug ] = $this->options['domains'][ $old_slug ];
224 unset( $this->options['domains'][ $old_slug ] );
225 }
226
227 // Update the default language option if necessary
228 if ( $this->options['default_lang'] == $old_slug ) {
229 $this->options['default_lang'] = $slug;
230 }
231 }
232
233 update_option( 'polylang', $this->options );
234
235 // And finally update the language itself
236 $description = maybe_serialize( array( 'locale' => $args['locale'], 'rtl' => (int) $args['rtl'], 'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'] ) );
237 wp_update_term( (int) $lang->term_id, 'language', array( 'slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => (int) $args['term_group'] ) );
238 if ( empty( $lang->tl_term_id ) ) {
239 // Attempt to repair the term_language if it has been deleted by a database cleaning tool.
240 wp_insert_term( $args['name'], 'term_language', array( 'slug' => 'pll_' . $slug ) );
241 } else {
242 wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
243 }
244
245 /**
246 * Fires when a language is updated.
247 *
248 * @since 1.9
249 *
250 * @param array $args Arguments used to modify the language. @see PLL_Admin_Model::update_language().
251 */
252 do_action( 'pll_update_language', $args );
253
254 $this->clean_languages_cache();
255 flush_rewrite_rules(); // Refresh rewrite rules
256 return true;
257 }
258
259 /**
260 * Validates data entered when creating or updating a language.
261 *
262 * @see PLL_Admin_Model::add_language().
263 *
264 * @since 0.4
265 *
266 * @param array $args Parameters of {@see PLL_Admin_Model::add_language() or @see PLL_Admin_Model::update_language()}.
267 * @param PLL_Language $lang Optional the language currently updated, the language is created if not set.
268 * @return WP_Error
269 */
270 protected function validate_lang( $args, $lang = null ) {
271 $errors = new WP_Error();
272
273 // Validate locale with the same pattern as WP 4.3. See #28303
274 if ( ! preg_match( '#^[a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?$#', $args['locale'], $matches ) ) {
275 $errors->add( 'pll_invalid_locale', __( 'Enter a valid WordPress locale', 'polylang' ) );
276 }
277
278 // Validate slug characters
279 if ( ! preg_match( '#^[a-z_-]+$#', $args['slug'] ) ) {
280 $errors->add( 'pll_invalid_slug', __( 'The language code contains invalid characters', 'polylang' ) );
281 }
282
283 // Validate slug is unique
284 foreach ( $this->get_languages_list() as $language ) {
285 if ( $language->slug === $args['slug'] && ( null === $lang || $lang->term_id !== $language->term_id ) ) {
286 $errors->add( 'pll_non_unique_slug', __( 'The language code must be unique', 'polylang' ) );
287 }
288 }
289
290 // Validate name
291 // No need to sanitize it as wp_insert_term will do it for us
292 if ( empty( $args['name'] ) ) {
293 $errors->add( 'pll_invalid_name', __( 'The language must have a name', 'polylang' ) );
294 }
295
296 // Validate flag
297 if ( ! empty( $args['flag'] ) && ! file_exists( POLYLANG_DIR . '/flags/' . $args['flag'] . '.png' ) ) {
298 $flag = PLL_Language::get_flag_informations( $args['flag'] );
299
300 if ( ! empty( $flag['url'] ) ) {
301 $response = function_exists( 'vip_safe_wp_remote_get' ) ? vip_safe_wp_remote_get( esc_url_raw( $flag['url'] ) ) : wp_remote_get( esc_url_raw( $flag['url'] ) );
302 }
303
304 if ( empty( $response ) || is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
305 $errors->add( 'pll_invalid_flag', __( 'The flag does not exist', 'polylang' ) );
306 }
307 }
308
309 return $errors;
310 }
311
312 /**
313 * Assigns a language to posts or terms in mass.
314 *
315 * @since 1.2
316 *
317 * @param string $type Either 'post' or 'term'.
318 * @param int[] $ids Array of post ids or term ids.
319 * @param PLL_Language|string $lang Language to assign to the posts or terms.
320 * @return void
321 */
322 public function set_language_in_mass( $type, $ids, $lang ) {
323 global $wpdb;
324
325 $lang = $this->get_language( $lang );
326
327 if ( empty( $lang ) ) {
328 return;
329 }
330
331 $tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
332 $values = array();
333 $ids = array_map( 'intval', $ids );
334
335 foreach ( $ids as $id ) {
336 $values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
337 }
338
339 if ( ! empty( $values ) ) {
340 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
341 $wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', array_unique( $values ) ) );
342 $lang->update_count(); // Updating term count is mandatory ( thanks to AndyDeGroo )
343 }
344
345 if ( 'term' === $type ) {
346 clean_term_cache( $ids, 'term_language' );
347 $translations = array();
348
349 foreach ( $ids as $id ) {
350 $translations[] = array( $lang->slug => $id );
351 }
352
353 if ( ! empty( $translations ) ) {
354 $this->set_translation_in_mass( 'term', $translations );
355 }
356 } else {
357 clean_term_cache( $ids, 'language' );
358 }
359 }
360
361 /**
362 * Creates translations groups in mass.
363 *
364 * @since 1.6.3
365 *
366 * @param string $type Either 'post' or 'term'
367 * @param array $translations Array of translations arrays.
368 * @return void
369 */
370 public function set_translation_in_mass( $type, $translations ) {
371 global $wpdb;
372
373 $taxonomy = $type . '_translations';
374 $terms = array();
375 $slugs = array();
376 $description = array();
377 $count = array();
378
379 foreach ( $translations as $t ) {
380 $term = uniqid( 'pll_' ); // the term name
381 $terms[] = $wpdb->prepare( '( %s, %s )', $term, $term );
382 $slugs[] = $wpdb->prepare( '%s', $term );
383 $description[ $term ] = maybe_serialize( $t );
384 $count[ $term ] = count( $t );
385 }
386
387 // Insert terms
388 if ( ! empty( $terms ) ) {
389 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
390 $wpdb->query( "INSERT INTO {$wpdb->terms} ( slug, name ) VALUES " . implode( ',', array_unique( $terms ) ) );
391 }
392
393 // Get all terms with their term_id
394 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
395 $terms = $wpdb->get_results( "SELECT term_id, slug FROM {$wpdb->terms} WHERE slug IN ( " . implode( ',', $slugs ) . ' )' );
396 $term_ids = array();
397 $tts = array();
398
399 // Prepare terms taxonomy relationship
400 foreach ( $terms as $term ) {
401 $term_ids[] = $term->term_id;
402 $tts[] = $wpdb->prepare( '( %d, %s, %s, %d )', $term->term_id, $taxonomy, $description[ $term->slug ], $count[ $term->slug ] );
403 }
404
405 // Insert term_taxonomy
406 if ( ! empty( $tts ) ) {
407 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
408 $wpdb->query( "INSERT INTO {$wpdb->term_taxonomy} ( term_id, taxonomy, description, count ) VALUES " . implode( ',', array_unique( $tts ) ) );
409 }
410
411 // Get all terms with term_taxonomy_id
412 $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
413 $trs = array();
414
415 // Prepare objects relationships.
416 if ( is_array( $terms ) ) {
417 foreach ( $terms as $term ) {
418 $t = maybe_unserialize( $term->description );
419 if ( in_array( $t, $translations ) ) {
420 foreach ( $t as $object_id ) {
421 if ( ! empty( $object_id ) ) {
422 $trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
423 }
424 }
425 }
426 }
427 }
428
429 // Insert term_relationships
430 if ( ! empty( $trs ) ) {
431 // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
432 $wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $trs ) );
433 $trs = array_unique( $trs );
434 }
435
436 clean_term_cache( $term_ids, $taxonomy );
437 }
438
439 /**
440 * Returns untranslated posts and terms ids ( used in settings ).
441 *
442 * @since 0.9
443 * @since 2.2.6 Add the $limit argument.
444 *
445 * @param int $limit Max number of posts or terms to return. Defaults to -1 (no limit).
446 * @return array {
447 * Objects without language.
448 *
449 * @type int[] $posts Array of post ids.
450 * @type int[] $terms Array of term ids.
451 * }
452 */
453 public function get_objects_with_no_lang( $limit = -1 ) {
454 global $wpdb;
455
456 /**
457 * Filters the max number of posts or terms to return when searching objects with no language.
458 * This filter can be used to decrease the memory usage in case the number of objects
459 * without language is too big. Using a negative value is equivalent to have no limit.
460 *
461 * @since 2.2.6
462 *
463 * @param int $limit Max number of posts or terms to retrieve from the database.
464 */
465 $limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
466
467 $posts = get_posts(
468 array(
469 'numberposts' => $limit,
470 'nopaging' => $limit <= 0,
471 'post_type' => $this->get_translated_post_types(),
472 'post_status' => 'any',
473 'fields' => 'ids',
474 'tax_query' => array(
475 array(
476 'taxonomy' => 'language',
477 'terms' => $this->get_languages_list( array( 'fields' => 'term_id' ) ),
478 'operator' => 'NOT IN',
479 ),
480 ),
481 )
482 );
483
484 // PHPCS:disable WordPress.DB.PreparedSQL
485 $terms = $wpdb->get_col(
486 sprintf(
487 "SELECT {$wpdb->term_taxonomy}.term_id FROM {$wpdb->term_taxonomy}
488 WHERE taxonomy IN ('%s')
489 AND {$wpdb->term_taxonomy}.term_id NOT IN (
490 SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
491 )
492 %s",
493 implode( "','", array_map( 'esc_sql', $this->get_translated_taxonomies() ) ),
494 implode( ',', array_map( 'intval', $this->get_languages_list( array( 'fields' => 'tl_term_taxonomy_id' ) ) ) ),
495 $limit > 0 ? "LIMIT {$limit}" : ''
496 )
497 );
498 // PHPCS:enable
499
500 /**
501 * Filters the list of untranslated posts ids and terms ids
502 *
503 * @since 0.9
504 *
505 * @param array|false $objects false if no ids found, list of post and/or term ids otherwise.
506 */
507 return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
508 }
509
510 /**
511 * Updates the translations when a language slug has been modified in settings
512 * or deletes them when a language is removed.
513 *
514 * @since 0.5
515 *
516 * @param string $old_slug The old language slug.
517 * @param string $new_slug Optional, the new language slug, if not set it means that the language has been deleted.
518 * @return void
519 */
520 public function update_translations( $old_slug, $new_slug = '' ) {
521 global $wpdb;
522
523 $terms = get_terms( array( 'post_translations', 'term_translations' ) );
524 $term_ids = array();
525 $dr = array();
526 $dt = array();
527 $ut = array();
528
529 if ( is_array( $terms ) ) {
530 foreach ( $terms as $term ) {
531 $term_ids[ $term->taxonomy ][] = $term->term_id;
532 $tr = maybe_unserialize( $term->description );
533 if ( ! empty( $tr[ $old_slug ] ) ) {
534 if ( $new_slug ) {
535 $tr[ $new_slug ] = $tr[ $old_slug ]; // Suppress this for delete
536 } else {
537 $dr['id'][] = (int) $tr[ $old_slug ];
538 $dr['tt'][] = (int) $term->term_taxonomy_id;
539 }
540 unset( $tr[ $old_slug ] );
541
542 if ( empty( $tr ) || 1 == count( $tr ) ) {
543 $dt['t'][] = (int) $term->term_id;
544 $dt['tt'][] = (int) $term->term_taxonomy_id;
545 } else {
546 $ut['case'][] = $wpdb->prepare( 'WHEN %d THEN %s', $term->term_id, maybe_serialize( $tr ) );
547 $ut['in'][] = (int) $term->term_id;
548 }
549 }
550 }
551 }
552
553 // Delete relationships
554 if ( ! empty( $dr ) ) {
555 // PHPCS:disable WordPress.DB.PreparedSQL.NotPrepared
556 $wpdb->query(
557 "DELETE FROM $wpdb->term_relationships
558 WHERE object_id IN ( " . implode( ',', $dr['id'] ) . ' )
559 AND term_taxonomy_id IN ( ' . implode( ',', $dr['tt'] ) . ' )'
560 );
561 // PHPCS:enable
562 }
563
564 // Delete terms
565 if ( ! empty( $dt ) ) {
566 $wpdb->query( "DELETE FROM $wpdb->terms WHERE term_id IN ( " . implode( ',', $dt['t'] ) . ' )' ); // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
567 $wpdb->query( "DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ( " . implode( ',', $dt['tt'] ) . ' )' ); // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
568 }
569
570 // Update terms
571 if ( ! empty( $ut ) ) {
572 // PHPCS:disable WordPress.DB.PreparedSQL.NotPrepared
573 $wpdb->query(
574 "UPDATE $wpdb->term_taxonomy
575 SET description = ( CASE term_id " . implode( ' ', $ut['case'] ) . ' END )
576 WHERE term_id IN ( ' . implode( ',', $ut['in'] ) . ' )'
577 );
578 // PHPCS:enable
579 }
580
581 if ( ! empty( $term_ids ) ) {
582 foreach ( $term_ids as $taxonomy => $ids ) {
583 clean_term_cache( $ids, $taxonomy );
584 }
585 }
586 }
587
588 /**
589 * Updates the default language
590 * taking care to update the default category & the nav menu locations.
591 *
592 * @since 1.8
593 *
594 * @param string $slug New language slug.
595 * @return void
596 */
597 public function update_default_lang( $slug ) {
598 // The nav menus stored in theme locations should be in the default language
599 $theme = get_stylesheet();
600 if ( ! empty( $this->options['nav_menus'][ $theme ] ) ) {
601 $menus = array();
602
603 foreach ( $this->options['nav_menus'][ $theme ] as $key => $loc ) {
604 $menus[ $key ] = empty( $loc[ $slug ] ) ? 0 : $loc[ $slug ];
605 }
606 set_theme_mod( 'nav_menu_locations', $menus );
607 }
608
609 // The default category should be in the default language
610 $default_cats = $this->term->get_translations( get_option( 'default_category' ) );
611 if ( isset( $default_cats[ $slug ] ) ) {
612 update_option( 'default_category', $default_cats[ $slug ] );
613 }
614
615 // Update options
616 $this->options['default_lang'] = $slug;
617 update_option( 'polylang', $this->options );
618
619 $this->clean_languages_cache();
620 flush_rewrite_rules();
621 }
622 }
623