PluginProbe
Polylang / 2.3.6
Polylang v2.3.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-filters-term.php

admin-filters-term.php in Polylang 2.3.6, at admin/admin-filters-term.php

760 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Manages filters and actions related to terms on admin side
5 *
6 * @since 1.2
7 */
8 class PLL_Admin_Filters_Term {
9 public $links, $model, $options, $curlang, $filter_lang, $pref_lang;
10 protected $pre_term_name; // Used to store the term name before creating a slug if needed
11 protected $post_id; // Used to store the current post_id when bulk editing posts
12 private $tax_query_lang;
13
14 /**
15 * Constructor: setups filters and actions
16 *
17 * @param object $polylang
18 */
19 public function __construct( &$polylang ) {
20 $this->links = &$polylang->links;
21 $this->model = &$polylang->model;
22 $this->options = &$polylang->options;
23 $this->curlang = &$polylang->curlang;
24 $this->filter_lang = &$polylang->filter_lang;
25 $this->pref_lang = &$polylang->pref_lang;
26
27 foreach ( $this->model->get_translated_taxonomies() as $tax ) {
28 // Adds the language field in the 'Categories' and 'Post Tags' panels
29 add_action( $tax . '_add_form_fields', array( $this, 'add_term_form' ) );
30
31 // Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels
32 add_action( $tax . '_edit_form_fields', array( $this, 'edit_term_form' ) );
33
34 // Adds action related to languages when deleting categories and post tags
35 add_action( 'delete_' . $tax, array( $this, 'delete_term' ) );
36 }
37
38 // Adds actions related to languages when creating or saving categories and post tags
39 add_filter( 'wp_dropdown_cats', array( $this, 'wp_dropdown_cats' ) );
40 add_action( 'create_term', array( $this, 'save_term' ), 999, 3 );
41 add_action( 'edit_term', array( $this, 'save_term' ), 999, 3 ); // late as it may conflict with other plugins, see http://wordpress.org/support/topic/polylang-and-wordpress-seo-by-yoast
42 add_action( 'pre_post_update', array( $this, 'pre_post_update' ) );
43 add_filter( 'pre_term_name', array( $this, 'pre_term_name' ) );
44 add_filter( 'pre_term_slug', array( $this, 'pre_term_slug' ), 10, 2 );
45
46 // Ajax response for edit term form
47 add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
48 add_action( 'wp_ajax_pll_terms_not_translated', array( $this, 'ajax_terms_not_translated' ) );
49
50 // Adds cache domain when querying terms
51 add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
52
53 // Filters categories and post tags by language
54 add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 3 );
55 add_action( 'pre_get_posts', array( $this, 'set_tax_query_lang' ), 999 );
56 add_action( 'posts_selection', array( $this, 'unset_tax_query_lang' ), 0 );
57
58 // Allows to get the default categories in all languages
59 add_filter( 'option_default_category', array( $this, 'option_default_category' ) );
60 add_action( 'update_option_default_category', array( $this, 'update_option_default_category' ), 10, 2 );
61
62 // Updates the translations term ids when splitting a shared term
63 add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); // WP 4.2
64 }
65
66 /**
67 * Adds the language field in the 'Categories' and 'Post Tags' panels
68 *
69 * @since 0.1
70 */
71 public function add_term_form() {
72 $taxonomy = $_GET['taxonomy'];
73 $post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
74
75 if ( ! taxonomy_exists( $taxonomy ) || ! post_type_exists( $post_type ) ) {
76 return;
77 }
78
79 $lang = isset( $_GET['new_lang'] ) ? $this->model->get_language( $_GET['new_lang'] ) : $this->pref_lang;
80 $dropdown = new PLL_Walker_Dropdown();
81
82 wp_nonce_field( 'pll_language', '_pll_nonce' );
83
84 printf( '
85 <div class="form-field">
86 <label for="term_lang_choice">%s</label>
87 <div id="select-add-term-language">%s</div>
88 <p>%s</p>
89 </div>',
90 esc_html__( 'Language', 'polylang' ),
91 $dropdown->walk( $this->model->get_languages_list(), array(
92 'name' => 'term_lang_choice',
93 'value' => 'term_id',
94 'selected' => $lang ? $lang->term_id : '',
95 'flag' => true,
96 ) ),
97 esc_html__( 'Sets the language', 'polylang' )
98 );
99
100 if ( ! empty( $_GET['from_tag'] ) ) {
101 printf( '<input type="hidden" name="from_tag" value="%d" />', (int) $_GET['from_tag'] );
102 }
103
104 // Adds translation fields
105 echo '<div id="term-translations" class="form-field">';
106 if ( $lang ) {
107 include PLL_ADMIN_INC . '/view-translations-term.php';
108 }
109 echo '</div>' . "\n";
110 }
111
112 /**
113 * Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels
114 *
115 * @since 0.1
116 *
117 * @param object $tag
118 */
119 public function edit_term_form( $tag ) {
120 $post_type = isset( $GLOBALS['post_type'] ) ? $GLOBALS['post_type'] : $_REQUEST['post_type'];
121
122 if ( ! post_type_exists( $post_type ) ) {
123 return;
124 }
125
126 $term_id = $tag->term_id;
127 $taxonomy = $tag->taxonomy;
128
129 $lang = $this->model->term->get_language( $term_id );
130 $lang = empty( $lang ) ? $this->pref_lang : $lang;
131
132 $dropdown = new PLL_Walker_Dropdown();
133
134 // Disable the language dropdown and the translations input fields for default categories to prevent removal
135 $disabled = in_array( get_option( 'default_category' ), $this->model->term->get_translations( $term_id ) );
136
137 printf( '
138 <tr class="form-field">
139 <th scope="row">
140 %s
141 <label for="term_lang_choice">%s</label>
142 </th>
143 <td id="select-edit-term-language">
144 %s<br />
145 <p class="description">%s</p>
146 </td>
147 </tr>',
148 wp_nonce_field( 'pll_language', '_pll_nonce', true, false ),
149 esc_html__( 'Language', 'polylang' ),
150 $dropdown->walk( $this->model->get_languages_list(), array(
151 'name' => 'term_lang_choice',
152 'value' => 'term_id',
153 'selected' => $lang ? $lang->term_id : '',
154 'disabled' => $disabled,
155 'flag' => true,
156 ) ),
157 esc_html__( 'Sets the language', 'polylang' )
158 );
159
160 echo '<tr id="term-translations" class="form-field">';
161 if ( $lang ) {
162 include PLL_ADMIN_INC . '/view-translations-term.php';
163 }
164 echo '</tr>' . "\n";
165 }
166
167 /**
168 * Translates term parent if exists when using "Add new" ( translation )
169 *
170 * @since 0.7
171 *
172 * @param string $output html markup for dropdown list of categories
173 * @return string modified html
174 */
175 public function wp_dropdown_cats( $output ) {
176 if ( isset( $_GET['taxonomy'], $_GET['from_tag'], $_GET['new_lang'] ) && taxonomy_exists( $_GET['taxonomy'] ) ) {
177 $term = get_term( (int) $_GET['from_tag'], $_GET['taxonomy'] );
178 if ( $term && $id = $term->parent ) {
179 $lang = $this->model->get_language( $_GET['new_lang'] );
180 if ( $parent = $this->model->term->get_translation( $id, $lang ) ) {
181 return str_replace( '"' . $parent . '"', '"' . $parent . '" selected="selected"', $output );
182 }
183 }
184 }
185 return $output;
186 }
187
188 /**
189 * stores the current post_id when bulk editing posts for use in save_language and pre_term_slug
190 *
191 * @since 1.7
192 *
193 * @param int $post_id
194 */
195 public function pre_post_update( $post_id ) {
196 if ( isset( $_GET['bulk_edit'] ) ) {
197 $this->post_id = $post_id;
198 }
199 }
200
201 /**
202 * Allows to set a language by default for terms if it has no language yet
203 *
204 * @since 1.5.4
205 *
206 * @param int $term_id
207 * @param string $taxonomy
208 */
209 protected function set_default_language( $term_id, $taxonomy ) {
210 if ( ! $this->model->term->get_language( $term_id ) ) {
211 // Sets language from term parent if exists thanks to Scott Kingsley Clark
212 if ( ( $term = get_term( $term_id, $taxonomy ) ) && ! empty( $term->parent ) && $parent_lang = $this->model->term->get_language( $term->parent ) ) {
213 $this->model->term->set_language( $term_id, $parent_lang );
214 }
215 else {
216 $this->model->term->set_language( $term_id, $this->pref_lang );
217 }
218 }
219 }
220
221 /**
222 * Saves language
223 *
224 * @since 1.5
225 *
226 * @param int $term_id
227 * @param string $taxonomy
228 */
229 protected function save_language( $term_id, $taxonomy ) {
230 global $wpdb;
231 // Security checks are necessary to accept language modifications
232 // as 'wp_update_term' can be called from outside WP admin
233
234 // Edit tags
235 if ( isset( $_POST['term_lang_choice'] ) ) {
236 if ( 'add-' . $taxonomy == $_POST['action'] ) {
237 check_ajax_referer( $_POST['action'], '_ajax_nonce-add-' . $taxonomy ); // category metabox
238 }
239 else {
240 check_admin_referer( 'pll_language', '_pll_nonce' ); // edit tags or tags metabox
241 }
242
243 $this->model->term->set_language( $term_id, $this->model->get_language( $_POST['term_lang_choice'] ) );
244 }
245
246 // *Post* bulk edit, in case a new term is created
247 elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) {
248 check_admin_referer( 'bulk-posts' );
249
250 // Bulk edit does not modify the language
251 // So we possibly create a tag in several languages
252 if ( -1 == $_GET['inline_lang_choice'] ) {
253 // The language of the current term is set a according to the language of the current post
254 $this->model->term->set_language( $term_id, $this->model->post->get_language( $this->post_id ) );
255 $term = get_term( $term_id, $taxonomy );
256
257 // Get all terms with the same name
258 // FIXME backward compatibility WP < 4.2
259 // No WP function to get all terms with the exact same name so let's use a custom query
260 // $terms = get_terms( $taxonomy, array( 'name' => $term->name, 'hide_empty' => false, 'fields' => 'ids' ) ); should be OK in 4.2
261 // I may need to rework the loop below
262 $terms = $wpdb->get_results( $wpdb->prepare( "
263 SELECT t.term_id FROM $wpdb->terms AS t
264 INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
265 WHERE tt.taxonomy = %s AND t.name = %s",
266 $taxonomy, $term->name
267 ) );
268
269 // If we have several terms with the same name, they are translations of each other
270 if ( count( $terms ) > 1 ) {
271 foreach ( $terms as $term ) {
272 $translations[ $this->model->term->get_language( $term->term_id )->slug ] = $term->term_id;
273 }
274
275 $this->model->term->save_translations( $term_id, $translations );
276 }
277 }
278
279 else {
280 $this->model->term->set_language( $term_id, $this->model->get_language( $_GET['inline_lang_choice'] ) );
281 }
282 }
283
284 // Quick edit
285 elseif ( isset( $_POST['inline_lang_choice'] ) ) {
286 check_ajax_referer(
287 isset( $_POST['action'] ) && 'inline-save' == $_POST['action'] ? 'inlineeditnonce' : 'taxinlineeditnonce', // Post quick edit or tag quick edit ?
288 '_inline_edit'
289 );
290
291 $old_lang = $this->model->term->get_language( $term_id ); // Stores the old language
292 $lang = $this->model->get_language( $_POST['inline_lang_choice'] ); // New language
293 $translations = $this->model->term->get_translations( $term_id );
294
295 // Checks if the new language already exists in the translation group
296 if ( $old_lang && $old_lang->slug != $lang->slug ) {
297 if ( array_key_exists( $lang->slug, $translations ) ) {
298 $this->model->term->delete_translation( $term_id );
299 }
300
301 elseif ( array_key_exists( $old_lang->slug, $translations ) ) {
302 unset( $translations[ $old_lang->slug ] );
303 $this->model->term->save_translations( $term_id, $translations );
304 }
305 }
306
307 $this->model->term->set_language( $term_id, $lang ); // Set new language
308 }
309
310 // Edit post
311 elseif ( isset( $_POST['post_lang_choice'] ) ) { // FIXME should be useless now
312 check_admin_referer( 'pll_language', '_pll_nonce' );
313 $this->model->term->set_language( $term_id, $this->model->get_language( $_POST['post_lang_choice'] ) );
314 }
315
316 else {
317 $this->set_default_language( $term_id, $taxonomy );
318 }
319 }
320
321 /**
322 * Save translations from our form
323 *
324 * @since 1.5
325 *
326 * @param int $term_id
327 * @return array
328 */
329 protected function save_translations( $term_id ) {
330 // Security check as 'wp_update_term' can be called from outside WP admin
331 check_admin_referer( 'pll_language', '_pll_nonce' );
332
333 // Save translations after checking the translated term is in the right language ( as well as cast id to int )
334 foreach ( $_POST['term_tr_lang'] as $lang => $tr_id ) {
335 $tr_lang = $this->model->term->get_language( (int) $tr_id );
336 $translations[ $lang ] = $tr_lang && $tr_lang->slug == $lang ? (int) $tr_id : 0;
337 }
338
339 $this->model->term->save_translations( $term_id, $translations );
340
341 return $translations;
342 }
343
344 /**
345 * Called when a category or post tag is created or edited
346 * Saves language and translations
347 *
348 * @since 0.1
349 *
350 * @param int $term_id
351 * @param int $tt_id term taxonomy id
352 * @param string $taxonomy
353 */
354 public function save_term( $term_id, $tt_id, $taxonomy ) {
355 // Does nothing except on taxonomies which are filterable
356 if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
357 return;
358 }
359
360 // Capability check
361 // As 'wp_update_term' can be called from outside WP admin
362 // 2nd test for creating tags when creating / editing a post
363 $tax = get_taxonomy( $taxonomy );
364 if ( current_user_can( $tax->cap->edit_terms ) || ( isset( $_POST['tax_input'][ $taxonomy ] ) && current_user_can( $tax->cap->assign_terms ) ) ) {
365 $this->save_language( $term_id, $taxonomy );
366
367 if ( isset( $_POST['term_tr_lang'] ) ) {
368 $translations = $this->save_translations( $term_id );
369 }
370
371 /**
372 * Fires after the term language and translations are saved
373 *
374 * @since 1.2
375 *
376 * @param int $term_id term id
377 * @param string $taxonomy taxonomy name
378 * @param array $translations the list of translations term ids
379 */
380 do_action( 'pll_save_term', $term_id, $taxonomy, empty( $translations ) ? $this->model->term->get_translations( $term_id ) : $translations );
381 }
382
383 // Attempts to set a default language even if no capability
384 else {
385 $this->set_default_language( $term_id, $taxonomy );
386 }
387 }
388
389 /**
390 * Stores the term name for use in pre_term_slug
391 *
392 * @since 0.9.5
393 *
394 * @param string $name term name
395 * @return string unmodified term name
396 */
397 public function pre_term_name( $name ) {
398 return $this->pre_term_name = $name;
399 }
400
401 /**
402 * Creates the term slug in case the term already exists in another language
403 *
404 * @since 0.9.5
405 *
406 * @param string $slug
407 * @param string $taxonomy
408 * @return string
409 */
410 public function pre_term_slug( $slug, $taxonomy ) {
411 $name = sanitize_title( $this->pre_term_name );
412
413 // If the term already exists in another language
414 if ( ! $slug && $this->model->is_translated_taxonomy( $taxonomy ) && term_exists( $name, $taxonomy ) ) {
415 if ( isset( $_POST['term_lang_choice'] ) ) {
416 $slug = $name . '-' . $this->model->get_language( $_POST['term_lang_choice'] )->slug;
417 }
418
419 elseif ( isset( $_POST['inline_lang_choice'] ) ) {
420 $slug = $name . '-' . $this->model->get_language( $_POST['inline_lang_choice'] )->slug;
421 }
422
423 // *Post* bulk edit, in case a new term is created
424 elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) {
425 // Bulk edit does not modify the language
426 if ( -1 == $_GET['inline_lang_choice'] ) {
427 $slug = $name . '-' . $this->model->post->get_language( $this->post_id )->slug;
428 } else {
429 $slug = $name . '-' . $this->model->get_language( $_GET['inline_lang_choice'] )->slug;
430 }
431 }
432 }
433
434 return $slug;
435 }
436
437 /**
438 * Called when a category or post tag is deleted
439 * Deletes language and translations
440 *
441 * @since 0.1
442 *
443 * @param int $term_id
444 */
445 public function delete_term( $term_id ) {
446 $this->model->term->delete_translation( $term_id );
447 $this->model->term->delete_language( $term_id );
448 }
449
450 /**
451 * Ajax response for edit term form
452 *
453 * @since 0.2
454 */
455 public function term_lang_choice() {
456 check_ajax_referer( 'pll_language', '_pll_nonce' );
457
458 $lang = $this->model->get_language( $_POST['lang'] );
459 $term_id = isset( $_POST['term_id'] ) ? (int) $_POST['term_id'] : null;
460 $taxonomy = $_POST['taxonomy'];
461 $post_type = $_POST['post_type'];
462
463 if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
464 die( 0 );
465 }
466
467 ob_start();
468 if ( $lang ) {
469 include PLL_ADMIN_INC . '/view-translations-term.php';
470 }
471 $x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
472 ob_end_clean();
473
474 // Parent dropdown list ( only for hierarchical taxonomies )
475 // $args copied from edit_tags.php except echo
476 if ( is_taxonomy_hierarchical( $taxonomy ) ) {
477 $args = array(
478 'hide_empty' => 0,
479 'hide_if_empty' => false,
480 'taxonomy' => $taxonomy,
481 'name' => 'parent',
482 'orderby' => 'name',
483 'hierarchical' => true,
484 'show_option_none' => __( 'None' ),
485 'echo' => 0,
486 );
487 $x->Add( array( 'what' => 'parent', 'data' => wp_dropdown_categories( $args ) ) );
488 }
489
490 // Tag cloud
491 // Tests copied from edit_tags.php
492 else {
493 $tax = get_taxonomy( $taxonomy );
494 if ( ! is_null( $tax->labels->popular_items ) ) {
495 $args = array( 'taxonomy' => $taxonomy, 'echo' => false );
496 if ( current_user_can( $tax->cap->edit_terms ) ) {
497 $args = array_merge( $args, array( 'link' => 'edit' ) );
498 }
499
500 if ( $tag_cloud = wp_tag_cloud( $args ) ) {
501 $html = sprintf( '<div class="tagcloud"><h2>%1$s</h2>%2$s</div>', esc_html( $tax->labels->popular_items ), $tag_cloud );
502 $x->Add( array( 'what' => 'tag_cloud', 'data' => $html ) );
503 }
504 }
505 }
506
507 // Flag
508 $x->Add( array( 'what' => 'flag', 'data' => empty( $lang->flag ) ? esc_html( $lang->slug ) : $lang->flag ) );
509
510 $x->send();
511 }
512
513 /**
514 * Ajax response for input in translation autocomplete input box
515 *
516 * @since 1.5
517 */
518 public function ajax_terms_not_translated() {
519 check_ajax_referer( 'pll_language', '_pll_nonce' );
520
521 $s = wp_unslash( $_GET['term'] );
522 $post_type = $_GET['post_type'];
523 $taxonomy = $_GET['taxonomy'];
524
525 if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
526 die( 0 );
527 }
528
529 $term_language = $this->model->get_language( $_GET['term_language'] );
530 $translation_language = $this->model->get_language( $_GET['translation_language'] );
531
532 $return = array();
533
534 // It is more efficient to use one common query for all languages as soon as there are more than 2
535 foreach ( get_terms( $taxonomy, 'hide_empty=0&lang=0&name__like=' . $s ) as $term ) {
536 $lang = $this->model->term->get_language( $term->term_id );
537
538 if ( $lang && $lang->slug == $translation_language->slug && ! $this->model->term->get_translation( $term->term_id, $term_language ) ) {
539 $return[] = array(
540 'id' => $term->term_id,
541 'value' => $term->name,
542 'link' => $this->links->edit_term_translation_link( $term->term_id, $taxonomy, $post_type ),
543 );
544 }
545 }
546
547 // Add current translation in list
548 // Not in add term for as term_id is not set
549 if ( 'undefined' !== $_GET['term_id'] && $term_id = $this->model->term->get_translation( (int) $_GET['term_id'], $translation_language ) ) {
550 $term = get_term( $term_id, $taxonomy );
551 array_unshift( $return, array(
552 'id' => $term_id,
553 'value' => $term->name,
554 'link' => $this->links->edit_term_translation_link( $term->term_id, $taxonomy, $post_type ),
555 ) );
556 }
557
558 wp_die( json_encode( $return ) );
559 }
560
561 /**
562 * Get the language(s) to filter get_terms
563 *
564 * @since 1.7.6
565 *
566 * @param array $taxonomies queried taxonomies
567 * @param array $args get_terms arguments
568 * @return object|string|bool the language(s) to use in the filter, false otherwise
569 */
570 protected function get_queried_language( $taxonomies, $args ) {
571 // Does nothing except on taxonomies which are filterable
572 // Since WP 4.7, make sure not to filter wp_get_object_terms()
573 if ( ! $this->model->is_translated_taxonomy( $taxonomies ) || ! empty( $args['object_ids'] ) ) {
574 return false;
575 }
576
577 if ( isset( $this->tax_query_lang ) ) {
578 $args['lang'] = $this->tax_query_lang;
579 }
580
581 // If get_terms is queried with a 'lang' parameter
582 if ( isset( $args['lang'] ) ) {
583 return $args['lang'];
584 }
585
586 // On tags page, everything should be filtered according to the admin language filter except the parent dropdown
587 if ( 'edit-tags.php' === $GLOBALS['pagenow'] && empty( $args['class'] ) ) {
588 return $this->filter_lang;
589 }
590
591 return $this->curlang;
592 }
593
594 /**
595 * Adds language dependent cache domain when querying terms
596 * Useful as the 'lang' parameter is not included in cache key by WordPress
597 *
598 * @since 1.3
599 *
600 * @param array $args
601 * @param array $taxonomies
602 * @return array modified arguments
603 */
604 public function get_terms_args( $args, $taxonomies ) {
605 // don't break _get_term_hierarchy()
606 if ( 'all' === $args['get'] && 'id' === $args['orderby'] && 'id=>parent' === $args['fields'] ) {
607 $args['lang'] = '';
608 }
609
610 if ( $lang = $this->get_queried_language( $taxonomies, $args ) ) {
611 $lang = is_string( $lang ) && strpos( $lang, ',' ) ? explode( ',', $lang ) : $lang;
612 $key = '_' . ( is_array( $lang ) ? implode( ',', $lang ) : $this->model->get_language( $lang )->slug );
613 $args['cache_domain'] = empty( $args['cache_domain'] ) ? 'pll' . $key : $args['cache_domain'] . $key;
614 }
615 return $args;
616 }
617
618 /**
619 * Filters categories and post tags by language(s) when needed on admin side
620 *
621 * @since 0.5
622 *
623 * @param array $clauses list of sql clauses
624 * @param array $taxonomies list of taxonomies
625 * @param array $args get_terms arguments
626 * @return array modified sql clauses
627 */
628 public function terms_clauses( $clauses, $taxonomies, $args ) {
629 $lang = $this->get_queried_language( $taxonomies, $args );
630 return ! empty( $lang ) ? $this->model->terms_clauses( $clauses, $lang ) : $clauses; // adds our clauses to filter by current language
631 }
632
633 /**
634 * Sets the WP_Term_Query language when doing a WP_Query
635 * Needed since WP 4.9
636 *
637 * @since 2.3.2
638 *
639 * @param object $query WP_Query object
640 */
641 public function set_tax_query_lang( $query ) {
642 $this->tax_query_lang = isset( $query->query_vars['lang'] ) ? $query->query_vars['lang'] : '';
643 }
644
645 /**
646 * Removes the WP_Term_Query language filter for WP_Query
647 * Needed since WP 4.9
648 *
649 * @since 2.3.2
650 */
651 public function unset_tax_query_lang() {
652 unset( $this->tax_query_lang );
653 }
654
655 /**
656 * Hack to avoid displaying delete link for the default category in all languages
657 * Also returns the default category in the right language when called from wp_delete_term
658 *
659 * @since 1.2
660 *
661 * @param int $value
662 * @return int
663 */
664 public function option_default_category( $value ) {
665 // Filters the default category in note below the category list table and in settings->writing dropdown
666 if ( isset( $this->pref_lang ) && $tr = $this->model->term->get( $value, $this->pref_lang ) ) {
667 $value = $tr;
668 }
669
670 // FIXME backward compatibility with WP < 4.7
671 if ( version_compare( $GLOBALS['wp_version'], '4.7alpha', '<' ) ) {
672 $traces = debug_backtrace();
673 $n = version_compare( PHP_VERSION, '7', '>=' ) ? 3 : 4; // PHP 7 does not include call_user_func_array
674
675 if ( isset( $traces[ $n ] ) ) {
676 // FIXME 'column_name' for backward compatibility with WP < 4.3
677 if ( in_array( $traces[ $n ]['function'], array( 'column_cb', 'column_name', 'handle_row_actions' ) ) && in_array( $traces[ $n ]['args'][0]->term_id, $this->model->term->get_translations( $value ) ) ) {
678 return $traces[ $n ]['args'][0]->term_id;
679 }
680
681 if ( 'wp_delete_term' == $traces[ $n ]['function'] ) {
682 return $this->model->term->get( $value, $this->model->term->get_language( $traces[ $n ]['args'][0] ) );
683 }
684 }
685 }
686
687 return $value;
688 }
689
690 /**
691 * Checks if the new default category is translated in all languages
692 * If not, create the translations
693 *
694 * @since 1.7
695 *
696 * @param int $old_value
697 * @param int $value
698 */
699 public function update_option_default_category( $old_value, $value ) {
700 $default_cat_lang = $this->model->term->get_language( $value );
701
702 // Assign a default language to default category
703 if ( ! $default_cat_lang ) {
704 $default_cat_lang = $this->model->get_language( $this->options['default_lang'] );
705 $this->model->term->set_language( (int) $value, $default_cat_lang );
706 }
707
708 foreach ( $this->model->get_languages_list() as $language ) {
709 if ( $language->slug != $default_cat_lang->slug && ! $this->model->term->get_translation( $value, $language ) ) {
710 $this->model->create_default_category( $language );
711 }
712 }
713 }
714
715 /**
716 * Updates the translations term ids when splitting a shared term
717 * Splits translations if these are shared terms too
718 *
719 * @since 1.7
720 *
721 * @param int $term_id Shared term_id
722 * @param int $new_term_id
723 * @param int $term_taxonomy_id
724 * @param string $taxonomy
725 */
726 public function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
727 if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
728 return;
729 }
730
731 // Avoid recursion
732 static $avoid_recursion = false;
733 if ( $avoid_recursion ) {
734 return;
735 }
736
737 $avoid_recursion = true;
738 $lang = $this->model->term->get_language( $term_id );
739
740 foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
741 if ( $lang->slug == $key ) {
742 $translations[ $key ] = $new_term_id;
743 }
744 else {
745 $tr_term = get_term( $tr_id, $taxonomy );
746 $translations[ $key ] = _split_shared_term( $tr_id, $tr_term->term_taxonomy_id );
747
748 // Hack translation ids sent by the form to avoid overwrite in PLL_Admin_Filters_Term::save_translations
749 if ( isset( $_POST['term_tr_lang'][ $key ] ) && $_POST['term_tr_lang'][ $key ] == $tr_id ) {
750 $_POST['term_tr_lang'][ $key ] = $translations[ $key ];
751 }
752 }
753 $this->model->term->set_language( $translations[ $key ], $key );
754 }
755
756 $this->model->term->save_translations( $new_term_id, $translations );
757 $avoid_recursion = false;
758 }
759 }
760