| @@ -3,10 +3,10 @@ | ||
| 3 | 3 | * @package Polylang |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | /** |
| 7 | - * A class to handle the WPML API based on hooks, introduced since WPML 3.2 | |
| 8 | - * It partly relies on the legacy API | |
| 7 | + * A class to handle the WPML API based on hooks, introduced since WPML 3.2. | |
| 8 | + * It partly relies on the legacy API. | |
| 9 | 9 | * |
| 10 | 10 | * @see https://wpml.org/documentation/support/wpml-coding-api/wpml-hooks-reference/ |
| 11 | 11 | * |
| 12 | 12 | * @since 2.0 |
| @@ -14,117 +14,130 @@ | ||
| 14 | 14 | class PLL_WPML_API { |
| 15 | 15 | /** |
| 16 | 16 | * Stores the original language when the language is switched. |
| 17 | 17 | * |
| 18 | - * @var PLL_Language | |
| 18 | + * @var PLL_Language|null | |
| 19 | 19 | */ |
| 20 | 20 | private static $original_language = null; |
| 21 | 21 | |
| 22 | 22 | /** |
| 23 | - * Constructor | |
| 23 | + * Constructor. | |
| 24 | 24 | * |
| 25 | 25 | * @since 2.0 |
| 26 | 26 | */ |
| 27 | 27 | public function __construct() { |
| 28 | - // Site Wide Language informations | |
| 29 | - | |
| 28 | + /* | |
| 29 | + * Site Wide Language information. | |
| 30 | + */ | |
| 30 | 31 | add_filter( 'wpml_active_languages', array( $this, 'wpml_active_languages' ), 10, 2 ); |
| 31 | - add_filter( 'wpml_display_language_names', array( $this, 'wpml_display_language_names' ), 10, 5 ); | |
| 32 | - // wpml_translated_language_name => not applicable | |
| 32 | + add_filter( 'wpml_display_language_names', array( $this, 'wpml_display_language_names' ), 10, 2 ); // Because we don't translate language names, 3rd to 5th parameters are not supported. | |
| 33 | + // wpml_translated_language_name => not applicable. | |
| 33 | 34 | add_filter( 'wpml_current_language', 'pll_current_language', 10, 0 ); |
| 34 | 35 | add_filter( 'wpml_default_language', 'pll_default_language', 10, 0 ); |
| 35 | - // wpml_add_language_selector => not implemented | |
| 36 | - // wpml_footer_language_selector => not applicable | |
| 36 | + // wpml_add_language_selector => not implemented. | |
| 37 | + // wpml_footer_language_selector => not applicable. | |
| 37 | 38 | add_action( 'wpml_add_language_form_field', array( $this, 'wpml_add_language_form_field' ) ); |
| 38 | 39 | add_filter( 'wpml_language_is_active', array( $this, 'wpml_language_is_active' ), 10, 2 ); |
| 39 | 40 | add_filter( 'wpml_is_rtl', array( $this, 'wpml_is_rtl' ) ); |
| 40 | 41 | // wpml_language_form_input_field => See wpml_add_language_form_field |
| 41 | 42 | // wpml_language_has_switched => See wpml_switch_language |
| 42 | - // wpml_element_trid => not implemented | |
| 43 | - // wpml_get_element_translations => not implemented | |
| 44 | - // wpml_language_switcher => not implemented | |
| 45 | - // wpml_browser_redirect_language_params => not implemented | |
| 46 | - // wpml_enqueue_browser_redirect_language => not applicable | |
| 47 | - // wpml_enqueued_browser_redirect_language => not applicable | |
| 48 | - // wpml_encode_string => not applicable | |
| 49 | - // wpml_decode_string => not applicable | |
| 43 | + add_filter( 'wpml_element_trid', array( $this, 'wpml_element_trid' ), 10, 3 ); | |
| 44 | + add_filter( 'wpml_get_element_translations', array( $this, 'wpml_get_element_translations' ), 10, 3 ); | |
| 45 | + // wpml_language_switcher => not implemented. | |
| 46 | + // wpml_browser_redirect_language_params => not implemented. | |
| 47 | + // wpml_enqueue_browser_redirect_language => not applicable. | |
| 48 | + // wpml_enqueued_browser_redirect_language => not applicable. | |
| 49 | + // wpml_encode_string => not applicable. | |
| 50 | + // wpml_decode_string => not applicable. | |
| 50 | 51 | |
| 51 | - // Retrieving Language Information for Content | |
| 52 | - | |
| 52 | + /* | |
| 53 | + * Retrieving Language Information for Content. | |
| 54 | + */ | |
| 53 | 55 | add_filter( 'wpml_post_language_details', 'wpml_get_language_information', 10, 2 ); |
| 54 | - add_action( 'wpml_switch_language', array( __CLASS__, 'wpml_switch_language' ), 10, 2 ); | |
| 55 | - add_filter( 'wpml_element_language_code', array( $this, 'wpml_element_language_code' ), 10, 3 ); | |
| 56 | - // wpml_element_language_details => not applicable | |
| 56 | + add_action( 'wpml_switch_language', array( self::class, 'wpml_switch_language' ), 10, 2 ); | |
| 57 | + add_filter( 'wpml_element_language_code', array( $this, 'wpml_element_language_code' ), 10, 2 ); | |
| 58 | + // wpml_element_language_details => not applicable. | |
| 57 | 59 | |
| 58 | - // Retrieving Localized Content | |
| 59 | - | |
| 60 | + /* | |
| 61 | + * Retrieving Localized Content. | |
| 62 | + */ | |
| 60 | 63 | add_filter( 'wpml_home_url', 'pll_home_url', 10, 0 ); |
| 61 | 64 | add_filter( 'wpml_element_link', 'icl_link_to_element', 10, 7 ); |
| 62 | 65 | add_filter( 'wpml_object_id', 'icl_object_id', 10, 4 ); |
| 63 | 66 | add_filter( 'wpml_translate_single_string', array( $this, 'wpml_translate_single_string' ), 10, 4 ); |
| 64 | - // wpml_translate_string => not applicable | |
| 65 | - // wpml_unfiltered_admin_string => not implemented | |
| 67 | + // wpml_translate_string => not applicable. | |
| 68 | + // wpml_unfiltered_admin_string => not implemented. | |
| 66 | 69 | add_filter( 'wpml_permalink', array( $this, 'wpml_permalink' ), 10, 2 ); |
| 67 | - // wpml_elements_without_translations => not implemented | |
| 70 | + // wpml_elements_without_translations => not implemented. | |
| 68 | 71 | add_filter( 'wpml_get_translated_slug', array( $this, 'wpml_get_translated_slug' ), 10, 3 ); |
| 69 | 72 | |
| 70 | - // Finding the Translation State of Content | |
| 71 | - | |
| 72 | - // wpml_element_translation_type => not implemented | |
| 73 | + /* | |
| 74 | + * Finding the Translation State of Content. | |
| 75 | + */ | |
| 76 | + // wpml_element_translation_type => not implemented. | |
| 73 | 77 | add_filter( 'wpml_element_has_translations', array( $this, 'wpml_element_has_translations' ), 10, 3 ); |
| 74 | - // wpml_master_post_from_duplicate => not applicable | |
| 75 | - // wpml_post_duplicates => not applicable | |
| 78 | + // wpml_master_post_from_duplicate => not applicable. | |
| 79 | + // wpml_post_duplicates => not applicable. | |
| 76 | 80 | |
| 77 | - // Inserting Content | |
| 78 | - | |
| 79 | - // wpml_admin_make_post_duplicates => not applicable | |
| 80 | - // wpml_make_post_duplicates => not applicable | |
| 81 | + /* | |
| 82 | + * Inserting Content. | |
| 83 | + */ | |
| 84 | + // wpml_admin_make_post_duplicates => not applicable. | |
| 85 | + // wpml_make_post_duplicates => not applicable. | |
| 81 | 86 | add_action( 'wpml_register_single_string', 'icl_register_string', 10, 3 ); |
| 82 | - // wpml_register_string => not applicable | |
| 83 | - // wpml_register_string_packages => not applicable | |
| 84 | - // wpml_delete_package_action => not applicable | |
| 85 | - // wpml_show_package_language_ui => not applicable | |
| 86 | - // wpml_set_element_language_details => not implemented | |
| 87 | - // wpml_multilingual_options => not applicable | |
| 87 | + // wpml_register_string => not applicable. | |
| 88 | + // wpml_register_string_packages => not applicable. | |
| 89 | + // wpml_delete_package_action => not applicable. | |
| 90 | + // wpml_show_package_language_ui => not applicable. | |
| 91 | + // wpml_set_element_language_details => not implemented. | |
| 92 | + // wpml_multilingual_options => not applicable. | |
| 88 | 93 | |
| 89 | - // Miscellaneous | |
| 94 | + /* | |
| 95 | + * Miscellaneous | |
| 96 | + */ | |
| 97 | + // wpml_element_type => not applicable. | |
| 98 | + // wpml_setting => not applicable. | |
| 99 | + // wpml_sub_setting => not applicable. | |
| 100 | + // wpml_editor_cf_to_display => not applicable. | |
| 101 | + // wpml_tm_save_translation_cf => not implemented. | |
| 102 | + // wpml_tm_xliff_export_translated_cf => not applicable. | |
| 103 | + // wpml_tm_xliff_export_original_cf => not applicable. | |
| 104 | + // wpml_duplicate_generic_string => not applicable. | |
| 105 | + // wpml_translatable_user_meta_fields => not implemented. | |
| 106 | + // wpml_cross_domain_language_data => not applicable. | |
| 107 | + // wpml_get_cross_domain_language_data => not applicable. | |
| 108 | + // wpml_loaded => not applicable. | |
| 109 | + // wpml_st_loaded => not applicable. | |
| 110 | + // wpml_tm_loaded => not applicable. | |
| 111 | + // wpml_hide_management_column (3.4.1) => not applicable. | |
| 112 | + // wpml_ls_directories_to_scan => not applicable. | |
| 113 | + // wpml_ls_model_css_classes => not applicable. | |
| 114 | + // wpml_ls_model_language_css_classes => not applicable. | |
| 115 | + // wpml_tf_feedback_open_link => not applicable. | |
| 116 | + // wpml_sync_custom_field => not implemented. | |
| 117 | + // wpml_sync_all_custom_fields => not implemented. | |
| 118 | + // wpml_is_redirected => not implemented. | |
| 90 | 119 | |
| 91 | - // wpml_element_type => not applicable | |
| 92 | - // wpml_setting => not applicable | |
| 93 | - // wpml_sub_setting => not applicable | |
| 94 | - // wpml_editor_cf_to_display => not applicable | |
| 95 | - // wpml_tm_save_translation_cf => not implemented | |
| 96 | - // wpml_tm_xliff_export_translated_cf => not applicable | |
| 97 | - // wpml_tm_xliff_export_original_cf => not applicable | |
| 98 | - // wpml_duplicate_generic_string => not applicable | |
| 99 | - // wpml_translatable_user_meta_fields => not implemented | |
| 100 | - // wpml_cross_domain_language_data => not applicable | |
| 101 | - // wpml_get_cross_domain_language_data => not applicable | |
| 102 | - // wpml_loaded => not applicable | |
| 103 | - // wpml_st_loaded => not applicable | |
| 104 | - // wpml_tm_loaded => not applicable | |
| 105 | - // wpml_hide_management_column (3.4.1) => not applicable | |
| 106 | - // wpml_ls_directories_to_scan => not applicable | |
| 107 | - // wpml_ls_model_css_classes => not applicable | |
| 108 | - // wpml_ls_model_language_css_classes => not applicable | |
| 109 | - // wpml_tf_feedback_open_link => not applicable | |
| 110 | - // wpml_sync_custom_field => not implemented | |
| 111 | - // wpml_sync_all_custom_fields => not implemented | |
| 112 | - // wpml_is_redirected => not implemented | |
| 120 | + /* | |
| 121 | + * Updating Content | |
| 122 | + */ | |
| 123 | + // wpml_set_translation_mode_for_post_type => not implemented. | |
| 113 | 124 | |
| 114 | - // Updating Content | |
| 115 | - | |
| 116 | - // wpml_set_translation_mode_for_post_type => not implemented | |
| 125 | + /* | |
| 126 | + * Undocumented | |
| 127 | + */ | |
| 128 | + add_filter( 'wpml_is_translated_post_type', array( $this, 'wpml_is_translated_post_type' ), 10, 2 ); | |
| 129 | + add_filter( 'wpml_is_translated_taxonomy', array( $this, 'wpml_is_translated_taxonomy' ), 10, 2 ); | |
| 117 | 130 | } |
| 118 | 131 | |
| 119 | 132 | /** |
| 120 | - * Get a list of the languages enabled for a site | |
| 133 | + * Get a list of the languages enabled for a site. | |
| 121 | 134 | * |
| 122 | 135 | * @since 2.0 |
| 123 | 136 | * |
| 124 | - * @param mixed $null Not used | |
| 125 | - * @param array| string $args See arguments of icl_get_languages() | |
| 126 | - * @return array Array of arrays per language | |
| 137 | + * @param mixed $null Not used. | |
| 138 | + * @param array| string $args See arguments of icl_get_languages(). | |
| 139 | + * @return array Array of arrays per language. | |
| 127 | 140 | */ |
| 128 | 141 | public function wpml_active_languages( $null, $args = '' ) { |
| 129 | 142 | return icl_get_languages( $args ); |
| 130 | 143 | } |
| @@ -144,9 +157,9 @@ | ||
| 144 | 157 | return $native_name; |
| 145 | 158 | } |
| 146 | 159 | |
| 147 | 160 | /** |
| 148 | - * Returns an HTML hidden input field with name=”lang” and as value the current language | |
| 161 | + * Returns an HTML hidden input field with name=”lang” and as value the current language. | |
| 149 | 162 | * |
| 150 | 163 | * @since 2.0 |
| 151 | 164 | * |
| 152 | 165 | * @return void |
| @@ -152,8 +165,13 @@ | ||
| 152 | 165 | * @return void |
| 153 | 166 | */ |
| 154 | 167 | public function wpml_add_language_form_field() { |
| 155 | 168 | $lang = pll_current_language(); |
| 169 | + | |
| 170 | + if ( empty( $lang ) ) { | |
| 171 | + return; | |
| 172 | + } | |
| 173 | + | |
| 156 | 174 | $field = sprintf( '<input type="hidden" name="lang" value="%s" />', esc_attr( $lang ) ); |
| 157 | 175 | $field = apply_filters( 'wpml_language_form_input_field', $field, $lang ); |
| 158 | 176 | echo $field; // phpcs:ignore WordPress.Security.EscapeOutput |
| 159 | 177 | } |
| @@ -158,23 +176,23 @@ | ||
| 158 | 176 | echo $field; // phpcs:ignore WordPress.Security.EscapeOutput |
| 159 | 177 | } |
| 160 | 178 | |
| 161 | 179 | /** |
| 162 | - * Find out if a specific language is enabled for the site | |
| 180 | + * Find out if a specific language is enabled for the site. | |
| 163 | 181 | * |
| 164 | 182 | * @since 2.0 |
| 165 | 183 | * |
| 166 | - * @param mixed $null Not used | |
| 167 | - * @param string $slug Language code | |
| 184 | + * @param mixed $null Not used. | |
| 185 | + * @param string $slug Language code. | |
| 168 | 186 | * @return bool |
| 169 | 187 | */ |
| 170 | 188 | public function wpml_language_is_active( $null, $slug ) { |
| 171 | 189 | $language = PLL()->model->get_language( $slug ); |
| 172 | - return empty( $language->active ) || true === $language->active; | |
| 190 | + return ! empty( $language ) && $language->active; | |
| 173 | 191 | } |
| 174 | 192 | |
| 175 | 193 | /** |
| 176 | - * Find out whether the current language text direction is RTL or not | |
| 194 | + * Find out whether the current language text direction is RTL or not. | |
| 177 | 195 | * |
| 178 | 196 | * @since 2.0 |
| 179 | 197 | * |
| 180 | 198 | * @return bool |
| @@ -183,8 +201,143 @@ | ||
| 183 | 201 | return pll_current_language( 'is_rtl' ); |
| 184 | 202 | } |
| 185 | 203 | |
| 186 | 204 | /** |
| 205 | + * Returns the id of the translation group of a translated element. | |
| 206 | + * | |
| 207 | + * @since 3.4 | |
| 208 | + * | |
| 209 | + * @param mixed $empty_value Not used. | |
| 210 | + * @param int $element_id The id of the item, post id for posts, term_taxonomy_id for terms. | |
| 211 | + * @param string $element_type Optional. The type of an element. | |
| 212 | + * @return int | |
| 213 | + */ | |
| 214 | + public function wpml_element_trid( $empty_value, $element_id, $element_type = 'post_post' ) { | |
| 215 | + if ( 0 === strpos( $element_type, 'tax_' ) ) { | |
| 216 | + $element = get_term_by( 'term_taxonomy_id', $element_id ); | |
| 217 | + if ( $element instanceof WP_Term ) { | |
| 218 | + $tr_term = PLL()->model->term->get_object_term( $element->term_id, 'term_translations' ); | |
| 219 | + } | |
| 220 | + } | |
| 221 | + | |
| 222 | + if ( 0 === strpos( $element_type, 'post_' ) ) { | |
| 223 | + $tr_term = PLL()->model->post->get_object_term( $element_id, 'post_translations' ); | |
| 224 | + } | |
| 225 | + | |
| 226 | + if ( isset( $tr_term ) && $tr_term instanceof WP_Term ) { | |
| 227 | + return $tr_term->term_id; | |
| 228 | + } | |
| 229 | + | |
| 230 | + return 0; | |
| 231 | + } | |
| 232 | + | |
| 233 | + /** | |
| 234 | + * Returns the element translations info using the ID of the translation group. | |
| 235 | + * | |
| 236 | + * @since 3.4 | |
| 237 | + * | |
| 238 | + * @param mixed $empty_value Not used. | |
| 239 | + * @param int $trid The ID of the translation group. | |
| 240 | + * @param string $element_type Optional. The type of an element. | |
| 241 | + * @return stdClass[] | |
| 242 | + */ | |
| 243 | + public function wpml_get_element_translations( $empty_value, $trid, $element_type = 'post_post' ) { | |
| 244 | + $return = array(); | |
| 245 | + | |
| 246 | + if ( 0 === strpos( $element_type, 'tax_' ) ) { | |
| 247 | + $translations = PLL()->model->term->get_translations_from_term_id( $trid ); | |
| 248 | + if ( empty( $translations ) ) { | |
| 249 | + return array(); | |
| 250 | + } | |
| 251 | + | |
| 252 | + $original = min( $translations ); // We suppose that the original is the first term created. | |
| 253 | + $source_lang = array_search( $original, $translations ); | |
| 254 | + | |
| 255 | + $args = array( | |
| 256 | + 'include' => $translations, | |
| 257 | + 'hide_empty' => false, | |
| 258 | + ); | |
| 259 | + $_terms = get_terms( $args ); | |
| 260 | + | |
| 261 | + if ( ! is_array( $_terms ) ) { | |
| 262 | + return array(); | |
| 263 | + } | |
| 264 | + | |
| 265 | + $terms = array(); | |
| 266 | + foreach ( $_terms as $term ) { | |
| 267 | + $terms[ $term->term_id ] = $term; | |
| 268 | + } | |
| 269 | + | |
| 270 | + foreach ( $translations as $lang => $term_id ) { | |
| 271 | + if ( empty( $terms[ $term_id ] ) ) { | |
| 272 | + continue; | |
| 273 | + } | |
| 274 | + | |
| 275 | + /* | |
| 276 | + * It seems that WPML fills the `instances` property with the total number of posts | |
| 277 | + * related to this term, while `WP_Term::$count` includes only *published* posts. | |
| 278 | + * We intentionnally accept this difference to avoid extra DB queries. | |
| 279 | + */ | |
| 280 | + $return[ $lang ] = (object) array( | |
| 281 | + 'translation_id' => '0', // We have nothing equivalent. | |
| 282 | + 'language_code' => $lang, | |
| 283 | + 'element_id' => (string) $terms[ $term_id ]->term_taxonomy_id, | |
| 284 | + 'source_language_code' => $source_lang === $lang ? null : $source_lang, | |
| 285 | + 'element_type' => $element_type, | |
| 286 | + 'original' => $original === $term_id ? '1' : '0', | |
| 287 | + 'name' => $terms[ $term_id ]->name, | |
| 288 | + 'term_id' => (string) $term_id, | |
| 289 | + 'instances' => (string) $terms[ $term_id ]->count, | |
| 290 | + ); | |
| 291 | + } | |
| 292 | + } | |
| 293 | + | |
| 294 | + if ( 0 === strpos( $element_type, 'post_' ) ) { | |
| 295 | + $translations = PLL()->model->post->get_translations_from_term_id( $trid ); | |
| 296 | + if ( empty( $translations ) ) { | |
| 297 | + return array(); | |
| 298 | + } | |
| 299 | + | |
| 300 | + $original = min( $translations ); // We suppose that the original is the first post created. | |
| 301 | + $source_lang = array_search( $original, $translations ); | |
| 302 | + | |
| 303 | + $args = array( | |
| 304 | + 'post__in' => $translations, | |
| 305 | + 'no_paging' => true, | |
| 306 | + 'posts_per_page' => -1, | |
| 307 | + 'update_post_meta_cache' => false, | |
| 308 | + 'update_post_term_cache' => false, | |
| 309 | + 'lang' => '', | |
| 310 | + ); | |
| 311 | + $_posts = get_posts( $args ); | |
| 312 | + | |
| 313 | + $posts = array(); | |
| 314 | + foreach ( $_posts as $post ) { | |
| 315 | + $posts[ $post->ID ] = $post; | |
| 316 | + } | |
| 317 | + | |
| 318 | + foreach ( $translations as $lang => $post_id ) { | |
| 319 | + if ( empty( $posts[ $post_id ] ) ) { | |
| 320 | + continue; | |
| 321 | + } | |
| 322 | + | |
| 323 | + $return[ $lang ] = (object) array( | |
| 324 | + 'translation_id' => '0', // We have nothing equivalent. | |
| 325 | + 'language_code' => $lang, | |
| 326 | + 'element_id' => (string) $post_id, | |
| 327 | + 'source_language_code' => $source_lang === $lang ? null : $source_lang, | |
| 328 | + 'element_type' => $element_type, | |
| 329 | + 'original' => $original === $post_id ? '1' : '0', | |
| 330 | + 'post_title' => $posts[ $post_id ]->post_title, | |
| 331 | + 'post_status' => $posts[ $post_id ]->post_status, | |
| 332 | + ); | |
| 333 | + } | |
| 334 | + } | |
| 335 | + | |
| 336 | + return $return; | |
| 337 | + } | |
| 338 | + | |
| 339 | + /** | |
| 187 | 340 | * Switches whole site to the given language or restores the language that was set when first calling this function. |
| 188 | 341 | * Unlike the WPML original action, it is not possible to set the current language and the cookie to different values. |
| 189 | 342 | * |
| 190 | 343 | * @since 2.7 |
| @@ -213,52 +366,60 @@ | ||
| 213 | 366 | do_action( 'wpml_language_has_switched', $lang, $cookie, self::$original_language ); |
| 214 | 367 | } |
| 215 | 368 | |
| 216 | 369 | /** |
| 217 | - * Get the language code for a translatable element | |
| 370 | + * Get the language code for a translatable element. | |
| 218 | 371 | * |
| 219 | 372 | * @since 2.0 |
| 220 | 373 | * |
| 221 | - * @param mixed $language_code | |
| 374 | + * @param mixed $language_code A 2-letter language code. | |
| 222 | 375 | * @param array $args An array with two keys element_id => post_id or term_taxonomy_id, element_type => post type or taxonomy |
| 223 | - * @return string | |
| 376 | + * @return string|null | |
| 224 | 377 | */ |
| 225 | 378 | public function wpml_element_language_code( $language_code, $args ) { |
| 226 | 379 | $type = $args['element_type']; |
| 227 | - $id = $args['element_id']; | |
| 228 | - $pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false ); | |
| 229 | - if ( 'term' === $pll_type ) { | |
| 380 | + $id = $args['element_id']; | |
| 381 | + | |
| 382 | + if ( 'post' === $type || pll_is_translated_post_type( $type ) ) { | |
| 383 | + $language = pll_get_post_language( $id ); | |
| 384 | + return is_string( $language ) ? $language : null; | |
| 385 | + } | |
| 386 | + | |
| 387 | + if ( 'term' === $type || pll_is_translated_taxonomy( $type ) ) { | |
| 230 | 388 | $term = get_term_by( 'term_taxonomy_id', $id ); |
| 231 | 389 | if ( $term instanceof WP_Term ) { |
| 232 | 390 | $id = $term->term_id; |
| 233 | 391 | } |
| 392 | + $language = pll_get_term_language( $id ); | |
| 393 | + return is_string( $language ) ? $language : null; | |
| 234 | 394 | } |
| 235 | - return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code; | |
| 395 | + | |
| 396 | + return null; | |
| 236 | 397 | } |
| 237 | 398 | |
| 238 | 399 | /** |
| 239 | - * Translates a string | |
| 400 | + * Translates a string. | |
| 240 | 401 | * |
| 241 | 402 | * @since 2.0 |
| 242 | 403 | * |
| 243 | - * @param string $string The string's original value | |
| 244 | - * @param string $context The string's registered context | |
| 245 | - * @param string $name The string's registered name | |
| 246 | - * @param null|string $lang Optional, return the translation in this language, defaults to current language | |
| 247 | - * @return string The translated string | |
| 404 | + * @param string $string The string's original value. | |
| 405 | + * @param string $context The string's registered context. | |
| 406 | + * @param string $name The string's registered name. | |
| 407 | + * @param null|string $lang Optional, return the translation in this language, defaults to current language. | |
| 408 | + * @return string The translated string. | |
| 248 | 409 | */ |
| 249 | 410 | public function wpml_translate_single_string( $string, $context, $name, $lang = null ) { |
| 250 | - $has_translation = null; // Passed by reference | |
| 411 | + $has_translation = null; // Passed by reference. | |
| 251 | 412 | return icl_translate( $context, $name, $string, false, $has_translation, $lang ); |
| 252 | 413 | } |
| 253 | 414 | |
| 254 | 415 | /** |
| 255 | - * Converts a permalink to a language specific permalink | |
| 416 | + * Converts a permalink to a language specific permalink. | |
| 256 | 417 | * |
| 257 | 418 | * @since 2.2 |
| 258 | 419 | * |
| 259 | - * @param string $url The url to filter | |
| 260 | - * @param null|string $lang Langage code, optional, defaults to the current language | |
| 420 | + * @param string $url The url to filter. | |
| 421 | + * @param null|string $lang Language code, optional, defaults to the current language. | |
| 261 | 422 | * @return string |
| 262 | 423 | */ |
| 263 | 424 | public function wpml_permalink( $url, $lang = '' ) { |
| 264 | 425 | $lang = PLL()->model->get_language( $lang ); |
| @@ -270,15 +431,15 @@ | ||
| 270 | 431 | return empty( $lang ) ? $url : PLL()->links_model->switch_language_in_link( $url, $lang ); |
| 271 | 432 | } |
| 272 | 433 | |
| 273 | 434 | /** |
| 274 | - * Translates a post type slug | |
| 435 | + * Translates a post type slug. | |
| 275 | 436 | * |
| 276 | 437 | * @since 2.2 |
| 277 | 438 | * |
| 278 | - * @param string $slug Post type slug | |
| 279 | - * @param string $post_type Post type name | |
| 280 | - * @param string $lang Optional language code (defaults to current language) | |
| 439 | + * @param string $slug Post type slug. | |
| 440 | + * @param string $post_type Post type name. | |
| 441 | + * @param string $lang Optional language code (defaults to current language). | |
| 281 | 442 | * @return string |
| 282 | 443 | */ |
| 283 | 444 | public function wpml_get_translated_slug( $slug, $post_type, $lang = null ) { |
| 284 | 445 | if ( isset( PLL()->translate_slugs ) ) { |
| @@ -291,18 +452,49 @@ | ||
| 291 | 452 | return $slug; |
| 292 | 453 | } |
| 293 | 454 | |
| 294 | 455 | /** |
| 295 | - * Find out whether a post type or a taxonomy term is translated | |
| 456 | + * Find out whether a post type or a taxonomy term is translated. | |
| 296 | 457 | * |
| 297 | 458 | * @since 2.0 |
| 298 | 459 | * |
| 299 | - * @param mixed $null | |
| 300 | - * @param int $id The post_id or term_id | |
| 301 | - * @param string $type The post type or taxonomy | |
| 460 | + * @param mixed $null Not used. | |
| 461 | + * @param int $id The post_id or term_id. | |
| 462 | + * @param string $type The post type or taxonomy. | |
| 302 | 463 | * @return bool |
| 303 | 464 | */ |
| 304 | 465 | public function wpml_element_has_translations( $null, $id, $type ) { |
| 305 | - $pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false ); | |
| 306 | - return ( $pll_type && $translations = call_user_func( "pll_get_{$pll_type}_translations", $id ) ) ? count( $translations ) > 1 : false; | |
| 466 | + if ( 'post' === $type || pll_is_translated_post_type( $type ) ) { | |
| 467 | + return count( pll_get_post_translations( $id ) ) > 1; | |
| 468 | + } elseif ( 'term' === $type || pll_is_translated_taxonomy( $type ) ) { | |
| 469 | + return count( pll_get_term_translations( $id ) ) > 1; | |
| 470 | + } | |
| 471 | + | |
| 472 | + return false; | |
| 473 | + } | |
| 474 | + | |
| 475 | + /** | |
| 476 | + * Returns true if languages and translations are managed for this post type. | |
| 477 | + * | |
| 478 | + * @since 3.4 | |
| 479 | + * | |
| 480 | + * @param mixed $value Not used. | |
| 481 | + * @param string $post_type The post type name. | |
| 482 | + * @return bool | |
| 483 | + */ | |
| 484 | + public function wpml_is_translated_post_type( $value, $post_type ) { | |
| 485 | + return pll_is_translated_post_type( $post_type ); | |
| 486 | + } | |
| 487 | + | |
| 488 | + /** | |
| 489 | + * Returns true if languages and translations are managed for this taxonomy. | |
| 490 | + * | |
| 491 | + * @since 3.4 | |
| 492 | + * | |
| 493 | + * @param mixed $value Not used. | |
| 494 | + * @param string $taxonomy The taxonomy name. | |
| 495 | + * @return bool | |
| 496 | + */ | |
| 497 | + public function wpml_is_translated_taxonomy( $value, $taxonomy ) { | |
| 498 | + return pll_is_translated_taxonomy( $taxonomy ); | |
| 307 | 499 | } |
| 308 | 500 | } |