PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.7
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.7
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / vendor / wpfluent / framework / src / WPFluent / Support / Locale.php

Locale.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 2.7.7, at vendor/wpfluent/framework/src/WPFluent/Support/Locale.php

594 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Framework\Support;
4
5 class Locale
6 {
7 /**
8 * Locale identifier.
9 *
10 * @var string
11 */
12 protected $locale = 'en_US';
13
14 /**
15 * Locale info.
16 *
17 * @var \stdClass
18 */
19 protected $localeInfo = null;
20
21 /**
22 * English month names for keys.
23 * @var array
24 */
25 protected static $monthNames = [
26 'January', 'February', 'March', 'April', 'May', 'June', 'July',
27 'August', 'September', 'October', 'November', 'December',
28 ];
29
30 /**
31 * English weekday names for keys.
32 * @var array
33 */
34 protected static $weekdayNames = [
35 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
36 'Thursday', 'Friday', 'Saturday'
37 ];
38
39 /**
40 * Construct the class.
41 *
42 * @param int|string|null $userIdOrLocale
43 */
44 public function __construct($userIdOrLocale = null)
45 {
46 $this->localeInfo = $this->populateLocaleInfo($userIdOrLocale);
47 }
48
49 /**
50 * Load the locale info of a user.
51 *
52 * @param int|null $userIdOrLocale
53 * @return \stdClass
54 */
55 protected function populateLocaleInfo($userIdOrLocale = null)
56 {
57 // Defensive: if WP's i18n stack hasn't fully booted yet (plugin
58 // activation hooks, early CLI, pre-`init` code paths), fall back
59 // to en_US-style defaults instead of fataling on null wp_locale.
60 if (
61 !function_exists('switch_to_locale')
62 || !function_exists('get_user_locale')
63 || empty($GLOBALS['wp_locale'])
64 || !is_object($GLOBALS['wp_locale'])
65 ) {
66 return $this->buildFallbackLocaleInfo($userIdOrLocale);
67 }
68
69 if ($userIdOrLocale) {
70 if (is_int($userIdOrLocale)) {
71 $this->locale = get_user_locale($userIdOrLocale);
72 } else {
73 $this->locale = $userIdOrLocale;
74 }
75 } else {
76 $this->locale = get_user_locale(get_current_user_id());
77 }
78
79 $didSwitch = false;
80 $originalLocale = get_locale();
81
82 if ($originalLocale !== $this->locale) {
83 switch_to_locale($this->locale);
84 $didSwitch = true;
85 }
86
87 try {
88 $userLocale = new \stdClass();
89
90 $wpLocale = $GLOBALS['wp_locale'];
91
92 // Weekdays
93 $userLocale->weekday = $wpLocale->weekday;
94
95 // Rebuild array with weekday names as keys
96 $userLocale->weekday_initial = array_combine(
97 static::$weekdayNames, $wpLocale->weekday_initial
98 );
99
100 // Rebuild array with weekday names as keys
101 $userLocale->weekday_abbrev = array_combine(
102 static::$weekdayNames, $wpLocale->weekday_abbrev
103 );
104
105 // Months with exact keys (01-12)
106 $monthNumbers = array_keys($wpLocale->month);
107
108 $userLocale->month = array_combine(
109 $monthNumbers, $wpLocale->month
110 );
111
112 $userLocale->month_genitive = array_combine(
113 $monthNumbers, $wpLocale->month_genitive
114 );
115
116 // Rebuild month_abbrev with english month names as keys
117 $userLocale->month_abbrev = array_combine(
118 static::$monthNames, $wpLocale->month_abbrev
119 );
120
121 // Meridiem
122 $userLocale->meridiem = [
123 'am' => $wpLocale->meridiem['am'],
124 'pm' => $wpLocale->meridiem['pm'],
125 'AM' => $wpLocale->meridiem['AM'],
126 'PM' => $wpLocale->meridiem['PM'],
127 ];
128
129 // Text Direction and other locale-specific settings
130 $userLocale->text_direction = $wpLocale->text_direction;
131 $userLocale->number_format = $wpLocale->number_format;
132 $userLocale->list_item_separator = $wpLocale->list_item_separator;
133 $userLocale->word_count_type = $wpLocale->word_count_type;
134 $userLocale->start_day_of_week = get_option('start_of_week');
135
136 $userLocale->id = $this->locale;
137
138 $userLocale->mappings = [
139 // Add the mapping of month index to number
140 'month_index_to_num' => array_combine(
141 array_keys(static::$monthNames),
142 array_map('intval', $monthNumbers)
143 ),
144 // Add the english names
145 'month' => static::$monthNames,
146 'weekday' => static::$weekdayNames
147 ];
148
149 return $userLocale;
150 } finally {
151 if ($didSwitch) {
152 restore_previous_locale();
153 }
154 }
155 }
156
157 /**
158 * Build a minimal en_US-style locale info object for use when WP's
159 * i18n stack isn't available (plugin activation, early CLI, etc.).
160 * Matches the shape produced by the full populateLocaleInfo() so
161 * downstream callers don't need to know the difference.
162 *
163 * @param int|string|null $userIdOrLocale
164 * @return \stdClass
165 */
166 protected function buildFallbackLocaleInfo($userIdOrLocale = null)
167 {
168 $this->locale = (is_string($userIdOrLocale) && $userIdOrLocale !== '')
169 ? $userIdOrLocale
170 : 'en_US';
171
172 $monthNumbers = ['01','02','03','04','05','06','07','08','09','10','11','12'];
173
174 $userLocale = new \stdClass();
175 $userLocale->weekday = static::$weekdayNames;
176 $userLocale->weekday_initial = array_combine(
177 static::$weekdayNames, ['S', 'M', 'T', 'W', 'T', 'F', 'S']
178 );
179 $userLocale->weekday_abbrev = array_combine(
180 static::$weekdayNames, ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
181 );
182 $userLocale->month = array_combine($monthNumbers, static::$monthNames);
183 $userLocale->month_genitive = $userLocale->month;
184 $userLocale->month_abbrev = array_combine(
185 static::$monthNames,
186 ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
187 );
188 $userLocale->meridiem = ['am' => 'am', 'pm' => 'pm', 'AM' => 'AM', 'PM' => 'PM'];
189 $userLocale->text_direction = 'ltr';
190 $userLocale->number_format = ['decimal_point' => '.', 'thousands_sep' => ','];
191 $userLocale->list_item_separator = ', ';
192 $userLocale->word_count_type = 'words';
193 $userLocale->start_day_of_week = 1;
194 $userLocale->id = $this->locale;
195 $userLocale->mappings = [
196 'month_index_to_num' => array_combine(
197 array_keys(static::$monthNames),
198 range(1, 12)
199 ),
200 'month' => static::$monthNames,
201 'weekday' => static::$weekdayNames,
202 ];
203
204 return $userLocale;
205 }
206
207 /**
208 * Switch the locale for the user.
209 *
210 * @param string $locale
211 * @return void
212 */
213 public function switch($locale)
214 {
215 $original = get_locale();
216
217 $this->localeInfo = static::getInfo(
218 $this->locale = $locale
219 );
220
221 switch_to_locale($original);
222 }
223
224 /**
225 * Restore to the user's original locale.
226 *
227 * @return void
228 */
229 public function restore()
230 {
231 $original = get_locale();
232
233 $this->localeInfo = static::getInfo(
234 $this->locale = get_user_locale()
235 );
236
237 switch_to_locale($original);
238 }
239
240 /**
241 * Get specific weekday.
242 *
243 * @param int $day 0-6
244 * @return string
245 */
246 public function getWeekday($day)
247 {
248 if (is_string($day)) {
249 $day = Str::title($day);
250 if (strlen($day) === 3) {
251 $day = Arr::startsLike(static::$weekdayNames, $day);
252 $day = key($day);
253 } else {
254 $day = array_search($day, static::$weekdayNames);
255 }
256 }
257
258 // Validate numeric day is within valid range 0-6
259 if (!is_int($day) || $day < 0 || $day > 6) {
260 return '';
261 }
262
263 return $this->localeInfo->weekday[$day] ?? '';
264 }
265 /**
266 * Get specific weekday.
267 *
268 * @param int $day 0-6
269 * @return string
270 */
271 public function getWeekdayName($day)
272 {
273 return $this->getWeekday($day);
274 }
275
276 /**
277 * Get weekday initials (Short form).
278 *
279 * @param string $day
280 * @return string
281 */
282 public function getWeekdayInitial($day)
283 {
284 $day = $this->resolveWeekdayKey($day);
285
286 return $this->localeInfo->weekday_initial[$day] ?? '';
287 }
288
289 /**
290 * Get weekday abbr (Short form).
291 *
292 * @param string $day
293 * @return string
294 */
295 public function getWeekdayAbbrev($day)
296 {
297 $day = $this->resolveWeekdayKey($day);
298 return $this->localeInfo->weekday_abbrev[$day] ?? '';
299 }
300
301 /**
302 * Get specific month.
303 *
304 * @param int $month 0-11
305 * @return string
306 */
307 public function getMonth($month)
308 {
309 $month = $this->resolveMonthNumber($month);
310
311 if (!$month) {
312 return '';
313 }
314
315 $key = $month < 10 ? '0' . $month : (string) $month;
316
317 return $this->localeInfo->month[$key] ?? '';
318 }
319
320 /**
321 * Get specific month.
322 *
323 * @param int $month 0-11
324 * @return string
325 */
326 public function getMonthName($month)
327 {
328 return $this->getMonth($month);
329 }
330
331 /**
332 * Get specific month.
333 *
334 * @param int $month 01-12
335 * @return string
336 */
337 public function getShortMonthName($month)
338 {
339 return $this->getMonthAbbrev($month);
340 }
341
342 /**
343 * Get specific genitive month.
344 *
345 * @param int $month 01-12
346 * @return string
347 */
348 public function getMonthGenitive($month)
349 {
350 $month = $this->resolveMonthNumber($month);
351 return $this->localeInfo->month_genitive[$month] ?? '';
352 }
353
354 /**
355 * Get month abbr (Short form).
356 *
357 * @param string $month
358 * @return string
359 */
360 public function getMonthAbbrev($month)
361 {
362 $month = $this->resolveMonthName($month);
363 return $this->localeInfo->month_abbrev[$month] ?? '';
364 }
365
366 /**
367 * Get meridiem.
368 *
369 * @param string $period
370 * @return string
371 */
372 public function getMeridiem($period)
373 {
374 return $this->localeInfo->meridiem[$period] ?? '';
375 }
376
377 /**
378 * Get tetx direction.
379 *
380 * @return string
381 */
382 public function getTextDirection()
383 {
384 return $this->localeInfo->text_direction ?? 'ltr';
385 }
386
387 /**
388 * Get number format.
389 *
390 * @return string
391 */
392 public function getNumberFormat()
393 {
394 return $this->localeInfo->number_format ?? '';
395 }
396
397 /**
398 * Get list item separator.
399 *
400 * @return string
401 */
402 public function getListItemSeparator()
403 {
404 return $this->localeInfo->list_item_separator ?? '';
405 }
406
407 /**
408 * Get word count type.
409 *
410 * @return string
411 */
412 public function getWordCountType()
413 {
414 return $this->localeInfo->word_count_type ?? '';
415 }
416
417 /**
418 * Get start day number/name of the week
419 *
420 * @return int
421 */
422 public function getStartDayOfWeek($name = false)
423 {
424 $num = $this->localeInfo->startDayOfWeek ?? 1;
425
426 if ($name) {
427 return static::$weekdayNames[$num] ?? '';
428 }
429
430 return $num;
431 }
432
433 /**
434 * Get start day name of the week
435 *
436 * @return int
437 */
438 public function getStartDayNameOfWeek()
439 {
440 return $this->getStartDayOfWeek(true);
441 }
442
443 /**
444 * Checks if current locale is RTL.
445 *
446 * @since 3.0.0
447 * @return bool Whether locale is RTL.
448 */
449 public function isRtl()
450 {
451 return 'rtl' === $this->localeInfo->text_direction;
452 }
453
454 /**
455 * Resolve the month number.
456 *
457 * @param int|string $month
458 * @return int
459 */
460 public function resolveMonthNumber($month)
461 {
462 if (is_numeric($month)) {
463 $month = (int) $month;
464 $month = $this->localeInfo->mappings['month_index_to_num'][$month] ?? null;
465 } elseif (is_string($month)) {
466 if (strlen($month) === 3) {
467 $found = Arr::startsLike(
468 $this->localeInfo->mappings['month'], Str::title($month)
469 );
470 $month = $found ? key($found) + 1 : null;
471 } else {
472 $pos = array_search(Str::title($month), static::$monthNames);
473 $month = ($pos !== false) ? $pos + 1 : null;
474 }
475 }
476
477 if (!is_int($month) || $month < 1 || $month > 12) {
478 return false;
479 }
480
481 return $month;
482 }
483
484 /**
485 * Resolve the month name.
486 *
487 * @param int|string $month
488 * @return string
489 */
490 public function resolveMonthName($month)
491 {
492 if (is_numeric($month)) {
493 $month = $this->resolveMonthNumber($month);
494 $name = $this->localeInfo->mappings['month'][$month - 1];
495 } elseif (is_string($month)) {
496 $name = Str::title($month);
497 if (strlen($month) === 3) {
498 $month = Arr::startsLike(
499 $this->localeInfo->mappings['month'], Str::title($month)
500 );
501 $name = reset($month);
502 }
503 }
504
505 return $name;
506 }
507
508 /**
509 * Resolve the weekday key.
510 *
511 * @param int|string $day
512 * @return int
513 */
514 public function resolveWeekdayKey($day)
515 {
516 if (is_numeric($day)) {
517 $day = $this->localeInfo->mappings['weekday'][$day];
518 } elseif (is_string($day)) {
519 $day = Str::title($day);
520 if (strlen($day) === 3) {
521 $day = Arr::startsLike(
522 $this->localeInfo->mappings['weekday'], Str::title($day)
523 );
524 $day = reset($day);
525 }
526 }
527
528 return $day;
529 }
530
531 /**
532 * Dynamic property accessor.
533 *
534 * @param string $key
535 * @return mixed
536 */
537 public function __get($key)
538 {
539 return $this->localeInfo->{$key};
540 }
541
542 /**
543 * Get the info as array.
544 *
545 * @return array
546 */
547 public function toArray()
548 {
549 return (array) $this->localeInfo;
550 }
551
552 /**
553 * Get the locale identifier.
554 *
555 * @return string
556 */
557 public function toString()
558 {
559 return $this->locale;
560 }
561
562 /**
563 * Get the locale identifier.
564 *
565 * @return string
566 */
567 public function __toString()
568 {
569 return $this->toString();
570 }
571
572 /**
573 * Alternative constructor.
574 *
575 * @param int|null $userIdOrLocale
576 * @return $this
577 */
578 public static function init($userIdOrLocale = null)
579 {
580 return new static($userIdOrLocale);
581 }
582
583 /**
584 * Load the locale info of a user.
585 *
586 * @param int|null $userIdOrLocale
587 * @return \stdClass
588 */
589 public static function getInfo($userIdOrLocale = null)
590 {
591 return new Static($userIdOrLocale);
592 }
593 }
594