PluginProbe
Polylang / 3.8.9
Polylang v3.8.9
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 / src / format-util.php

format-util.php in Polylang 3.8.9, at src/format-util.php

108 lines 3.0 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 class to match values against a given format.
8 *
9 * @since 3.6
10 * @since 3.7 Moved from Polylang Pro to Polylang.
11 */
12 class PLL_Format_Util {
13 /**
14 * Cache for regex patterns.
15 * Useful when using `filter_list()` for example.
16 *
17 * @var string[] Formats as array keys, patterns as array values.
18 *
19 * @phpstan-var array<non-empty-string, non-empty-string>
20 */
21 private $patterns = array();
22
23 /**
24 * Filters the given list to return only the values whose the key or value matches the given format.
25 *
26 * @since 3.6
27 * @since 3.7 Only accepts arrays as first parameter.
28 *
29 * @param array $list A list with keys or values to match against `$format`.
30 * @param string $format A format, where `*` means "any characters" (`.*`), unless escaped.
31 * @param string $mode Optional. Tell if we should filter the keys or values from `$list`.
32 * Possible values are `'use_keys'` and `'use_values'`. Default is `'use_keys'`.
33 * @return array
34 *
35 * @template TArrayValue
36 * @phpstan-param ($mode is 'use_keys' ? array<string, TArrayValue> : array<string>) $list
37 * @phpstan-param 'use_keys'|'use_values' $mode
38 * @phpstan-return ($mode is 'use_keys' ? array<string, TArrayValue> : array<string>)
39 */
40 public function filter_list( array $list, string $format, string $mode = 'use_keys' ): array {
41 $filter = function ( $key ) use ( $format ) {
42 return $this->matches( (string) $key, $format );
43 };
44
45 if ( 'use_values' === $mode ) {
46 return array_filter( $list, $filter );
47 }
48
49 return array_filter( $list, $filter, ARRAY_FILTER_USE_KEY );
50 }
51
52 /**
53 * Tells if the given string matches the given format.
54 *
55 * @since 3.6
56 *
57 * @param string $key A string to test.
58 * @param string $format A format, where `*` means "any characters" (`.*`), unless escaped.
59 * @return bool
60 */
61 public function matches( string $key, string $format ): bool {
62 if ( ! $this->is_format( $format ) ) {
63 return $key === $format;
64 }
65
66 if ( '*' === $format ) {
67 return true;
68 }
69
70 if ( empty( $this->patterns[ $format ] ) ) {
71 $pattern = addcslashes( $format, '.+?[^]$(){}=!<>|:-#/' ); // Escape regular expression characters (list from `preg_quote()` but `*` and `\` are ignored).
72 $pattern = preg_replace(
73 array(
74 '/\\\(?!\*)/', // Escape `\` characters except if followed by `*`.
75 '/(?<!\\\)\*/', // Replace `*` characters by `.*` except if preceded by `\`.
76 ),
77 array( '\\', '.*' ),
78 $pattern
79 );
80
81 if ( empty( $pattern ) ) {
82 // Error.
83 return false;
84 }
85
86 $this->patterns[ $format ] = $pattern;
87 } else {
88 $pattern = $this->patterns[ $format ];
89 }
90
91 return (bool) preg_match( "/^{$pattern}$/", $key );
92 }
93
94 /**
95 * Tells if the given string is a format (that includes a `*`).
96 *
97 * @since 3.7
98 *
99 * @param string $format Format to test.
100 * @return bool
101 *
102 * @phpstan-assert-if-true non-empty-string $format
103 */
104 public function is_format( string $format ): bool {
105 return (bool) preg_match( '/(?<!\\\)\*/', $format ); // Match `*` characters unless if preceded by `\`.
106 }
107 }
108