PluginProbe
Polylang / 2.8.1
Polylang v2.8.1
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 2.8.1, at modules/wpml/wpml-legacy-api.php

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