PluginProbe
Polylang / 1.8.2
Polylang v1.8.2
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 1.8.2, at admin/admin-filters-term.php

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