PluginProbe
Polylang / 2.0.3
Polylang v2.0.3
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.0.3, at admin/admin-filters-term.php

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