PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.6
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.6
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
← All changes | app/Services/Translations/TransStrings.php +133 -4 1.3.21 → 1.6.6 View file →
@@ -1,7 +1,10 @@
1 1 <?php
2 2
3 3 namespace FluentCart\App\Services\Translations;
4 +
5 +use FluentCart\App\Services\DateTime\DateFormatter;
6 +
4 7 class TransStrings
5 8 {
6 9 public static function getStrings(): array
7 10 {
@@ -89,10 +92,14 @@
89 92
90 93 public static function singleProductPageString(): array
91 94 {
92 95 return [
93 - 'In Stock' => _x('In Stock', 'Single Product Page', 'fluent-cart'),
94 - 'Out Of Stock' => _x('Out Of Stock', 'Single Product Page', 'fluent-cart'),
96 + 'In Stock' => _x('In Stock', 'Single Product Page', 'fluent-cart'),
97 + 'Out Of Stock' => _x('Out Of Stock', 'Single Product Page', 'fluent-cart'),
98 + 'Package' => _x('Package', 'Single Product Page', 'fluent-cart'),
99 + 'Dimensions' => _x('Dimensions', 'Single Product Page', 'fluent-cart'),
100 + 'Weight' => _x('Weight', 'Single Product Page', 'fluent-cart'),
101 + 'Shipping Weight' => _x('Shipping Weight', 'Single Product Page', 'fluent-cart'),
95 102 ];
96 103 }
97 104
98 105 public static function checkoutPageString()
@@ -295,11 +302,51 @@
295 302 ],
296 303 ];
297 304 }
298 305
299 - public static function dateTimeStrings(): array
306 + /**
307 + * Names and formats for every date FluentCart renders, PHP and JS alike.
308 + *
309 + * One filter covers the whole map: the month/weekday names, and the
310 + * formats derived from the store's WordPress date/time settings. Formats
311 + * are PHP date() strings -- the dialect Settings > General shows and
312 + * get_option() returns; the SPA payload converts them to Day.js tokens.
313 + *
314 + * The NAMES follow the same source setting as the formats. On 'wordpress'
315 + * they come from $wp_locale -- the exact arrays wp_date() renders with --
316 + * so the PHP side and the SPA cannot disagree about what August is called.
317 + * They used to come from FluentCart's own text domain while PHP rendered
318 + * through wp_date(), so one locale produced two answers:
319 + *
320 + * PHP wp_date('M') -> 'Aout' (WP core pack)
321 + * JS _x('Aug', 'monthsShort', ...) -> 'Aug' (untranslated)
322 + *
323 + * and fluent-cart ships only a .pot, so the JS side was English on any
324 + * store that had not sourced its own catalogue. $wp_locale also gets the
325 + * hard cases right for free: German abbreviations keep their trailing
326 + * period ('Aug.') and the four months German never abbreviates come back
327 + * in full ('Marz', 'Mai', 'Juni', 'Juli').
328 + *
329 + * On 'fluent_cart' the text-domain names stay, because that source exists
330 + * to reproduce what each side rendered before these settings landed.
331 + *
332 + * Cached per request AND per locale: DateFormatter reads this for every
333 + * date it renders, and rebuilding ~30 gettext lookups inside a table loop
334 + * is wasted work -- but the names now vary with the locale, so a request
335 + * that switches locale (switch_to_locale() in a per-recipient mailer, a
336 + * multilingual plugin) must not be served the first locale's month names.
337 + */
338 + public static function dateTimeStrings(bool $refresh = false): array
300 339 {
301 - return [
340 + static $cached = [];
341 +
342 + $locale = determine_locale();
343 +
344 + if (!$refresh && isset($cached[$locale])) {
345 + return $cached[$locale];
346 + }
347 +
348 + $strings = [
302 349 'weekdays' => array(
303 350 'sunday' => _x('Sunday', 'weekdays', 'fluent-cart'),
304 351 'monday' => _x('Monday', 'weekdays', 'fluent-cart'),
305 352 'tuesday' => _x('Tuesday', 'weekdays', 'fluent-cart'),
@@ -347,7 +394,89 @@
347 394 ),
348 395 'am' => __('AM', 'fluent-cart'),
349 396 'pm' => __('PM', 'fluent-cart'),
350 397 'numericSystem' => _x('0_1_2_3_4_5_6_7_8_9', 'numeric system - Sequence must need to maintained', 'fluent-cart'),
398 + 'formats' => DateFormatter::defaultFormats(),
399 + // The bundle carries its own legacy literals, which are not the same
400 + // as PHP's ('h:mm A' against 'h:i A' -- unpadded against padded). On
401 + // the FluentCart source each side must reproduce its OWN past output,
402 + // so the bundle needs to know which source is active rather than just
403 + // reading the converted formats above.
404 + 'formats_source' => DateFormatter::usesWordPressFormats() ? 'wordpress' : 'fluent_cart',
405 + // Read by the admin bundle and the customer dashboard, which pick a
406 + // Day.js timezone from this rather than always rendering in the
407 + // browser's. 'site' is only consulted when source is 'wordpress'.
408 + 'timezone' => array(
409 + 'source' => DateFormatter::usesWordPressTimezone() ? 'wordpress' : 'fluent_cart',
410 + 'site' => wp_timezone_string(),
411 + ),
351 412 ];
413 +
414 + if (DateFormatter::usesWordPressFormats()) {
415 + $strings = static::applyWordPressLocaleNames($strings);
416 + }
417 +
418 + return ($cached[$locale] = apply_filters('fluent_cart/date_time_strings', $strings));
419 + }
420 +
421 + /**
422 + * Swap the text-domain month/weekday names for WordPress core's own.
423 + *
424 + * $wp_locale is what wp_date() renders with, so taking the names from the
425 + * same object is what makes the PHP and JS sides agree by construction
426 + * rather than by two catalogues happening to match.
427 + *
428 + * The KEYS are left exactly as built above. The SPA reads these maps by
429 + * position (Object.values() against an English fallback list, see
430 + * localeNames() in utils/dateFormats.js), and other consumers read them by
431 + * key, so only the values may change here.
432 + *
433 + * Degrades to the text-domain names if $wp_locale is missing or shaped
434 + * unexpectedly -- this runs on every rendered date and must never fatal.
435 + *
436 + * @param array<string, mixed> $strings
437 + * @return array<string, mixed>
438 + */
439 + protected static function applyWordPressLocaleNames(array $strings): array
440 + {
441 + global $wp_locale;
442 +
443 + if (!($wp_locale instanceof \WP_Locale)) {
444 + return $strings;
445 + }
446 +
447 + // get_weekday() is 0-indexed from Sunday; get_month() takes '01'-'12'.
448 + $weekdayIndex = 0;
449 + foreach ($strings['weekdays'] as $key => $unused) {
450 + $name = $wp_locale->get_weekday($weekdayIndex);
451 + if ($name !== '') {
452 + $strings['weekdays'][$key] = $name;
453 + // The abbreviation is looked up BY the full name, so it has to
454 + // be resolved from $wp_locale's own name, not from our key.
455 + if (isset($strings['weekdaysShort'][substr($key, 0, 3)])) {
456 + $strings['weekdaysShort'][substr($key, 0, 3)] = $wp_locale->get_weekday_abbrev($name);
457 + }
458 + }
459 + $weekdayIndex++;
460 + }
461 +
462 + $monthIndex = 1;
463 + foreach ($strings['months'] as $key => $unused) {
464 + $name = $wp_locale->get_month(str_pad((string)$monthIndex, 2, '0', STR_PAD_LEFT));
465 + if ($name !== '') {
466 + $strings['months'][$key] = $name;
467 + $shortKey = strtolower(substr($key, 0, 3));
468 + if (isset($strings['monthsShort'][$shortKey])) {
469 + $strings['monthsShort'][$shortKey] = $wp_locale->get_month_abbrev($name);
470 + }
471 + }
472 + $monthIndex++;
473 + }
474 +
475 + $am = $wp_locale->get_meridiem('AM');
476 + $pm = $wp_locale->get_meridiem('PM');
477 + $strings['am'] = $am !== '' ? $am : $strings['am'];
478 + $strings['pm'] = $pm !== '' ? $pm : $strings['pm'];
479 +
480 + return $strings;
352 481 }
353 482 }