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