PluginProbe
Polylang / 3.2.8
Polylang v3.2.8
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 / modules / wpml / wpml-legacy-api.php

wpml-legacy-api.php in Polylang 3.2.8, at modules/wpml/wpml-legacy-api.php

416 lines 15.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 /**
7 * Compatibility with WPML legacy API
8 * Deprecated since WPML 3.2 and no more documented
9 * But a lot of 3rd party plugins / themes are still using these functions
10 */
11
12 if ( ! function_exists( 'icl_get_home_url' ) ) {
13 /**
14 * Link to the home page in the active language
15 *
16 * @since 0.9.4
17 *
18 * @return string
19 */
20 function icl_get_home_url() {
21 return pll_home_url();
22 }
23 }
24
25 if ( ! function_exists( 'icl_get_languages' ) ) {
26 /**
27 * Used for building custom language selectors
28 * available only on frontend
29 *
30 * List of paramaters accepted in $args:
31 *
32 * skip_missing => whether to skip missing translation or not, 0 or 1, defaults to 0
33 * orderby => 'id', 'code', 'name', defaults to 'id'
34 * order => 'ASC' or 'DESC', defaults to 'ASC'
35 * link_empty_to => link to use when the translation is missing {$lang} is replaced by the language code
36 *
37 * List of parameters returned per language:
38 *
39 * id => the language id
40 * active => whether this is the active language or no, 0 or 1
41 * native_name => the language name
42 * missing => whether the translation is missing or not, 0 or 1
43 * translated_name => empty, does not exist in Polylang
44 * language_code => the language code ( slug )
45 * country_flag_url => the url of the flag
46 * url => the url of the translation
47 *
48 * @since 1.0
49 *
50 * @param string|array $args optional
51 * @return array array of arrays per language
52 */
53 function icl_get_languages( $args = '' ) {
54 $args = wp_parse_args( $args, array( 'skip_missing' => 0, 'orderby' => 'id', 'order' => 'ASC' ) );
55 $orderby = ( isset( $args['orderby'] ) && 'code' == $args['orderby'] ) ? 'slug' : ( isset( $args['orderby'] ) && 'name' == $args['orderby'] ? 'name' : 'id' );
56 $order = ( ! empty( $args['order'] ) && 'desc' == $args['order'] ) ? 'DESC' : 'ASC';
57
58 $arr = array();
59
60 // NB: When 'skip_missing' is false, WPML returns all languages even if there is no content
61 $languages = PLL()->model->get_languages_list( array( 'hide_empty' => $args['skip_missing'] ) );
62 $languages = wp_list_sort( $languages, $orderby, $order ); // Since WP 4.7
63
64 foreach ( $languages as $lang ) {
65 // We can find a translation only on frontend once the global $wp_query object has been instantiated
66 if ( method_exists( PLL()->links, 'get_translation_url' ) && ! empty( $GLOBALS['wp_query'] ) ) {
67 $url = PLL()->links->get_translation_url( $lang );
68 }
69
70 // It seems that WPML does not bother of skip_missing parameter on admin side and before the $wp_query object has been filled
71 if ( empty( $url ) && ! empty( $args['skip_missing'] ) && ! is_admin() && did_action( 'parse_query' ) ) {
72 continue;
73 }
74
75 $arr[ $lang->slug ] = array(
76 'id' => $lang->term_id,
77 'active' => isset( PLL()->curlang->slug ) && PLL()->curlang->slug == $lang->slug ? 1 : 0,
78 'native_name' => $lang->name,
79 'missing' => empty( $url ) ? 1 : 0,
80 'translated_name' => '', // Does not exist in Polylang
81 'language_code' => $lang->slug,
82 'country_flag_url' => $lang->get_display_flag_url(),
83 'url' => ! empty( $url ) ? $url :
84 ( empty( $args['link_empty_to'] ) ? PLL()->links->get_home_url( $lang ) :
85 str_replace( '{$lang}', $lang->slug, $args['link_empty_to'] ) ),
86 );
87 }
88
89 // Apply undocumented WPML filter
90 $arr = apply_filters( 'icl_ls_languages', $arr );
91
92 return $arr;
93 }
94 }
95
96 if ( ! function_exists( 'icl_link_to_element' ) ) {
97 /**
98 * Used for creating language dependent links in themes
99 *
100 * @since 1.0
101 * @since 2.0 add support for arguments 6 and 7
102 *
103 * @param int $id object id
104 * @param string $type optional, post type or taxonomy name of the object, defaults to 'post'
105 * @param string $text optional, the link text. If not specified will produce the name of the element in the current language
106 * @param array $args optional, an array of arguments to add to the link, defaults to empty
107 * @param string $anchor optional, the anchor to add to the link, defaults to empty
108 * @param bool $echo optional, whether to echo the link, defaults to true
109 * @param bool $return_original_if_missing optional, whether to return a value if the translation is missing
110 * @return string a language dependent link
111 */
112 function icl_link_to_element( $id, $type = 'post', $text = '', $args = array(), $anchor = '', $echo = true, $return_original_if_missing = true ) {
113 if ( 'tag' == $type ) {
114 $type = 'post_tag';
115 }
116
117 $pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
118 if ( $pll_type && ( $lang = pll_current_language() ) && ( $tr_id = PLL()->model->$pll_type->get_translation( $id, $lang ) ) && ( 'term' === $pll_type || PLL()->model->post->current_user_can_read( $tr_id ) ) ) {
119 $id = $tr_id;
120 } elseif ( ! $return_original_if_missing ) {
121 return '';
122 }
123
124 if ( post_type_exists( $type ) ) {
125 $link = get_permalink( $id );
126 if ( empty( $text ) ) {
127 $text = get_the_title( $id );
128 }
129 } elseif ( taxonomy_exists( $type ) ) {
130 $link = get_term_link( $id, $type );
131 if ( empty( $text ) && ( $term = get_term( $id, $type ) ) && $term instanceof WP_Term ) {
132 $text = $term->name;
133 }
134 }
135
136 if ( empty( $link ) || is_wp_error( $link ) ) {
137 return '';
138 }
139
140 if ( ! empty( $args ) ) {
141 $link .= ( false === strpos( $link, '?' ) ? '?' : '&' ) . http_build_query( $args );
142 }
143
144 if ( ! empty( $anchor ) ) {
145 $link .= '#' . $anchor;
146 }
147
148 $link = sprintf( '<a href="%s">%s</a>', esc_url( $link ), esc_html( $text ) );
149
150 if ( $echo ) {
151 echo $link; // phpcs:ignore WordPress.Security.EscapeOutput
152 }
153
154 return $link;
155 }
156 }
157
158 if ( ! function_exists( 'icl_object_id' ) ) {
159 /**
160 * Returns an element’s ID in the current language or in another specified language.
161 *
162 * @since 0.9.5
163 *
164 * @param int $element_id Object id.
165 * @param string $element_type Optional, post type or taxonomy name of the object, defaults to 'post'.
166 * @param bool $return_original_if_missing Optional, true if Polylang should return the original id if the translation is missing, defaults to false.
167 * @param string|null $ulanguage_code Optional, language code, defaults to the current language.
168 * @return int|null The object id of the translation, null if the translation is missing and $return_original_if_missing set to false.
169 */
170 function icl_object_id( $element_id, $element_type = 'post', $return_original_if_missing = false, $ulanguage_code = null ) {
171 if ( empty( $element_id ) ) {
172 return null;
173 }
174
175 $element_id = (int) $element_id;
176
177 if ( 'any' === $element_type ) {
178 $element_type = get_post_type( $element_id );
179 }
180
181 if ( empty( $element_type ) ) {
182 return null;
183 }
184
185 if ( empty( $ulanguage_code ) ) {
186 $ulanguage_code = pll_current_language();
187 }
188
189 if ( 'nav_menu' === $element_type ) {
190 $tr_id = false;
191 $theme = get_option( 'stylesheet' );
192 if ( isset( PLL()->options['nav_menus'][ $theme ] ) ) {
193 foreach ( PLL()->options['nav_menus'][ $theme ] as $menu ) {
194 if ( array_search( $element_id, $menu ) && ! empty( $menu[ $ulanguage_code ] ) ) {
195 $tr_id = $menu[ $ulanguage_code ];
196 break;
197 }
198 }
199 }
200 } elseif ( pll_is_translated_post_type( $element_type ) ) {
201 $tr_id = PLL()->model->post->get_translation( $element_id, $ulanguage_code );
202 } elseif ( pll_is_translated_taxonomy( $element_type ) ) {
203 $tr_id = PLL()->model->term->get_translation( $element_id, $ulanguage_code );
204 }
205
206 if ( ! isset( $tr_id ) ) {
207 return $element_id; // WPML doesn't honor $return_original_if_missing if the post type or taxonomy is not translated.
208 }
209
210 if ( empty( $tr_id ) ) {
211 return $return_original_if_missing ? $element_id : null;
212 }
213
214 return (int) $tr_id;
215 }
216 }
217
218 if ( ! function_exists( 'wpml_object_id_filter' ) ) {
219 /**
220 * Undocumented alias of `icl_object_id` introduced in WPML 3.2, used by Yith WooCommerce compare
221 *
222 * @since 2.2.4
223 *
224 * @param int $id object id
225 * @param string $type optional, post type or taxonomy name of the object, defaults to 'post'
226 * @param bool $return_original_if_missing optional, true if Polylang should return the original id if the translation is missing, defaults to false
227 * @param string $lang optional, language code, defaults to current language
228 * @return int|null the object id of the translation, null if the translation is missing and $return_original_if_missing set to false
229 */
230 function wpml_object_id_filter( $id, $type = 'post', $return_original_if_missing = false, $lang = null ) {
231 return icl_object_id( $id, $type, $return_original_if_missing, $lang );
232 }
233 }
234
235 if ( ! function_exists( 'wpml_get_language_information' ) ) {
236 /**
237 * Undocumented function used by the theme Maya
238 * returns the post language
239 *
240 * @see https://wpml.org/forums/topic/canonical-urls-for-wpml-duplicated-posts/#post-52198 for the original WPML code
241 *
242 * @since 1.8
243 *
244 * @param null $empty optional, not used
245 * @param int $post_id optional, post id, defaults to current post
246 * @return array
247 */
248 function wpml_get_language_information( $empty = null, $post_id = null ) {
249 if ( empty( $post_id ) ) {
250 $post_id = get_the_ID();
251 }
252
253 // FIXME WPML may return a WP_Error object
254 return false === ( $lang = PLL()->model->post->get_language( $post_id ) ) ? array() : array(
255 'language_code' => $lang->slug,
256 'locale' => $lang->locale,
257 'text_direction' => (bool) $lang->is_rtl,
258 'display_name' => $lang->name, // Seems to be the post language name displayed in the current language, not a feature in Polylang
259 'native_name' => $lang->name,
260 'different_language' => pll_current_language() !== $lang->slug,
261 );
262 }
263 }
264
265 if ( ! function_exists( 'icl_register_string' ) ) {
266 /**
267 * Registers a string for translation in the "strings translation" panel
268 *
269 * The 4th and 5th parameters $allow_empty_value and $source_lang are not used by Polylang.
270 *
271 * @since 0.9.3
272 *
273 * @param string $context the group in which the string is registered, defaults to 'polylang'
274 * @param string $name a unique name for the string
275 * @param string $string the string to register
276 * @return void
277 */
278 function icl_register_string( $context, $name, $string ) {
279 PLL_WPML_Compat::instance()->register_string( $context, $name, $string );
280 }
281 }
282
283 if ( ! function_exists( 'icl_unregister_string' ) ) {
284 /**
285 * Removes a string from the "strings translation" panel
286 *
287 * @since 1.0.2
288 *
289 * @param string $context the group in which the string is registered, defaults to 'polylang'
290 * @param string $name a unique name for the string
291 * @return void
292 */
293 function icl_unregister_string( $context, $name ) {
294 PLL_WPML_Compat::instance()->unregister_string( $context, $name );
295 }
296 }
297
298 if ( ! function_exists( 'icl_t' ) ) {
299 /**
300 * Gets the translated value of a string ( previously registered with icl_register_string or pll_register_string )
301 *
302 * @since 0.9.3
303 * @since 1.9.2 argument 3 is optional
304 * @since 2.0 add support for arguments 4 to 6
305 *
306 * @param string $context the group in which the string is registered
307 * @param string $name a unique name for the string
308 * @param string $string the string to translate, optional for strings registered with icl_register_string
309 * @param bool|null $has_translation optional, not supported in Polylang
310 * @param bool $bool optional, not used
311 * @param string|null $lang optional, return the translation in this language, defaults to current language
312 * @return string the translated string
313 */
314 function icl_t( $context, $name, $string = '', &$has_translation = null, $bool = false, $lang = null ) {
315 return icl_translate( $context, $name, $string, false, $has_translation, $lang );
316 }
317 }
318
319 if ( ! function_exists( 'icl_translate' ) ) {
320 /**
321 * Undocumented function used by NextGen Gallery
322 * used in PLL_Plugins_Compat for Jetpack with only 3 arguments
323 *
324 * @since 1.0.2
325 * @since 2.0 add support for arguments 5 and 6, strings are no more automatically registered
326 *
327 * @param string $context the group in which the string is registered
328 * @param string $name a unique name for the string
329 * @param string $string the string to translate, optional for strings registered with icl_register_string
330 * @param bool $bool optional, not used
331 * @param bool|null $has_translation optional, not supported in Polylang
332 * @param string|null $lang optional, return the translation in this language, defaults to current language
333 * @return string the translated string
334 */
335 function icl_translate( $context, $name, $string = '', $bool = false, &$has_translation = null, $lang = null ) {
336 // FIXME WPML can automatically registers the string based on an option
337 if ( empty( $string ) ) {
338 $string = PLL_WPML_Compat::instance()->get_string_by_context_and_name( $context, $name );
339 }
340 return empty( $lang ) ? pll__( $string ) : pll_translate_string( $string, $lang );
341 }
342 }
343
344 if ( ! function_exists( 'wpml_get_copied_fields_for_post_edit' ) ) {
345 /**
346 * Undocumented function used by Types
347 * FIXME: tested only with Types
348 * probably incomplete as Types locks the custom fields for a new post, but not when edited
349 * This is probably linked to the fact that WPML has always an original post in the default language and not Polylang :)
350 *
351 * @since 1.1.2
352 *
353 * @return array
354 */
355 function wpml_get_copied_fields_for_post_edit() {
356 if ( empty( $_GET['from_post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
357 return array();
358 }
359
360 $arr = array( 'original_post_id' => (int) $_GET['from_post'] ); // phpcs:ignore WordPress.Security.NonceVerification
361
362 // Don't know what WPML does but Polylang does copy all public meta keys by default
363 foreach ( $keys = array_unique( array_keys( get_post_custom( $arr['original_post_id'] ) ) ) as $k => $meta_key ) {
364 if ( is_protected_meta( $meta_key ) ) {
365 unset( $keys[ $k ] );
366 }
367 }
368
369 // Apply our filter and fill the expected output ( see /types/embedded/includes/fields-post.php )
370 /** This filter is documented in modules/sync/admin-sync.php */
371 $arr['fields'] = array_unique( apply_filters( 'pll_copy_post_metas', empty( $keys ) ? array() : $keys, false ) );
372 return $arr;
373 }
374 }
375
376 if ( ! function_exists( 'icl_get_default_language' ) ) {
377 /**
378 * Undocumented function used by Warp 6 by Yootheme
379 *
380 * @since 1.0.5
381 *
382 * @return string default language code
383 */
384 function icl_get_default_language() {
385 return pll_default_language();
386 }
387 }
388
389 if ( ! function_exists( 'wpml_get_default_language' ) ) {
390 /**
391 * Undocumented function reported to be used by Table Rate Shipping for WooCommerce
392 *
393 * @see https://wordpress.org/support/topic/add-wpml-compatibility-function
394 *
395 * @since 1.8.2
396 *
397 * @return string default language code
398 */
399 function wpml_get_default_language() {
400 return pll_default_language();
401 }
402 }
403
404 if ( ! function_exists( 'icl_get_current_language' ) ) {
405 /**
406 * Undocumented function used by Ultimate Member
407 *
408 * @since 2.2.4
409 *
410 * @return string Current language code
411 */
412 function icl_get_current_language() {
413 return pll_current_language();
414 }
415 }
416