PluginProbe
Polylang / trunk
Polylang vtrunk
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 | src/language.php +115 -46 3.8.8 → trunk View file →
@@ -22,9 +22,9 @@
22 22 * name: non-empty-string,
23 23 * slug: non-empty-string,
24 24 * locale: non-empty-string,
25 25 * w3c: non-empty-string,
26 - * flag_code: non-empty-string,
26 + * flag_code: string,
27 27 * term_group: int,
28 28 * is_rtl: int<0, 1>,
29 29 * facebook?: string,
30 30 * home_url: non-empty-string,
@@ -29,17 +29,18 @@
29 29 * facebook?: string,
30 30 * home_url: non-empty-string,
31 31 * search_url: non-empty-string,
32 32 * host: non-empty-string,
33 - * flag_url: non-empty-string,
34 - * flag: non-empty-string,
33 + * flag_url: string,
34 + * flag: string,
35 35 * custom_flag_url?: string,
36 36 * custom_flag?: string,
37 - * page_on_front: int<0, max>,
38 - * page_for_posts: int<0, max>,
39 - * active: bool,
37 + * page_on_front?: int<0, max>,
38 + * page_for_posts?: int<0, max>,
39 + * active?: bool,
40 40 * fallbacks?: array<non-empty-string>,
41 - * is_default: bool
41 + * is_default: bool,
42 + * admin_flag: array{'aria-hidden': non-empty-string, '': non-empty-string}
42 43 * }
43 44 */
44 45 class PLL_Language extends PLL_Language_Deprecated {
45 46
@@ -110,9 +111,9 @@
110 111 * Facebook locale.
111 112 *
112 113 * @var string
113 114 */
114 - public $facebook = '';
115 + public $facebook;
115 116
116 117 /**
117 118 * Home URL in this language.
118 119 *
@@ -146,9 +147,9 @@
146 147 * @var int
147 148 *
148 149 * @phpstan-var int<0, max>
149 150 */
150 - public $page_on_front = 0;
151 + public $page_on_front;
151 152
152 153 /**
153 154 * ID of the page for posts in this language (set from pll_additional_language_data filter).
154 155 *
@@ -155,16 +156,14 @@
155 156 * @var int
156 157 *
157 158 * @phpstan-var int<0, max>
158 159 */
159 - public $page_for_posts = 0;
160 + public $page_for_posts;
160 161
161 162 /**
162 163 * Code of the flag.
163 164 *
164 165 * @var string
165 - *
166 - * @phpstan-var non-empty-string
167 166 */
168 167 public $flag_code;
169 168
170 169 /**
@@ -170,10 +169,8 @@
170 169 /**
171 170 * URL of the flag. Always set to the main domain.
172 171 *
173 172 * @var string
174 - *
175 - * @phpstan-var non-empty-string
176 173 */
177 174 public $flag_url;
178 175
179 176 /**
@@ -179,10 +176,8 @@
179 176 /**
180 177 * HTML markup of the flag.
181 178 *
182 179 * @var string
183 - *
184 - * @phpstan-var non-empty-string
185 180 */
186 181 public $flag;
187 182
188 183 /**
@@ -189,9 +184,9 @@
189 184 * URL of the custom flag if it exists. Always set to the main domain.
190 185 *
191 186 * @var string
192 187 */
193 - public $custom_flag_url = '';
188 + public $custom_flag_url;
194 189
195 190 /**
196 191 * HTML markup of the custom flag if it exists.
197 192 *
@@ -196,9 +191,9 @@
196 191 * HTML markup of the custom flag if it exists.
197 192 *
198 193 * @var string
199 194 */
200 - public $custom_flag = '';
195 + public $custom_flag;
201 196
202 197 /**
203 198 * Whether or not the language is active. Default `true`.
204 199 *
@@ -203,9 +198,9 @@
203 198 * Whether or not the language is active. Default `true`.
204 199 *
205 200 * @var bool
206 201 */
207 - public $active = true;
202 + public $active;
208 203
209 204 /**
210 205 * List of WordPress language locales. Ex: array( 'en_GB' ).
211 206 *
@@ -212,9 +207,9 @@
212 207 * @var string[]
213 208 *
214 209 * @phpstan-var list<non-empty-string>
215 210 */
216 - public $fallbacks = array();
211 + public $fallbacks;
217 212
218 213 /**
219 214 * Whether the language is the default one.
220 215 *
@@ -256,8 +251,15 @@
256 251 */
257 252 protected $term_props;
258 253
259 254 /**
255 + * @var array
256 + *
257 + * @phpstan-var array{'aria-hidden': non-empty-string, '': non-empty-string}
258 + */
259 + private $admin_flag;
260 +
261 + /**
260 262 * Constructor: builds a language object given the corresponding data.
261 263 *
262 264 * @since 1.2
263 265 * @since 3.4 Only accepts one argument.
@@ -284,17 +286,30 @@
284 286 * @type string $custom_flag_url Optional. URL of the custom flag if it exists.
285 287 * @type string $custom_flag Optional. HTML markup of the custom flag if it exists.
286 288 * @type int $page_on_front Optional. ID of the page on front in this language.
287 289 * @type int $page_for_posts Optional. ID of the page for posts in this language.
288 - * @type bool $active Whether or not the language is active. Default `true`.
289 - * @type string[] $fallbacks List of WordPress language locales. Ex: array( 'en_GB' ).
290 + * @type bool $active Optional. Whether or not the language is active. Default `true`.
291 + * @type string[] $fallbacks Optional. List of WordPress language locales. Ex: array( 'en_GB' ).
290 292 * @type bool $is_default Whether or not the language is the default one.
293 + * @type array $admin_flag An array containing the keys `''` (empty string) for the "normal" flag, and
294 + * `'aria-hidden'` for the flag hidden to screen readers.
291 295 * }
292 296 *
293 297 * @phpstan-param LanguageData $language_data
294 298 */
295 299 public function __construct( array $language_data ) {
296 - foreach ( $language_data as $prop => $value ) {
300 + // Default values for optional params.
301 + $defaults = array(
302 + 'facebook' => '',
303 + 'page_on_front' => 0,
304 + 'page_for_posts' => 0,
305 + 'custom_flag_url' => '',
306 + 'custom_flag' => '',
307 + 'active' => true,
308 + 'fallbacks' => array(),
309 + );
310 +
311 + foreach ( array_merge( $defaults, $language_data ) as $prop => $value ) {
297 312 $this->$prop = $value;
298 313 }
299 314
300 315 $this->term_id = $this->term_props['language']['term_id'];
@@ -350,8 +365,20 @@
350 365 return $term_props;
351 366 }
352 367
353 368 /**
369 + * Returns a predefined HTML flag.
370 + *
371 + * @since 3.4
372 + *
373 + * @param string $flag_code Flag code to render.
374 + * @return string HTML code for the flag.
375 + */
376 + public static function get_predefined_flag( $flag_code ) {
377 + return self::get_flag_html( self::get_flag_information( $flag_code ) );
378 + }
379 +
380 + /**
354 381 * Returns the flag information.
355 382 *
356 383 * @since 2.6
357 384 *
@@ -377,20 +404,29 @@
377 404 'url' => '',
378 405 'src' => '',
379 406 );
380 407
408 + if ( empty( $code ) ) {
409 + return $default_flag;
410 + }
411 +
381 412 // Polylang builtin flags.
382 - if ( ! empty( $code ) && is_readable( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
383 - $default_flag['url'] = plugins_url( $file, POLYLANG_FILE );
413 + $file = "/vendor/wpsyntex/flags/{$code}.svg";
414 + if ( is_readable( POLYLANG_ROOT_DIR . $file ) ) {
415 + $default_flag = array(
416 + 'url' => plugins_url( $file, POLYLANG_ROOT_FILE ),
417 + 'src' => '',
418 + 'width' => 18,
419 + 'height' => 12,
420 + );
384 421
385 422 // If base64 encoded flags are preferred.
386 423 if ( pll_get_constant( 'PLL_ENCODED_FLAGS', true ) ) {
387 - $imagesize = getimagesize( POLYLANG_DIR . $file );
388 - if ( is_array( $imagesize ) ) {
389 - list( $default_flag['width'], $default_flag['height'] ) = $imagesize;
424 + $content = file_get_contents( POLYLANG_ROOT_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
425 +
426 + if ( ! empty( $content ) ) {
427 + $default_flag['src'] = 'data:image/svg+xml,' . self::encode_svg( $content );
390 428 }
391 - $file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
392 - $default_flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
393 429 }
394 430 }
395 431
396 432 /**
@@ -430,11 +466,11 @@
430 466 /**
431 467 * Returns HTML code for flag.
432 468 *
433 469 * @since 2.7
470 + * @since 3.9 Removed param `$title` and pass `$alt` as second param.
434 471 *
435 472 * @param array $flag Flag properties: src, width and height.
436 - * @param string $title Optional title attribute.
437 473 * @param string $alt Optional alt attribute.
438 474 * @return string
439 475 *
440 476 * @phpstan-param array{
@@ -442,13 +478,20 @@
442 478 * width?: int|numeric-string,
443 479 * height?: int|numeric-string
444 480 * } $flag
445 481 */
446 - public static function get_flag_html( $flag, $title = '', $alt = '' ) {
482 + public static function get_flag_html( $flag, $alt = '' ) {
447 483 if ( empty( $flag['src'] ) ) {
448 484 return '';
449 485 }
450 486
487 + // Backward compatibility.
488 + if ( func_num_args() > 2 ) {
489 + _deprecated_argument( __METHOD__ . '()', '3.9', 'The parameter `$title` has been removed and replaced by `$alt` in second position' );
490 + /** @var string */
491 + $alt = func_get_arg( 2 );
492 + }
493 +
451 494 $alt_attr = empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) );
452 495 $width_attr = empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] );
453 496 $height_attr = empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] );
454 497
@@ -475,8 +518,26 @@
475 518 );
476 519 }
477 520
478 521 /**
522 + * Returns the language flag or the language slug if there is no flag.
523 + *
524 + * @since 3.9
525 + *
526 + * @param string $mode Optional. Allows to modify the markup depending on how the flag is used. Possible values are:
527 + * - Empty string: the flag can be seen by screen readers,
528 + * - `aria-hidden`: the flag is hidden from screen readers: it is preceded or followed by a
529 + * text (language name for example) that would make the information redundant.
530 + * Default is an empty string.
531 + * @return string
532 + *
533 + * @phpstan-param ''|'aria-hidden' $mode
534 + */
535 + public function get_admin_flag( string $mode = '' ): string {
536 + return $this->admin_flag[ $mode ];
537 + }
538 +
539 + /**
479 540 * Returns the html of the custom flag if any, or the default flag otherwise.
480 541 *
481 542 * @since 2.8
482 543 * @since 3.5.3 Added the `$alt` parameter.
@@ -560,8 +621,9 @@
560 621 * @phpstan-return LanguageData
561 622 */
562 623 public function to_array( $context = 'display' ) {
563 624 $language = get_object_vars( $this );
625 + unset( $language['admin_flag'] );
564 626
565 627 if ( 'db' !== $context ) {
566 628 $language['home_url'] = $this->get_home_url();
567 629 $language['search_url'] = $this->get_search_url();
@@ -582,22 +644,8 @@
582 644 return (object) $this->to_array();
583 645 }
584 646
585 647 /**
586 - * Returns a predefined HTML flag.
587 - *
588 - * @since 3.4
589 - *
590 - * @param string $flag_code Flag code to render.
591 - * @return string HTML code for the flag.
592 - */
593 - public static function get_predefined_flag( $flag_code ) {
594 - $flag = self::get_flag_information( $flag_code );
595 -
596 - return self::get_flag_html( $flag );
597 - }
598 -
599 - /**
600 648 * Returns language's home URL. Takes care to render it dynamically if no cache is allowed.
601 649 *
602 650 * @since 3.4
603 651 *
@@ -673,6 +721,27 @@
673 721 return $this->get_tax_prop( $matches['tax'], $matches['field'] );
674 722 }
675 723
676 724 return $this->$property ?? false;
725 + }
726 +
727 + /**
728 + * Prepares a SVG image for use in data uri.
729 + *
730 + * @see https://codepen.io/tigt/post/optimizing-svgs-in-data-uris.
731 + * @since 3.9
732 + *
733 + * @param string $svg A string representing an SVG image.
734 + * @return string Encode SVG.
735 + */
736 + protected static function encode_svg( string $svg ): string {
737 + $to_replace = array(
738 + '"' => "'",
739 + '<' => '%3C',
740 + '>' => '%3E',
741 + '#' => '%23',
742 + "\n" => '',
743 + "\r" => '',
744 + );
745 + return str_replace( array_keys( $to_replace ), array_values( $to_replace ), $svg );
677 746 }
678 747 }