at path:ROOT / clients / vendor / punic / punic / src / Misc.php
run:R W Run
DIR
2026-04-08 19:42:30
R W Run
DIR
2026-04-08 19:53:13
R W Run
126.16 KB
2026-04-08 19:35:40
R W Run
4.19 KB
2026-04-08 19:35:40
R W Run
8.96 KB
2026-04-08 19:35:41
R W Run
24.16 KB
2026-04-08 19:35:40
R W Run
2 KB
2026-04-08 19:35:42
R W Run
3.93 KB
2026-04-08 19:35:41
R W Run
12.53 KB
2026-04-08 19:35:40
R W Run
17.07 KB
2026-04-08 19:35:39
R W Run
2.3 KB
2026-04-08 19:35:42
R W Run
6.93 KB
2026-04-08 19:35:39
R W Run
20.49 KB
2026-04-08 19:35:40
R W Run
13.16 KB
2026-04-08 19:35:39
R W Run
error_log
📄Misc.php
1<?php
2
3namespace Punic;
4
5use Traversable;
6
7/**
8 * Various helper stuff.
9 */
10class Misc
11{
12 /**
13 * Concatenates a list of items returning a localized string using "and" as seperator.
14 *
15 * For instance, array(1, 2, 3) will result in '1, 2, and 3' for English or '1, 2 e 3' for Italian.
16 *
17 * @param array|\Traversable $list The list to concatenate
18 * @param string $width The preferred width ('' for default, or 'short' or 'narrow')
19 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
20 *
21 * @return string returns an empty string if $list is not an array of it it's empty, the joined items otherwise
22 */
23 public static function joinAnd($list, $width = '', $locale = '')
24 {
25 return static::joinInternal($list, 'standard', $width, $locale);
26 }
27
28 /**
29 * Concatenates a list of items returning a localized string using "or" as seperator.
30 *
31 * For instance, array(1, 2, 3) will result in '1, 2, or 3' for English or '1, 2 o 3' for Italian.
32 *
33 * @param array|\Traversable $list The list to concatenate
34 * @param string $width The preferred width ('' for default, or 'short' or 'narrow')
35 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
36 *
37 * @return string returns an empty string if $list is not an array of it it's empty, the joined items otherwise
38 */
39 public static function joinOr($list, $width = '', $locale = '')
40 {
41 return static::joinInternal($list, 'or', $width, $locale);
42 }
43
44 /**
45 * Concatenates a list of unit items returning a localized string.
46 *
47 * For instance, array('3 ft', '2 in') will result in '3 ft, 2 in'.
48 *
49 * @param array|\Traversable $list The list to concatenate
50 * @param string $width The preferred width ('' for default, or 'short' or 'narrow')
51 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
52 *
53 * @return string returns an empty string if $list is not an array of it it's empty, the joined items otherwise
54 */
55 public static function joinUnits($list, $width = '', $locale = '')
56 {
57 return static::joinInternal($list, 'unit', $width, $locale);
58 }
59
60 /**
61 * Fix the case of a string.
62 *
63 * @param string $string The string whose case needs to be fixed
64 * @param string $case How to fix case. Allowed values:
65 * <li>`'titlecase-words'` all words in the phrase should be title case</li>
66 * <li>`'titlecase-firstword'` the first word should be title case</li>
67 * <li>`'lowercase-words'` all words in the phrase should be lower case</li>
68 * </ul>
69 *
70 * @return string
71 *
72 * @see http://cldr.unicode.org/development/development-process/design-proposals/consistent-casing
73 */
74 public static function fixCase($string, $case)
75 {
76 $result = $string;
77 if (is_string($string) && is_string($case) && $string !== '') {
78 switch ($case) {
79 case 'titlecase-words':
80 if (function_exists('mb_strtoupper') && (@preg_match('/\pL/u', 'a'))) {
81 $result = preg_replace_callback('/\\pL+/u', function ($m) {
82 $s = $m[0];
83 $l = mb_strlen($s, 'UTF-8');
84 if ($l === 1) {
85 $s = mb_strtoupper($s, 'UTF-8');
86 } else {
87 $s = mb_strtoupper(mb_substr($s, 0, 1, 'UTF-8'), 'UTF-8').mb_substr($s, 1, $l - 1, 'UTF-8');
88 }
89
90 return $s;
91 }, $string);
92 }
93 break;
94 case 'titlecase-firstword':
95 if (function_exists('mb_strlen')) {
96 $l = mb_strlen($string, 'UTF-8');
97 if ($l === 1) {
98 $result = mb_strtoupper($string, 'UTF-8');
99 } elseif ($l > 1) {
100 $result = mb_strtoupper(mb_substr($string, 0, 1, 'UTF-8'), 'UTF-8').mb_substr($string, 1, $l - 1, 'UTF-8');
101 }
102 }
103 break;
104 case 'lowercase-words':
105 if (function_exists('mb_strtolower')) {
106 $result = mb_strtolower($string, 'UTF-8');
107 }
108 break;
109 }
110 }
111
112 return $result;
113 }
114
115 /**
116 * Parse the browser HTTP_ACCEPT_LANGUAGE header and return the found locales, sorted in descending order by the quality values.
117 *
118 * @param bool $ignoreCache Set to true if you want to ignore the cache
119 *
120 * @return array Array keys are the found locales, array values are the relative quality value (from 0 to 1)
121 */
122 public static function getBrowserLocales($ignoreCache = false)
123 {
124 static $result;
125 if (!isset($result) || $ignoreCache) {
126 $httpAcceptLanguages = @getenv('HTTP_ACCEPT_LANGUAGE');
127 if ((!is_string($httpAcceptLanguages)) || (strlen($httpAcceptLanguages) === 0)) {
128 if (isset($_SERVER) && is_array($_SERVER) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
129 $httpAcceptLanguages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
130 }
131 }
132 $result = self::parseHttpAcceptLanguage($httpAcceptLanguages);
133 }
134
135 return $result;
136 }
137
138 /**
139 * Parse the value of an HTTP_ACCEPT_LANGUAGE header and return the found locales, sorted in descending order by the quality values.
140 *
141 * @param string $httpAcceptLanguages
142 *
143 * @return array Array keys are the found locales, array values are the relative quality value (from 0 to 1)
144 */
145 public static function parseHttpAcceptLanguage($httpAcceptLanguages)
146 {
147 $result = array();
148 if (is_string($httpAcceptLanguages) && $httpAcceptLanguages !== '') {
149 foreach (explode(',', $httpAcceptLanguages) as $httpAcceptLanguage) {
150 if (preg_match('/^([a-z]{2,3}(?:[_\\-][a-z]+)*)(?:\\s*;(?:\\s*q(?:\\s*=(?:\\s*([\\d.]+))?)?)?)?$/', strtolower(trim($httpAcceptLanguage, " \t")), $m)) {
151 if (count($m) > 2) {
152 if (strpos($m[2], '.') === 0) {
153 $m[2] = '0'.$m[2];
154 }
155 if (preg_match('/^[01](\\.\\d*)?$/', $m[2])) {
156 $quality = round(@(float) $m[2], 4);
157 } else {
158 $quality = -1;
159 }
160 } else {
161 $quality = 1;
162 }
163 if (($quality >= 0) && ($quality <= 1)) {
164 $found = array();
165 $chunks = explode('-', str_replace('_', '-', $m[1]));
166 $numChunks = count($chunks);
167 if ($numChunks === 1) {
168 $found[] = $m[1];
169 } else {
170 $base = $chunks[0];
171 for ($i = 1; $i < $numChunks; ++$i) {
172 if (strlen($chunks[$i]) === 4) {
173 $base .= '-'.ucfirst($chunks[$i]);
174 break;
175 }
176 }
177 for ($i = 1; $i < $numChunks; ++$i) {
178 if (preg_match('/^[a-z][a-z]$/', $chunks[$i])) {
179 $found[] = $base.'-'.strtoupper($chunks[$i]);
180 } elseif (preg_match('/^\\d{3}$/', $chunks[$i])) {
181 $found[] = $base.'-'.$chunks[$i];
182 }
183 }
184 if (empty($found)) {
185 $found[] = $base;
186 }
187 }
188 foreach ($found as $f) {
189 if (isset($result[$f])) {
190 if ($result[$f] < $quality) {
191 $result[$f] = $quality;
192 }
193 } else {
194 $result[$f] = $quality;
195 }
196 }
197 }
198 }
199 }
200 }
201 arsort($result, SORT_NUMERIC);
202
203 return $result;
204 }
205
206 /**
207 * Retrieve the character order (right-to-left or left-to-right).
208 *
209 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
210 *
211 * @return string Return 'left-to-right' or 'right-to-left'
212 */
213 public static function getCharacterOrder($locale = '')
214 {
215 $data = Data::get('layout', $locale);
216
217 return $data['characterOrder'];
218 }
219
220 /**
221 * Retrieve the line order (top-to-bottom or bottom-to-top).
222 *
223 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
224 *
225 * @return string Return 'top-to-bottom' or 'bottom-to-top'
226 */
227 public static function getLineOrder($locale = '')
228 {
229 $data = Data::get('layout', $locale);
230
231 return $data['lineOrder'];
232 }
233
234 /**
235 * @deprecated use joinAnd($list, '', $locale)
236 *
237 * @param array|\Traversable $list
238 * @param string $locale
239 *
240 * @return string
241 */
242 public static function join($list, $locale = '')
243 {
244 return static::joinInternal($list, 'standard', '', $locale);
245 }
246
247 /**
248 * Concatenates a list of items returning a localized string.
249 *
250 * @param array|\Traversable $list The list to concatenate
251 * @param string $type The type of list; 'standard' (e.g. '1, 2, and 3'), 'or' ('1, 2, or 3') or 'unit' ('3 ft, 2 in').
252 * @param string $width The preferred width ('' for default, or 'short' or 'narrow')
253 * @param string $locale The locale to use. If empty we'll use the default locale set in \Punic\Data
254 *
255 * @return string returns an empty string if $list is not an array of it it's empty, the joined items otherwise
256 */
257 protected static function joinInternal($list, $type, $width, $locale)
258 {
259 $result = '';
260 if ($list instanceof Traversable) {
261 $list = iterator_to_array($list);
262 }
263 if (is_array($list)) {
264 switch ((string) $width) {
265 case 'narrow':
266 $suffixes = array('-narrow', '-short', '');
267 break;
268 case 'short':
269 $suffixes = array('-short', '-narrow', '');
270 break;
271 case '':
272 $suffixes = array('', '-short', '-narrow');
273 break;
274 default:
275 throw new \Punic\Exception\ValueNotInList($width, array('', 'short', 'narrow'));
276 }
277
278 $list = array_values($list);
279 $n = count($list);
280 switch ($n) {
281 case 0:
282 break;
283 case 1:
284 $result = (string) $list[0];
285 break;
286 default:
287 $allData = Data::get('listPatterns', $locale);
288 $data = null;
289 foreach ($suffixes as $suffix) {
290 $key = $type.$suffix;
291 if (isset($allData[$key])) {
292 $data = $allData[$key];
293 break;
294 }
295 }
296 if ($data === null) {
297 $types = array_unique(array_map(function ($key) { return strtok($key, '-'); }, array_keys($allData)));
298 throw new \Punic\Exception\ValueNotInList($type, $types);
299 }
300 if (isset($data[$n])) {
301 $result = vsprintf($data[$n], $list);
302 } else {
303 $result = sprintf($data['end'], $list[$n - 2], $list[$n - 1]);
304 if ($n > 2) {
305 for ($index = $n - 3; $index > 0; --$index) {
306 $result = sprintf($data['middle'], $list[$index], $result);
307 }
308 $result = sprintf($data['start'], $list[0], $result);
309 }
310 }
311 break;
312 }
313 }
314
315 return $result;
316 }
317}
318