PluginProbe
Polylang / 3.1.4
Polylang v3.1.4
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 | admin/admin-model.php +106 -157 2.7.23.1.4 View file →
@@ -1,8 +1,11 @@
1 1 <?php
2 +/**
3 + * @package Polylang
4 + */
2 5
3 6 /**
4 - * Extends the PLL_Model class with methods needed only in Polylang settings pages
7 + * Extends the PLL_Model class with methods needed only in Polylang settings pages.
5 8 *
6 9 * @since 1.2
7 10 */
8 11 class PLL_Admin_Model extends PLL_Model {
@@ -8,25 +11,22 @@
8 11 class PLL_Admin_Model extends PLL_Model {
9 12
10 13 /**
11 14 * Adds a new language
12 - * Creates a default category for this language
15 + * and creates a default category for this language.
13 16 *
14 - * List of arguments that $args must contain:
15 - * name -> language name ( used only for display )
16 - * slug -> language code ( ideally 2-letters ISO 639-1 language code )
17 - * locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
18 - * rtl -> 1 if rtl language, 0 otherwise
19 - * term_group -> language order when displayed
20 - *
21 - * Optional arguments that $args can contain:
22 - * no_default_cat -> if set, no default category will be created for this language
23 - * flag -> country code, see flags.php
24 - *
25 17 * @since 1.2
26 18 *
27 - * @param array $args
28 - * @return bool true if success / false if failed
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 29 */
30 30 public function add_language( $args ) {
31 31 $errors = $this->validate_lang( $args );
32 32 if ( $errors->get_error_code() ) { // Using has_errors() would be more meaningful but is available only since WP 5.0
@@ -51,13 +51,8 @@
51 51 if ( ! isset( $this->options['default_lang'] ) ) {
52 52 // If this is the first language created, set it as default language
53 53 $this->options['default_lang'] = $args['slug'];
54 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 55 }
61 56
62 57 // Init a mo_id for this language
63 58 $mo = new PLL_MO();
@@ -63,13 +58,13 @@
63 58 $mo = new PLL_MO();
64 59 $mo->export_to_db( $this->get_language( $args['slug'] ) );
65 60
66 61 /**
67 - * Fires when a language is added
62 + * Fires when a language is added.
68 63 *
69 64 * @since 1.9
70 65 *
71 - * @param array $args arguments used to create the language
66 + * @param array $args Arguments used to create the language. @see PLL_Admin_Model::add_language().
72 67 */
73 68 do_action( 'pll_add_language', $args );
74 69
75 70 $this->clean_languages_cache(); // Again to set add mo_id in the cached languages list
@@ -77,13 +72,14 @@
77 72 return true;
78 73 }
79 74
80 75 /**
81 - * Delete a language
76 + * Delete a language.
82 77 *
83 78 * @since 1.2
84 79 *
85 - * @param int $lang_id language term_id
80 + * @param int $lang_id Language term_id.
81 + * @return bool
86 82 */
87 83 public function delete_language( $lang_id ) {
88 84 $lang = $this->get_language( (int) $lang_id );
89 85
@@ -138,9 +134,9 @@
138 134 }
139 135
140 136 // Delete the string translations
141 137 $post = wpcom_vip_get_page_by_title( 'polylang_mo_' . $lang->term_id, OBJECT, 'polylang_mo' );
142 - if ( ! empty( $post ) ) {
138 + if ( $post instanceof WP_Post ) {
143 139 wp_delete_post( $post->ID );
144 140 }
145 141
146 142 // Delete domain
@@ -158,25 +154,22 @@
158 154 return true;
159 155 }
160 156
161 157 /**
162 - * Update language properties
158 + * Updates language properties.
163 159 *
164 - * List of arguments that $args must contain:
165 - * lang_id -> term_id of the language to modify
166 - * name -> language name ( used only for display )
167 - * slug -> language code ( ideally 2-letters ISO 639-1 language code
168 - * locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
169 - * rtl -> 1 if rtl language, 0 otherwise
170 - * term_group -> language order when displayed
171 - *
172 - * Optional arguments that $args can contain:
173 - * flag -> country code, see flags.php
174 - *
175 160 * @since 1.2
176 161 *
177 - * @param array $args
178 - * @return bool true if success / false if failed
162 + * @param array $args {
163 + * @type int $lang_id Id of the language to modify.
164 + * @type string $name Language name ( used only for display ).
165 + * @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
166 + * @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
167 + * @type int $rtl 1 if rtl language, 0 otherwise.
168 + * @type int $term_group Language order when displayed.
169 + * @type string $flag Optional, country code, @see flags.php.
170 + * }
171 + * @return WP_Error|true true if success / WP_Error if failed.
179 172 */
180 173 public function update_language( $args ) {
181 174 $lang = $this->get_language( (int) $args['lang_id'] );
182 175
@@ -236,16 +229,21 @@
236 229
237 230 // And finally update the language itself
238 231 $description = maybe_serialize( array( 'locale' => $args['locale'], 'rtl' => (int) $args['rtl'], 'flag_code' => empty( $args['flag'] ) ? '' : $args['flag'] ) );
239 232 wp_update_term( (int) $lang->term_id, 'language', array( 'slug' => $slug, 'name' => $args['name'], 'description' => $description, 'term_group' => (int) $args['term_group'] ) );
240 - wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
233 + if ( empty( $lang->tl_term_id ) ) {
234 + // Attempt to repair the term_language if it has been deleted by a database cleaning tool.
235 + wp_insert_term( $args['name'], 'term_language', array( 'slug' => 'pll_' . $slug ) );
236 + } else {
237 + wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
238 + }
241 239
242 240 /**
243 - * Fires when a language is added
241 + * Fires when a language is updated.
244 242 *
245 243 * @since 1.9
246 244 *
247 - * @param array $args arguments used to modify the language
245 + * @param array $args Arguments used to modify the language. @see PLL_Admin_Model::update_language().
248 246 */
249 247 do_action( 'pll_update_language', $args );
250 248
251 249 $this->clean_languages_cache();
@@ -253,17 +251,17 @@
253 251 return true;
254 252 }
255 253
256 254 /**
257 - * Validates data entered when creating or updating a language
255 + * Validates data entered when creating or updating a language.
258 256 *
259 - * @see PLL_Admin_Model::add_language
257 + * @see PLL_Admin_Model::add_language().
260 258 *
261 259 * @since 0.4
262 260 *
263 - * @param array $args
264 - * @param object $lang optional the language currently updated, the language is created if not set
265 - * @return bool true if success / false if failed
261 + * @param array $args Parameters of {@see PLL_Admin_Model::add_language() or @see PLL_Admin_Model::update_language()}.
262 + * @param PLL_Language $lang Optional the language currently updated, the language is created if not set.
263 + * @return WP_Error
266 264 */
267 265 protected function validate_lang( $args, $lang = null ) {
268 266 $errors = new WP_Error();
269 267
@@ -278,9 +276,9 @@
278 276 }
279 277
280 278 // Validate slug is unique
281 279 foreach ( $this->get_languages_list() as $language ) {
282 - if ( $language->slug === $args['slug'] && ( null === $lang || ( isset( $lang ) && $lang->term_id != $language->term_id ) ) ) {
280 + if ( $language->slug === $args['slug'] && ( null === $lang || $lang->term_id !== $language->term_id ) ) {
283 281 $errors->add( 'pll_non_unique_slug', __( 'The language code must be unique', 'polylang' ) );
284 282 }
285 283 }
286 284
@@ -306,23 +304,29 @@
306 304 return $errors;
307 305 }
308 306
309 307 /**
310 - * Used to set the language of posts or terms in mass
308 + * Assigns a language to posts or terms in mass.
311 309 *
312 310 * @since 1.2
313 311 *
314 - * @param string $type either 'post' or 'term'
315 - * @param array $ids array of post ids or term ids
316 - * @param object|string $lang object or slug
312 + * @param string $type Either 'post' or 'term'.
313 + * @param int[] $ids Array of post ids or term ids.
314 + * @param PLL_Language|string $lang Language to assign to the posts or terms.
315 + * @return void
317 316 */
318 317 public function set_language_in_mass( $type, $ids, $lang ) {
319 318 global $wpdb;
320 319
321 - $ids = array_map( 'intval', $ids );
322 - $lang = $this->get_language( $lang );
320 + $lang = $this->get_language( $lang );
321 +
322 + if ( empty( $lang ) ) {
323 + return;
324 + }
325 +
323 326 $tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
324 327 $values = array();
328 + $ids = array_map( 'intval', $ids );
325 329
326 330 foreach ( $ids as $id ) {
327 331 $values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
328 332 }
@@ -349,14 +353,15 @@
349 353 }
350 354 }
351 355
352 356 /**
353 - * Used to create a translations groups in mass
357 + * Creates translations groups in mass.
354 358 *
355 359 * @since 1.6.3
356 360 *
357 - * @param string $type either 'post' or 'term'
358 - * @param array $translations array of translations arrays
361 + * @param string $type Either 'post' or 'term'
362 + * @param array $translations Array of translations arrays.
363 + * @return void
359 364 */
360 365 public function set_translation_in_mass( $type, $translations ) {
361 366 global $wpdb;
362 367
@@ -401,15 +406,17 @@
401 406 // Get all terms with term_taxonomy_id
402 407 $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
403 408 $trs = array();
404 409
405 - // Prepare objects relationships
406 - foreach ( $terms as $term ) {
407 - $t = maybe_unserialize( $term->description );
408 - if ( in_array( $t, $translations ) ) {
409 - foreach ( $t as $object_id ) {
410 - if ( ! empty( $object_id ) ) {
411 - $trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
410 + // Prepare objects relationships.
411 + if ( is_array( $terms ) ) {
412 + foreach ( $terms as $term ) {
413 + $t = maybe_unserialize( $term->description );
414 + if ( in_array( $t, $translations ) ) {
415 + foreach ( $t as $object_id ) {
416 + if ( ! empty( $object_id ) ) {
417 + $trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
418 + }
412 419 }
413 420 }
414 421 }
415 422 }
@@ -424,80 +431,16 @@
424 431 clean_term_cache( $term_ids, $taxonomy );
425 432 }
426 433
427 434 /**
428 - * Returns untranslated posts and terms ids ( used in settings )
435 + * Updates the translations when a language slug has been modified in settings
436 + * or deletes them when a language is removed.
429 437 *
430 - * @since 0.9
431 - * @since 2.2.6 Add the $limit argument
432 - *
433 - * @param in $limit Max number of posts or terms to return. Defaults to -1 (no limit).
434 - * @return array Array made of an array of post ids and an array of term ids
435 - */
436 - public function get_objects_with_no_lang( $limit = -1 ) {
437 - global $wpdb;
438 -
439 - /**
440 - * Filters the max number of posts or terms to return when searching objects with no language
441 - * This filter can be used to decrease the memory usage in case the number of objects
442 - * without language is too big. Using a negative value is equivalent to have no limit.
443 - *
444 - * @since 2.2.6
445 - *
446 - * @param int $limit Max number of posts or terms to retrieve from the database
447 - */
448 - $limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
449 -
450 - $posts = get_posts(
451 - array(
452 - 'numberposts' => $limit,
453 - 'nopaging' => $limit <= 0,
454 - 'post_type' => $this->get_translated_post_types(),
455 - 'post_status' => 'any',
456 - 'fields' => 'ids',
457 - 'tax_query' => array(
458 - array(
459 - 'taxonomy' => 'language',
460 - 'terms' => $this->get_languages_list( array( 'fields' => 'term_id' ) ),
461 - 'operator' => 'NOT IN',
462 - ),
463 - ),
464 - )
465 - );
466 -
467 - // PHPCS:disable WordPress.DB.PreparedSQL
468 - $terms = $wpdb->get_col(
469 - sprintf(
470 - "SELECT {$wpdb->term_taxonomy}.term_id FROM {$wpdb->term_taxonomy}
471 - WHERE taxonomy IN ('%s')
472 - AND {$wpdb->term_taxonomy}.term_id NOT IN (
473 - SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
474 - )
475 - %s",
476 - implode( "','", array_map( 'esc_sql', $this->get_translated_taxonomies() ) ),
477 - implode( ',', array_map( 'intval', $this->get_languages_list( array( 'fields' => 'tl_term_taxonomy_id' ) ) ) ),
478 - $limit > 0 ? "LIMIT {$limit}" : ''
479 - )
480 - );
481 - // PHPCS:enable
482 -
483 - /**
484 - * Filter the list of untranslated posts ids and terms ids
485 - *
486 - * @since 0.9
487 - *
488 - * @param bool|array $objects false if no ids found, list of post and/or term ids otherwise
489 - */
490 - return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
491 - }
492 -
493 - /**
494 - * Used to delete translations or update the translations when a language slug has been modified in settings
495 - *
496 438 * @since 0.5
497 439 *
498 - * @param string $old_slug the old language slug
499 - * @param string $new_slug optional, the new language slug, if not set it means the correspondent has been deleted
440 + * @param string $old_slug The old language slug.
441 + * @param string $new_slug Optional, the new language slug, if not set it means that the language has been deleted.
442 + * @return void
500 443 */
501 444 public function update_translations( $old_slug, $new_slug = '' ) {
502 445 global $wpdb;
503 446
@@ -506,26 +449,28 @@
506 449 $dr = array();
507 450 $dt = array();
508 451 $ut = array();
509 452
510 - foreach ( $terms as $term ) {
511 - $term_ids[ $term->taxonomy ][] = $term->term_id;
512 - $tr = maybe_unserialize( $term->description );
513 - if ( ! empty( $tr[ $old_slug ] ) ) {
514 - if ( $new_slug ) {
515 - $tr[ $new_slug ] = $tr[ $old_slug ]; // Suppress this for delete
516 - } else {
517 - $dr['id'][] = (int) $tr[ $old_slug ];
518 - $dr['tt'][] = (int) $term->term_taxonomy_id;
519 - }
520 - unset( $tr[ $old_slug ] );
453 + if ( is_array( $terms ) ) {
454 + foreach ( $terms as $term ) {
455 + $term_ids[ $term->taxonomy ][] = $term->term_id;
456 + $tr = maybe_unserialize( $term->description );
457 + if ( ! empty( $tr[ $old_slug ] ) ) {
458 + if ( $new_slug ) {
459 + $tr[ $new_slug ] = $tr[ $old_slug ]; // Suppress this for delete
460 + } else {
461 + $dr['id'][] = (int) $tr[ $old_slug ];
462 + $dr['tt'][] = (int) $term->term_taxonomy_id;
463 + }
464 + unset( $tr[ $old_slug ] );
521 465
522 - if ( empty( $tr ) || 1 == count( $tr ) ) {
523 - $dt['t'][] = (int) $term->term_id;
524 - $dt['tt'][] = (int) $term->term_taxonomy_id;
525 - } else {
526 - $ut['case'][] = $wpdb->prepare( 'WHEN %d THEN %s', $term->term_id, maybe_serialize( $tr ) );
527 - $ut['in'][] = (int) $term->term_id;
466 + if ( empty( $tr ) || 1 == count( $tr ) ) {
467 + $dt['t'][] = (int) $term->term_id;
468 + $dt['tt'][] = (int) $term->term_taxonomy_id;
469 + } else {
470 + $ut['case'][] = $wpdb->prepare( 'WHEN %d THEN %s', $term->term_id, maybe_serialize( $tr ) );
471 + $ut['in'][] = (int) $term->term_id;
472 + }
528 473 }
529 474 }
530 475 }
531 476
@@ -565,13 +510,14 @@
565 510 }
566 511
567 512 /**
568 513 * Updates the default language
569 - * taking care to update the default category & the nav menu locations
514 + * taking care to update the default category & the nav menu locations.
570 515 *
571 516 * @since 1.8
572 517 *
573 - * @param string $slug new language slug
518 + * @param string $slug New language slug.
519 + * @return void
574 520 */
575 521 public function update_default_lang( $slug ) {
576 522 // The nav menus stored in theme locations should be in the default language
577 523 $theme = get_stylesheet();
@@ -583,13 +529,16 @@
583 529 }
584 530 set_theme_mod( 'nav_menu_locations', $menus );
585 531 }
586 532
587 - // The default category should be in the default language
588 - $default_cats = $this->term->get_translations( get_option( 'default_category' ) );
589 - if ( isset( $default_cats[ $slug ] ) ) {
590 - update_option( 'default_category', $default_cats[ $slug ] );
591 - }
533 + /**
534 + * Fires when a default language is updated.
535 + *
536 + * @since 3.1
537 + *
538 + * @param string $slug Slug.
539 + */
540 + do_action( 'pll_update_default_lang', $slug );
592 541
593 542 // Update options
594 543 $this->options['default_lang'] = $slug;
595 544 update_option( 'polylang', $this->options );