PluginProbe
Polylang / 3.3
Polylang v3.3
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 / include / language.php

language.php in Polylang 3.3, at include/language.php

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