| @@ -17,9 +17,9 @@ | ||
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | 19 | * Preferred language to assign to a new post. |
| 20 | 20 | * |
| 21 | - * @var PLL_Language | |
| 21 | + * @var PLL_Language|null | |
| 22 | 22 | */ |
| 23 | 23 | protected $pref_lang; |
| 24 | 24 | |
| 25 | 25 | /** |
| @@ -24,28 +24,37 @@ | ||
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | 26 | * Current language. |
| 27 | 27 | * |
| 28 | - * @var PLL_Language | |
| 28 | + * @var PLL_Language|null | |
| 29 | 29 | */ |
| 30 | 30 | protected $curlang; |
| 31 | 31 | |
| 32 | 32 | /** |
| 33 | + * Reference to the Polylang options array. | |
| 34 | + * | |
| 35 | + * @var array | |
| 36 | + */ | |
| 37 | + protected $options; | |
| 38 | + | |
| 39 | + /** | |
| 33 | 40 | * Constructor |
| 34 | 41 | * |
| 35 | 42 | * @since 2.4 |
| 36 | 43 | * |
| 37 | - * @param object $polylang | |
| 44 | + * @param object $polylang The Polylang object. | |
| 38 | 45 | */ |
| 39 | 46 | public function __construct( &$polylang ) { |
| 40 | - $this->model = &$polylang->model; | |
| 47 | + $this->options = &$polylang->options; | |
| 48 | + $this->model = &$polylang->model; | |
| 41 | 49 | $this->pref_lang = &$polylang->pref_lang; |
| 42 | - $this->curlang = &$polylang->curlang; | |
| 50 | + $this->curlang = &$polylang->curlang; | |
| 43 | 51 | |
| 44 | 52 | add_action( 'save_post', array( $this, 'save_post' ), 10, 2 ); |
| 45 | 53 | add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 4 ); |
| 46 | - add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 4 ); | |
| 54 | + add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 2 ); | |
| 47 | 55 | add_action( 'before_delete_post', array( $this, 'delete_post' ) ); |
| 56 | + add_action( 'post_updated', array( $this, 'force_tags_translation' ), 10, 3 ); | |
| 48 | 57 | |
| 49 | 58 | // Specific for media |
| 50 | 59 | if ( $polylang->options['media_support'] ) { |
| 51 | 60 | add_action( 'add_attachment', array( $this, 'set_default_language' ) ); |
| @@ -54,13 +63,13 @@ | ||
| 54 | 63 | } |
| 55 | 64 | } |
| 56 | 65 | |
| 57 | 66 | /** |
| 58 | - * Allows to set a language by default for posts if it has no language yet | |
| 67 | + * Allows to set a language by default for posts if it has no language yet. | |
| 59 | 68 | * |
| 60 | 69 | * @since 1.5 |
| 61 | 70 | * |
| 62 | - * @param int $post_id | |
| 71 | + * @param int $post_id Post ID. | |
| 63 | 72 | * @return void |
| 64 | 73 | */ |
| 65 | 74 | public function set_default_language( $post_id ) { |
| 66 | 75 | if ( ! $this->model->post->get_language( $post_id ) ) { |
| @@ -72,13 +81,16 @@ | ||
| 72 | 81 | $this->model->post->set_language( $post_id, $lang ); |
| 73 | 82 | } elseif ( ( $parent_id = wp_get_post_parent_id( $post_id ) ) && $parent_lang = $this->model->post->get_language( $parent_id ) ) { |
| 74 | 83 | $this->model->post->set_language( $post_id, $parent_lang ); |
| 75 | 84 | } elseif ( isset( $this->pref_lang ) ) { |
| 76 | - // Always defined on admin, never defined on frontend | |
| 85 | + // Always defined on admin, never defined on frontend. | |
| 77 | 86 | $this->model->post->set_language( $post_id, $this->pref_lang ); |
| 87 | + } elseif ( ! empty( $this->curlang ) ) { | |
| 88 | + // Only on frontend due to the previous test always true on admin. | |
| 89 | + $this->model->post->set_language( $post_id, $this->curlang ); | |
| 78 | 90 | } else { |
| 79 | - // Only on frontend due to the previous test always true on admin | |
| 80 | - $this->model->post->set_language( $post_id, $this->curlang ); | |
| 91 | + // In all other cases set to default language. | |
| 92 | + $this->model->post->set_language( $post_id, $this->options['default_lang'] ); | |
| 81 | 93 | } |
| 82 | 94 | } |
| 83 | 95 | } |
| 84 | 96 | |
| @@ -118,108 +130,111 @@ | ||
| 118 | 130 | } |
| 119 | 131 | } |
| 120 | 132 | |
| 121 | 133 | /** |
| 122 | - * Makes sure that saved terms are in the right language (especially tags with same name in different languages). | |
| 134 | + * Makes sure that saved terms are in the right language. | |
| 123 | 135 | * |
| 124 | 136 | * @since 2.3 |
| 125 | 137 | * |
| 126 | - * @param int $object_id Object ID. | |
| 127 | - * @param WP_Term[] $terms An array of object terms. | |
| 128 | - * @param int[] $tt_ids An array of term taxonomy IDs. | |
| 129 | - * @param string $taxonomy Taxonomy slug. | |
| 138 | + * @param int $object_id Object ID. | |
| 139 | + * @param int[]|string[] $terms An array of object term IDs or slugs. | |
| 140 | + * @param int[] $tt_ids An array of term taxonomy IDs. | |
| 141 | + * @param string $taxonomy Taxonomy slug. | |
| 130 | 142 | * @return void |
| 131 | 143 | */ |
| 132 | 144 | public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy ) { |
| 133 | 145 | static $avoid_recursion; |
| 134 | 146 | |
| 135 | - if ( ! $avoid_recursion && $this->model->is_translated_taxonomy( $taxonomy ) && ! empty( $terms ) ) { | |
| 136 | - $lang = $this->model->post->get_language( $object_id ); | |
| 147 | + if ( $avoid_recursion || empty( $terms ) || ! is_array( $terms ) || empty( $tt_ids ) | |
| 148 | + || ! $this->model->is_translated_taxonomy( $taxonomy ) ) { | |
| 149 | + return; | |
| 150 | + } | |
| 137 | 151 | |
| 138 | - if ( ! empty( $lang ) && is_array( $terms ) ) { | |
| 139 | - // Convert to term ids if we got tag names | |
| 140 | - $strings = array_filter( $terms, 'is_string' ); | |
| 141 | - if ( ! empty( $strings ) ) { | |
| 142 | - $_terms = get_terms( $taxonomy, array( 'name' => $strings, 'object_ids' => $object_id, 'fields' => 'ids' ) ); | |
| 143 | - $terms = array_merge( array_diff( $terms, $strings ), $_terms ); | |
| 144 | - } | |
| 152 | + $lang = $this->model->post->get_language( $object_id ); | |
| 145 | 153 | |
| 146 | - $term_ids = array_combine( $terms, $terms ); | |
| 147 | - $languages = array_map( array( $this->model->term, 'get_language' ), $term_ids ); | |
| 148 | - $languages = array_filter( $languages ); // Remove terms without language. | |
| 149 | - $languages = wp_list_pluck( $languages, 'slug' ); | |
| 150 | - $wrong_terms = array_diff( $languages, array( $lang->slug ) ); | |
| 154 | + if ( empty( $lang ) ) { | |
| 155 | + return; | |
| 156 | + } | |
| 151 | 157 | |
| 152 | - if ( ! empty( $wrong_terms ) ) { | |
| 153 | - // We got terms in a wrong language | |
| 154 | - $wrong_term_ids = array_keys( $wrong_terms ); | |
| 155 | - $terms = get_the_terms( $object_id, $taxonomy ); | |
| 156 | - wp_remove_object_terms( $object_id, $wrong_term_ids, $taxonomy ); | |
| 158 | + // Use the term_taxonomy_ids to get all the requested terms in 1 query. | |
| 159 | + $new_terms = get_terms( | |
| 160 | + array( | |
| 161 | + 'taxonomy' => $taxonomy, | |
| 162 | + 'term_taxonomy_id' => array_map( 'intval', $tt_ids ), | |
| 163 | + 'lang' => '', | |
| 164 | + ) | |
| 165 | + ); | |
| 157 | 166 | |
| 158 | - if ( is_array( $terms ) ) { | |
| 159 | - $newterms = array(); | |
| 167 | + if ( empty( $new_terms ) || ! is_array( $new_terms ) ) { | |
| 168 | + // Terms not found. | |
| 169 | + return; | |
| 170 | + } | |
| 160 | 171 | |
| 161 | - foreach ( $terms as $term ) { | |
| 162 | - if ( in_array( $term->term_id, $wrong_term_ids ) ) { | |
| 163 | - // Check if the term is in the correct language or if a translation exist ( mainly for default category ) | |
| 164 | - if ( $newterm = $this->model->term->get( $term->term_id, $lang ) ) { | |
| 165 | - $newterms[] = (int) $newterm; | |
| 166 | - } | |
| 172 | + $new_term_ids_translated = $this->translate_terms( $new_terms, $taxonomy, $lang ); | |
| 167 | 173 | |
| 168 | - // Or choose the correct language for tags ( initially defined by name ) | |
| 169 | - elseif ( $newterm = $this->model->term_exists( $term->name, $taxonomy, $term->parent, $lang ) ) { | |
| 170 | - $newterms[] = (int) $newterm; // Cast is important otherwise we get 'numeric' tags | |
| 171 | - } | |
| 174 | + // Query the object's term. | |
| 175 | + $orig_terms = get_terms( | |
| 176 | + array( | |
| 177 | + 'taxonomy' => $taxonomy, | |
| 178 | + 'object_ids' => $object_id, | |
| 179 | + 'lang' => '', | |
| 180 | + ) | |
| 181 | + ); | |
| 172 | 182 | |
| 173 | - // Or create the term in the correct language | |
| 174 | - elseif ( ! is_wp_error( $term_info = wp_insert_term( $term->name, $taxonomy ) ) ) { | |
| 175 | - $newterms[] = (int) $term_info['term_id']; | |
| 176 | - } | |
| 177 | - } | |
| 178 | - } | |
| 183 | + if ( is_array( $orig_terms ) ) { | |
| 184 | + $orig_term_ids = wp_list_pluck( $orig_terms, 'term_id' ); | |
| 185 | + $orig_term_ids_translated = $this->translate_terms( $orig_terms, $taxonomy, $lang ); | |
| 179 | 186 | |
| 180 | - $avoid_recursion = true; | |
| 181 | - wp_set_object_terms( $object_id, array_unique( $newterms ), $taxonomy, true ); // Append | |
| 182 | - $avoid_recursion = false; | |
| 183 | - } | |
| 184 | - } | |
| 187 | + // Terms that are not in the translated list. | |
| 188 | + $remove_term_ids = array_diff( $orig_term_ids, $orig_term_ids_translated ); | |
| 189 | + | |
| 190 | + if ( ! empty( $remove_term_ids ) ) { | |
| 191 | + wp_remove_object_terms( $object_id, $remove_term_ids, $taxonomy ); | |
| 185 | 192 | } |
| 193 | + } else { | |
| 194 | + $orig_term_ids = array(); | |
| 195 | + $orig_term_ids_translated = array(); | |
| 186 | 196 | } |
| 197 | + | |
| 198 | + // Terms to add. | |
| 199 | + $add_term_ids = array_unique( array_merge( $orig_term_ids_translated, $new_term_ids_translated ) ); | |
| 200 | + $add_term_ids = array_diff( $add_term_ids, $orig_term_ids ); | |
| 201 | + | |
| 202 | + if ( ! empty( $add_term_ids ) ) { | |
| 203 | + $avoid_recursion = true; | |
| 204 | + wp_set_object_terms( $object_id, $add_term_ids, $taxonomy, true ); // Append. | |
| 205 | + $avoid_recursion = false; | |
| 206 | + } | |
| 187 | 207 | } |
| 188 | 208 | |
| 189 | 209 | /** |
| 190 | - * Make sure that the post parent is in the correct language when using bulk edit | |
| 210 | + * Make sure that the post parent is in the correct language. | |
| 191 | 211 | * |
| 192 | 212 | * @since 1.8 |
| 193 | 213 | * |
| 194 | - * @param int $post_parent Post parent ID. | |
| 195 | - * @param int $post_id Post ID. | |
| 196 | - * @param array $new_postarr Array of parsed post data. | |
| 197 | - * @param array $postarr Array of sanitized, but otherwise unmodified post data. | |
| 214 | + * @param int $post_parent Post parent ID. | |
| 215 | + * @param int $post_id Post ID. | |
| 198 | 216 | * @return int |
| 199 | 217 | */ |
| 200 | - public function wp_insert_post_parent( $post_parent, $post_id, $new_postarr, $postarr ) { | |
| 201 | - if ( isset( $postarr['bulk_edit'], $postarr['inline_lang_choice'] ) ) { | |
| 202 | - check_admin_referer( 'bulk-posts' ); | |
| 203 | - $lang = -1 == $postarr['inline_lang_choice'] ? | |
| 204 | - $this->model->post->get_language( $post_id ) : | |
| 205 | - $this->model->get_language( $postarr['inline_lang_choice'] ); | |
| 206 | - // Dont break the hierarchy in case the post has no language | |
| 207 | - if ( ! empty( $lang ) ) { | |
| 208 | - $post_parent = $this->model->post->get_translation( $post_parent, $lang ); | |
| 209 | - } | |
| 218 | + public function wp_insert_post_parent( $post_parent, $post_id ) { | |
| 219 | + $lang = $this->model->post->get_language( $post_id ); | |
| 220 | + $parent_post_type = $post_parent > 0 ? get_post_type( $post_parent ) : null; | |
| 221 | + // Dont break the hierarchy in case the post has no language | |
| 222 | + if ( ! empty( $lang ) && ! empty( $parent_post_type ) && $this->model->is_translated_post_type( $parent_post_type ) ) { | |
| 223 | + $post_parent = $this->model->post->get_translation( $post_parent, $lang ); | |
| 210 | 224 | } |
| 225 | + | |
| 211 | 226 | return $post_parent; |
| 212 | 227 | } |
| 213 | 228 | |
| 214 | 229 | /** |
| 215 | 230 | * Called when a post, page or media is deleted |
| 216 | - * Don't delete translations if this is a post revision thanks to AndyDeGroo who catched this bug | |
| 231 | + * Don't delete translations if this is a post revision thanks to AndyDeGroo who caught this bug | |
| 217 | 232 | * http://wordpress.org/support/topic/plugin-polylang-quick-edit-still-breaks-translation-linking-of-pages-in-072 |
| 218 | 233 | * |
| 219 | 234 | * @since 0.1 |
| 220 | 235 | * |
| 221 | - * @param int $post_id | |
| 236 | + * @param int $post_id Post ID. | |
| 222 | 237 | * @return void |
| 223 | 238 | */ |
| 224 | 239 | public function delete_post( $post_id ) { |
| 225 | 240 | if ( ! wp_is_post_revision( $post_id ) ) { |
| @@ -227,10 +242,9 @@ | ||
| 227 | 242 | } |
| 228 | 243 | } |
| 229 | 244 | |
| 230 | 245 | /** |
| 231 | - * Prevents WP deleting files when there are still media using them | |
| 232 | - * Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function | |
| 246 | + * Prevents WP deleting files when there are still media using them. | |
| 233 | 247 | * |
| 234 | 248 | * @since 0.9 |
| 235 | 249 | * |
| 236 | 250 | * @param string $file Path to the file to delete. |
| @@ -240,21 +254,22 @@ | ||
| 240 | 254 | global $wpdb; |
| 241 | 255 | |
| 242 | 256 | $uploadpath = wp_upload_dir(); |
| 243 | 257 | |
| 258 | + // Get the main attached file. | |
| 259 | + $attached_file = substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) ); | |
| 260 | + $attached_file = preg_replace( '#-\d+x\d+\.([a-z]+)$#', '.$1', $attached_file ); | |
| 261 | + | |
| 244 | 262 | $ids = $wpdb->get_col( |
| 245 | 263 | $wpdb->prepare( |
| 246 | 264 | "SELECT post_id FROM $wpdb->postmeta |
| 247 | 265 | WHERE meta_key = '_wp_attached_file' AND meta_value = %s", |
| 248 | - substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) ) | |
| 266 | + $attached_file | |
| 249 | 267 | ) |
| 250 | 268 | ); |
| 251 | 269 | |
| 252 | 270 | if ( ! empty( $ids ) ) { |
| 253 | - // Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ). | |
| 254 | - require_once ABSPATH . 'wp-admin/includes/image.php'; // In case the file is deleted outside admin. | |
| 255 | - wp_update_attachment_metadata( $ids[0], wp_slash( wp_generate_attachment_metadata( $ids[0], $file ) ) ); // Directly uses update_post_meta, so expects slashed. | |
| 256 | - return ''; // Prevent deleting the main file. | |
| 271 | + return ''; // Prevent deleting the file. | |
| 257 | 272 | } |
| 258 | 273 | |
| 259 | 274 | return $file; |
| 260 | 275 | } |
| @@ -287,9 +302,11 @@ | ||
| 287 | 302 | |
| 288 | 303 | // Create a new attachment ( translate attachment parent if exists ). |
| 289 | 304 | add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload. |
| 290 | 305 | unset( $post['ID'] ); // Will force the creation. |
| 291 | - $post['post_parent'] = ( $post['post_parent'] && $tr_parent = $this->model->post->get_translation( $post['post_parent'], $lang->slug ) ) ? $tr_parent : 0; | |
| 306 | + if ( ! empty( $post['post_parent'] ) ) { | |
| 307 | + $post['post_parent'] = (int) $this->model->post->get_translation( $post['post_parent'], $lang->slug ); | |
| 308 | + } | |
| 292 | 309 | $post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language. |
| 293 | 310 | $tr_id = wp_insert_attachment( wp_slash( $post ) ); |
| 294 | 311 | remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload. |
| 295 | 312 | |
| @@ -325,6 +342,144 @@ | ||
| 325 | 342 | * @param string $slug Language code of the new translation. |
| 326 | 343 | */ |
| 327 | 344 | do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug ); |
| 328 | 345 | return $tr_id; |
| 346 | + } | |
| 347 | + | |
| 348 | + /** | |
| 349 | + * Ensure that tags are in the correct language when a post is updated, due to `tags_input` parameter being removed in `wp_update_post()`. | |
| 350 | + * | |
| 351 | + * @since 3.4.5 | |
| 352 | + * | |
| 353 | + * @param int $post_id Post ID, unused. | |
| 354 | + * @param WP_Post $post_after Post object following the update. | |
| 355 | + * @param WP_Post $post_before Post object before the update. | |
| 356 | + * @return void | |
| 357 | + */ | |
| 358 | + public function force_tags_translation( $post_id, $post_after, $post_before ) { | |
| 359 | + if ( ! is_object_in_taxonomy( $post_before->post_type, 'post_tag' ) ) { | |
| 360 | + return; | |
| 361 | + } | |
| 362 | + | |
| 363 | + $terms = get_the_terms( $post_before, 'post_tag' ); | |
| 364 | + | |
| 365 | + if ( empty( $terms ) || ! is_array( $terms ) ) { | |
| 366 | + return; | |
| 367 | + } | |
| 368 | + | |
| 369 | + $term_ids = wp_list_pluck( $terms, 'term_id' ); | |
| 370 | + | |
| 371 | + // Let's ensure that `PLL_CRUD_Posts::set_object_terms()` will do its job. | |
| 372 | + wp_set_post_terms( $post_id, $term_ids, 'post_tag' ); | |
| 373 | + } | |
| 374 | + | |
| 375 | + /** | |
| 376 | + * Makes sure that all terms in the given list are in the given language. | |
| 377 | + * If not the case, the terms are translated or created (for a hierarchical taxonomy, terms are created recursively). | |
| 378 | + * | |
| 379 | + * @since 3.5 | |
| 380 | + * | |
| 381 | + * @param WP_Term[] $terms List of terms to translate. | |
| 382 | + * @param string $taxonomy The terms' taxonomy. | |
| 383 | + * @param PLL_Language $language The language to translate the terms into. | |
| 384 | + * @return int[] List of `term_id`s. | |
| 385 | + * | |
| 386 | + * @phpstan-return array<positive-int> | |
| 387 | + */ | |
| 388 | + private function translate_terms( array $terms, string $taxonomy, PLL_Language $language ): array { | |
| 389 | + $term_ids_translated = array(); | |
| 390 | + | |
| 391 | + foreach ( $terms as $term ) { | |
| 392 | + $term_ids_translated[] = $this->translate_term( $term, $taxonomy, $language ); | |
| 393 | + } | |
| 394 | + | |
| 395 | + return array_filter( $term_ids_translated ); | |
| 396 | + } | |
| 397 | + | |
| 398 | + /** | |
| 399 | + * Translates the given term into the given language. | |
| 400 | + * If the translation doesn't exist, it is created (for a hierarchical taxonomy, terms are created recursively). | |
| 401 | + * | |
| 402 | + * @since 3.5 | |
| 403 | + * | |
| 404 | + * @param WP_Term $term The term to translate. | |
| 405 | + * @param string $taxonomy The term's taxonomy. | |
| 406 | + * @param PLL_Language $language The language to translate the term into. | |
| 407 | + * @return int A `term_id` on success, `0` on failure. | |
| 408 | + * | |
| 409 | + * @phpstan-return int<0, max> | |
| 410 | + */ | |
| 411 | + private function translate_term( WP_Term $term, string $taxonomy, PLL_Language $language ): int { | |
| 412 | + // Check if the term is in the correct language or if a translation exists. | |
| 413 | + $tr_term_id = $this->model->term->get( $term->term_id, $language ); | |
| 414 | + | |
| 415 | + if ( ! empty( $tr_term_id ) ) { | |
| 416 | + // Already in the correct language. | |
| 417 | + return $tr_term_id; | |
| 418 | + } | |
| 419 | + | |
| 420 | + // Or choose the correct language for tags (initially defined by name). | |
| 421 | + $tr_term_id = $this->model->term_exists( $term->name, $taxonomy, $term->parent, $language ); | |
| 422 | + | |
| 423 | + if ( ! empty( $tr_term_id ) ) { | |
| 424 | + return $tr_term_id; | |
| 425 | + } | |
| 426 | + | |
| 427 | + // Or create the term in the correct language. | |
| 428 | + $tr_parent_term_id = 0; | |
| 429 | + | |
| 430 | + if ( $term->parent > 0 && is_taxonomy_hierarchical( $taxonomy ) ) { | |
| 431 | + $parent = get_term( $term->parent, $taxonomy ); | |
| 432 | + | |
| 433 | + if ( $parent instanceof WP_Term ) { | |
| 434 | + // Translate the parent recursively. | |
| 435 | + $tr_parent_term_id = $this->translate_term( $parent, $taxonomy, $language ); | |
| 436 | + } | |
| 437 | + } | |
| 438 | + | |
| 439 | + $lang_callback = function ( $lang, $tax, $slug ) use ( $language, $term, $taxonomy ) { | |
| 440 | + if ( ! $lang instanceof PLL_Language && $tax === $taxonomy && $slug === $term->slug ) { | |
| 441 | + return $language; | |
| 442 | + } | |
| 443 | + return $lang; | |
| 444 | + }; | |
| 445 | + $parent_callback = function ( $parent_id, $tax, $slug ) use ( $tr_parent_term_id, $term, $taxonomy ) { | |
| 446 | + if ( empty( $parent_id ) && $tax === $taxonomy && $slug === $term->slug ) { | |
| 447 | + return $tr_parent_term_id; | |
| 448 | + } | |
| 449 | + return $parent_id; | |
| 450 | + }; | |
| 451 | + add_filter( 'pll_inserted_term_language', $lang_callback, 10, 3 ); | |
| 452 | + add_filter( 'pll_inserted_term_parent', $parent_callback, 10, 3 ); | |
| 453 | + $new_term_info = wp_insert_term( | |
| 454 | + $term->name, | |
| 455 | + $taxonomy, | |
| 456 | + array( | |
| 457 | + 'parent' => $tr_parent_term_id, | |
| 458 | + 'slug' => $term->slug, // Useless but prevents the use of `sanitize_title()` and for consistency with `$lang_callback`. | |
| 459 | + ) | |
| 460 | + ); | |
| 461 | + remove_filter( 'pll_inserted_term_language', $lang_callback ); | |
| 462 | + remove_filter( 'pll_inserted_term_parent', $parent_callback ); | |
| 463 | + | |
| 464 | + if ( is_wp_error( $new_term_info ) ) { | |
| 465 | + // Term creation failed. | |
| 466 | + return 0; | |
| 467 | + } | |
| 468 | + | |
| 469 | + $tr_term_id = max( 0, (int) $new_term_info['term_id'] ); | |
| 470 | + | |
| 471 | + if ( empty( $tr_term_id ) ) { | |
| 472 | + return 0; | |
| 473 | + } | |
| 474 | + | |
| 475 | + $this->model->term->set_language( $tr_term_id, $language ); | |
| 476 | + | |
| 477 | + $trs = $this->model->term->get_translations( $term->term_id ); | |
| 478 | + | |
| 479 | + $trs[ $language->slug ] = $tr_term_id; | |
| 480 | + | |
| 481 | + $this->model->term->save_translations( $term->term_id, $trs ); | |
| 482 | + | |
| 483 | + return $tr_term_id; | |
| 329 | 484 | } |
| 330 | 485 | } |