PluginProbe
Polylang / 3.1.4
Polylang v3.1.4
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
← All changes | include/language.php +287 -116 2.83.1.4 View file →
@@ -3,86 +3,215 @@
3 3 * @package Polylang
4 4 */
5 5
6 6 /**
7 - * A language object is made of two terms in 'language' and 'term_language' taxonomies
8 - * manipulating only one object per language instead of two terms should make things easier
7 + * A language object is made of two terms in 'language' and 'term_language' taxonomies.
8 + * Manipulating only one object per language instead of two terms should make things easier.
9 9 *
10 - * Properties:
11 - * term_id => id of term in 'language' taxonomy
12 - * name => language name. Ex: English
13 - * slug => language code used in url. Ex: en
14 - * term_group => order of the language when displayed in a list of languages
15 - * term_taxonomy_id => term taxonomy id in 'language' taxonomy
16 - * taxonomy => 'language'
17 - * description => language locale for backward compatibility
18 - * parent => 0 / not used
19 - * count => number of posts and pages in that language
20 - * tl_term_id => id of the term in 'term_language' taxonomy
21 - * tl_term_taxonomy_id => term taxonomy id in 'term_language' taxonomy
22 - * tl_count => number of terms in that language ( not used by Polylang )
23 - * locale => WordPress language locale. Ex: en_US
24 - * is_rtl => 1 if the language is rtl
25 - * w3c => W3C locale
26 - * flag_code => code of the flag
27 - * flag_url => url of the flag
28 - * flag => html img of the flag
29 - * custom_flag_url => url of the custom flag if exists, internal use only, moves to flag_url on frontend
30 - * custom_flag => html img of the custom flag if exists, internal use only, moves to flag on frontend
31 - * home_url => home url in this language
32 - * search_url => home url to use in search forms
33 - * host => host of this language
34 - * mo_id => id of the post storing strings translations
35 - * page_on_front => id of the page on front in this language ( set from pll_languages_list filter )
36 - * page_for_posts => id of the page for posts in this language ( set from pll_languages_list filter )
37 - *
38 10 * @since 1.2
39 11 */
40 12 class PLL_Language {
41 - public $term_id, $name, $slug, $term_group, $term_taxonomy_id, $taxonomy, $description, $parent, $count;
42 - public $tl_term_id, $tl_term_taxonomy_id, $tl_count;
43 - public $locale, $is_rtl;
44 - public $w3c, $facebook;
45 - public $flag_url, $flag;
46 - public $home_url, $search_url;
47 - public $host, $mo_id;
48 - public $page_on_front, $page_for_posts;
13 + /**
14 + * Id of the term in 'language' taxonomy.
15 + *
16 + * @var int
17 + */
18 + public $term_id;
49 19
50 20 /**
51 - * Constructor: builds a language object given its two corresponding terms in language and term_language taxonomies
21 + * Language name. Ex: English.
52 22 *
23 + * @var string
24 + */
25 + public $name;
26 +
27 + /**
28 + * Language code used in url. Ex: en.
29 + *
30 + * @var string
31 + */
32 + public $slug;
33 +
34 + /**
35 + * Order of the language when displayed in a list of languages.
36 + *
37 + * @var int
38 + */
39 + public $term_group;
40 +
41 + /**
42 + * Term taxonomy id in 'language' taxonomy.
43 + *
44 + * @var int
45 + */
46 + public $term_taxonomy_id;
47 +
48 + /**
49 + * Number of posts and pages in that language.
50 + *
51 + * @var int
52 + */
53 + public $count;
54 +
55 + /**
56 + * Id of the term in 'term_language' taxonomy.
57 + *
58 + * @var int
59 + */
60 + public $tl_term_id;
61 +
62 + /**
63 + * Term taxonomy id in 'term_language' taxonomy.
64 + *
65 + * @var int
66 + */
67 + public $tl_term_taxonomy_id;
68 +
69 + /**
70 + * Number of terms in that language.
71 + *
72 + * @var int
73 + */
74 + public $tl_count;
75 +
76 + /**
77 + * WordPress language locale. Ex: en_US.
78 + *
79 + * @var string
80 + */
81 + public $locale;
82 +
83 + /**
84 + * 1 if the language is rtl, 0 otherwise.
85 + *
86 + * @var int
87 + */
88 + public $is_rtl;
89 +
90 + /**
91 + * W3C locale.
92 + *
93 + * @var string.
94 + */
95 + public $w3c;
96 +
97 + /**
98 + * Facebook locale.
99 + *
100 + * @var string.
101 + */
102 + public $facebook;
103 +
104 + /**
105 + * Home url in this language.
106 + *
107 + * @var string
108 + */
109 + public $home_url;
110 +
111 + /**
112 + * Home url to use in search forms.
113 + *
114 + * @var string
115 + */
116 + public $search_url;
117 +
118 + /**
119 + * Host corresponding to this language.
120 + *
121 + * @var string
122 + */
123 + public $host;
124 +
125 + /**
126 + * Id of the post storing strings translations.
127 + *
128 + * @var int
129 + */
130 + public $mo_id;
131 +
132 + /**
133 + * Id of the page on front in this language ( set from pll_languages_list filter ).
134 + *
135 + * @var int
136 + */
137 + public $page_on_front;
138 +
139 + /**
140 + * Id of the page for posts in this language ( set from pll_languages_list filter ).
141 + *
142 + * @var int
143 + */
144 + public $page_for_posts;
145 +
146 + /**
147 + * Code of the flag.
148 + *
149 + * @var string
150 + */
151 + public $flag_code;
152 +
153 + /**
154 + * Url of the flag.
155 + *
156 + * @var string
157 + */
158 + public $flag_url;
159 +
160 + /**
161 + * Html markup of the flag.
162 + *
163 + * @var string
164 + */
165 + public $flag;
166 +
167 + /**
168 + * Url of the custom flag if it exists.
169 + *
170 + * @var string
171 + */
172 + public $custom_flag_url;
173 +
174 + /**
175 + * Html markup of the custom flag if it exists.
176 + *
177 + * @var string
178 + */
179 + public $custom_flag;
180 +
181 + /**
182 + * Constructor: builds a language object given its two corresponding terms in 'language' and 'term_language' taxonomies.
183 + *
53 184 * @since 1.2
54 185 *
55 - * @param object|array $language 'language' term or language object properties stored as an array
56 - * @param object $term_language Corresponding 'term_language' term
186 + * @param WP_Term|array $language Term in 'language' taxonomy or language object properties stored as an array.
187 + * @param WP_Term $term_language Corresponding 'term_language' term.
57 188 */
58 189 public function __construct( $language, $term_language = null ) {
59 - // Build the object from all properties stored as an array
60 190 if ( empty( $term_language ) ) {
191 + // Build the object from all properties stored as an array.
61 192 foreach ( $language as $prop => $value ) {
62 193 $this->$prop = $value;
63 194 }
64 - }
195 + } else {
196 + // Build the object from taxonomy terms.
197 + $this->term_id = (int) $language->term_id;
198 + $this->name = $language->name;
199 + $this->slug = $language->slug;
200 + $this->term_group = (int) $language->term_group;
201 + $this->term_taxonomy_id = (int) $language->term_taxonomy_id;
202 + $this->count = (int) $language->count;
65 203
66 - // Build the object from taxonomies
67 - else {
68 - foreach ( $language as $prop => $value ) {
69 - $this->$prop = in_array( $prop, array( 'term_id', 'term_taxonomy_id', 'count' ) ) ? (int) $language->$prop : $language->$prop;
70 - }
71 -
72 204 $this->tl_term_id = (int) $term_language->term_id;
73 205 $this->tl_term_taxonomy_id = (int) $term_language->term_taxonomy_id;
74 206 $this->tl_count = (int) $term_language->count;
75 207
76 - // The description field can contain any property
77 - // Backward compatibility for is_rtl
208 + // The description field can contain any property.
78 209 $description = maybe_unserialize( $language->description );
79 210 foreach ( $description as $prop => $value ) {
80 211 'rtl' == $prop ? $this->is_rtl = $value : $this->$prop = $value;
81 212 }
82 213
83 - $this->description = &$this->locale; // Backward compatibility with Polylang < 1.2
84 -
85 214 $this->mo_id = PLL_MO::get_id( $this );
86 215
87 216 $languages = include POLYLANG_DIR . '/settings/languages.php';
88 217 $this->w3c = isset( $languages[ $this->locale ]['w3c'] ) ? $languages[ $this->locale ]['w3c'] : str_replace( '_', '-', $this->locale );
@@ -92,66 +221,74 @@
92 221 }
93 222 }
94 223
95 224 /**
96 - * Get the flag informations
97 - * 'url' => Flag url
98 - * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
99 - * 'width' => Optional, flag width in pixels
100 - * 'height' => Optional, flag height in pixels
225 + * Get the flag informations:
101 226 *
102 227 * @since 2.6
103 228 *
104 229 * @param string $code Flag code.
105 - * @return array Flag informations.
230 + * @return array {
231 + * Flag informations.
232 + *
233 + * @type string $url Flag url.
234 + * @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
235 + * @type int $width Optional, flag width in pixels.
236 + * @type int $height Optional, flag height in pixels.
237 + * }
106 238 */
107 239 public static function get_flag_informations( $code ) {
108 240 $flag = array( 'url' => '' );
109 241
110 - // Polylang builtin flags
242 + // Polylang builtin flags.
111 243 if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
112 - $flag['url'] = $_url = plugins_url( $file, POLYLANG_FILE );
244 + $flag['url'] = plugins_url( $file, POLYLANG_FILE );
245 +
246 + // If base64 encoded flags are preferred.
247 + if ( ! defined( 'PLL_ENCODED_FLAGS' ) || PLL_ENCODED_FLAGS ) {
248 + list( $flag['width'], $flag['height'] ) = getimagesize( POLYLANG_DIR . $file );
249 + $file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
250 + $flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
251 + }
113 252 }
114 253
115 254 /**
116 - * Filter flag informations
117 - * 'url' => Flag url
118 - * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
119 - * 'width' => Optional, flag width in pixels
120 - * 'height' => Optional, flag height in pixels
255 + * Filters flag informations:
121 256 *
122 257 * @since 2.4
123 258 *
124 - * @param array $flag Information about the flag
125 - * @param string $code Flag code
259 + * @param array $flag {
260 + * Information about the flag.
261 + *
262 + * @type string $url Flag url.
263 + * @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
264 + * @type int $width Optional, flag width in pixels.
265 + * @type int $height Optional, flag height in pixels.
266 + * }
267 + * @param string $code Flag code.
126 268 */
127 269 $flag = apply_filters( 'pll_flag', $flag, $code );
128 270
271 + $flag['url'] = esc_url_raw( $flag['url'] );
272 +
129 273 if ( empty( $flag['src'] ) ) {
130 - // If using predefined flags and base64 encoded flags are preferred
131 - if ( isset( $_url ) && $flag['url'] === $_url && ( ! defined( 'PLL_ENCODED_FLAGS' ) || PLL_ENCODED_FLAGS ) ) {
132 - list( $flag['width'], $flag['height'] ) = getimagesize( POLYLANG_DIR . $file );
133 - $file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
134 - $flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
135 - } else {
136 - $flag['src'] = esc_url( set_url_scheme( $flag['url'], 'relative' ) );
137 - }
274 + $flag['src'] = esc_url( set_url_scheme( $flag['url'], 'relative' ) );
138 275 }
139 276
140 - $flag['url'] = esc_url_raw( $flag['url'] );
141 -
142 277 return $flag;
143 278 }
144 279
145 280 /**
146 - * Sets flag_url and flag properties
281 + * Sets flag_url and flag properties.
147 282 *
148 283 * @since 1.2
284 + *
285 + * @return void
149 286 */
150 287 public function set_flag() {
151 288 $flags = array( 'flag' => self::get_flag_informations( $this->flag_code ) );
152 289
153 - // Custom flags ?
290 + // Custom flags?
154 291 $directories = array(
155 292 PLL_LOCAL_DIR,
156 293 get_stylesheet_directory() . '/polylang',
157 294 get_template_directory() . '/polylang',
@@ -164,18 +301,21 @@
164 301 }
165 302 }
166 303
167 304 /**
168 - * Filter the custom flag informations
169 - * 'url' => Flag url
170 - * 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
171 - * 'width' => Optional, flag width in pixels
172 - * 'height' => Optional, flag height in pixels
305 + * Filters the custom flag informations.
173 306 *
307 + * @param array $flag {
308 + * Information about the custom flag.
309 + *
310 + * @type string $url Flag url.
311 + * @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
312 + * @type int $width Optional, flag width in pixels.
313 + * @type int $height Optional, flag height in pixels.
314 + * }
315 + * @param string $code Flag code.
316 + *
174 317 * @since 2.4
175 - *
176 - * @param array $flag Information about the custom flag
177 - * @param string $code Flag code
178 318 */
179 319 $flags['custom_flag'] = apply_filters( 'pll_custom_flag', empty( $flags['custom_flag'] ) ? null : $flags['custom_flag'], $this->flag_code );
180 320
181 321 if ( ! empty( $flags['custom_flag']['url'] ) ) {
@@ -188,16 +328,16 @@
188 328 unset( $flags['custom_flag'] );
189 329 }
190 330
191 331 /**
192 - * Filter the flag title attribute
193 - * Defaults to the language name
332 + * Filters the flag title attribute.
333 + * Defaults to the language name.
194 334 *
195 335 * @since 0.7
196 336 *
197 - * @param string $title the flag title attribute
198 - * @param string $slug the language code
199 - * @param string $locale the language locale
337 + * @param string $title The flag title attribute.
338 + * @param string $slug The language code.
339 + * @param string $locale The language locale.
200 340 */
201 341 $title = apply_filters( 'pll_flag_title', $this->name, $this->slug, $this->locale );
202 342
203 343 foreach ( $flags as $key => $flag ) {
@@ -203,14 +343,14 @@
203 343 foreach ( $flags as $key => $flag ) {
204 344 $this->{$key . '_url'} = empty( $flag['url'] ) ? '' : $flag['url'];
205 345
206 346 /**
207 - * Filter the html markup of a flag
347 + * Filters the html markup of a flag.
208 348 *
209 349 * @since 1.0.2
210 350 *
211 - * @param string $flag html markup of the flag or empty string
212 - * @param string $slug language code
351 + * @param string $flag Html markup of the flag or empty string.
352 + * @param string $slug Language code.
213 353 */
214 354 $this->{$key} = apply_filters(
215 355 'pll_get_flag',
216 356 self::get_flag_html( $flag, $title, $this->name ),
@@ -219,24 +359,46 @@
219 359 }
220 360 }
221 361
222 362 /**
223 - * Get HTML code for flag
363 + * Get HTML code for flag.
224 364 *
225 365 * @since 2.7
226 366 *
227 - * @param array $flag flag properties: src, width and height
228 - * @param string $title optional title attribute
229 - * @param string $alt optional alt attribute
367 + * @param array $flag Flag properties: src, width and height.
368 + * @param string $title Optional title attribute.
369 + * @param string $alt Optional alt attribute.
370 + * @return string
230 371 */
231 372 public static function get_flag_html( $flag, $title = '', $alt = '' ) {
232 - return empty( $flag['src'] ) ? '' : sprintf(
373 + if ( empty( $flag['src'] ) ) {
374 + return '';
375 + }
376 +
377 + $alt_attr = empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) );
378 + $width_attr = empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] );
379 + $height_attr = empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] );
380 +
381 + $style = '';
382 + $sizes = array_intersect_key( $flag, array_flip( array( 'width', 'height' ) ) );
383 +
384 + if ( ! empty( $sizes ) ) {
385 + array_walk(
386 + $sizes,
387 + function ( &$value, $key ) {
388 + $value = sprintf( '%s: %dpx;', esc_attr( $key ), (int) $value );
389 + }
390 + );
391 + $style = sprintf( ' style="%s"', implode( ' ', $sizes ) );
392 + }
393 +
394 + return sprintf(
233 395 '<img src="%s"%s%s%s%s />',
234 396 $flag['src'],
235 - empty( $title ) ? '' : sprintf( ' title="%s"', esc_attr( $title ) ),
236 - empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) ),
237 - empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] ),
238 - empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] )
397 + $alt_attr,
398 + $width_attr,
399 + $height_attr,
400 + $style
239 401 );
240 402 }
241 403
242 404 /**
@@ -242,8 +404,10 @@
242 404 /**
243 405 * Returns the html of the custom flag if any, or the default flag otherwise.
244 406 *
245 407 * @since 2.8
408 + *
409 + * @return string
246 410 */
247 411 public function get_display_flag() {
248 412 return empty( $this->custom_flag ) ? $this->flag : $this->custom_flag;
249 413 }
@@ -251,30 +415,35 @@
251 415 /**
252 416 * Returns the url of the custom flag if any, or the default flag otherwise.
253 417 *
254 418 * @since 2.8
419 + *
420 + * @return string
255 421 */
256 422 public function get_display_flag_url() {
257 - return empty( $this->custom_flag_url ) ? $this->flag : $this->custom_flag_url;
423 + return empty( $this->custom_flag_url ) ? $this->flag_url : $this->custom_flag_url;
258 424 }
259 425
260 426 /**
261 - * Updates post and term count
427 + * Updates post and term count.
262 428 *
263 429 * @since 1.2
430 + *
431 + * @return void
264 432 */
265 433 public function update_count() {
266 - wp_update_term_count( $this->term_taxonomy_id, 'language' ); // posts count
267 - wp_update_term_count( $this->tl_term_taxonomy_id, 'term_language' ); // terms count
434 + wp_update_term_count( $this->term_taxonomy_id, 'language' ); // Posts count.
435 + wp_update_term_count( $this->tl_term_taxonomy_id, 'term_language' ); // Terms count.
268 436 }
269 437
270 438 /**
271 - * Set home_url and search_url properties
439 + * Set home_url and search_url properties.
272 440 *
273 441 * @since 1.3
274 442 *
275 - * @param string $search_url
276 - * @param string $home_url
443 + * @param string $search_url Home url to use in search forms.
444 + * @param string $home_url Home url.
445 + * @return void
277 446 */
278 447 public function set_home_url( $search_url, $home_url ) {
279 448 $this->search_url = $search_url;
280 449 $this->home_url = $home_url;
@@ -280,13 +449,15 @@
280 449 $this->home_url = $home_url;
281 450 }
282 451
283 452 /**
284 - * Sets the scheme of the home url and the flag urls
453 + * Sets the scheme of the home url and the flag urls.
285 454 *
286 455 * This can't be cached across pages.
287 456 *
288 457 * @since 2.8
458 + *
459 + * @return void
289 460 */
290 461 public function set_url_scheme() {
291 462 $this->home_url = set_url_scheme( $this->home_url );
292 463 $this->search_url = set_url_scheme( $this->search_url );
@@ -298,14 +469,14 @@
298 469 }
299 470 }
300 471
301 472 /**
302 - * Returns the language locale
303 - * Converts WP locales to W3C valid locales for display
473 + * Returns the language locale.
474 + * Converts WP locales to W3C valid locales for display.
304 475 *
305 476 * @since 1.8
306 477 *
307 - * @param string $filter either 'display' or 'raw', defaults to raw
478 + * @param string $filter Either 'display' or 'raw', defaults to raw.
308 479 * @return string
309 480 */
310 481 public function get_locale( $filter = 'raw' ) {
311 482 return 'display' === $filter ? $this->w3c : $this->locale;