|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace MintyPHP; |
| 4 | + |
| 5 | +class I18n |
| 6 | +{ |
| 7 | + private static $strings = []; |
| 8 | + |
| 9 | + public static $domain = 'default'; |
| 10 | + public static $locale = ''; // should be either: 'en', 'de', 'fr', 'nl' |
| 11 | + public static $defaultLocale = 'en'; |
| 12 | + |
| 13 | + public static $formats = [ |
| 14 | + 'currency' => [ |
| 15 | + 'en' => ['thousandSeparator' => ',', 'decimalSeparator' => '.'], |
| 16 | + 'de' => ['thousandSeparator' => '.', 'decimalSeparator' => ','], |
| 17 | + 'fr' => ['thousandSeparator' => '.', 'decimalSeparator' => ','], |
| 18 | + 'nl' => ['thousandSeparator' => '.', 'decimalSeparator' => ','], |
| 19 | + ], |
| 20 | + 'datetime' => [ |
| 21 | + 'en' => ['date' => 'm/d/Y', 'datetime' => 'm/d/Y H:i:s', 'time' => 'H:i:s'], |
| 22 | + 'de' => ['date' => 'd.m.Y', 'datetime' => 'd.m.Y H:i:s', 'time' => 'H:i:s'], |
| 23 | + 'fr' => ['date' => 'd-m-Y', 'datetime' => 'd-m-Y H:i:s', 'time' => 'H:i:s'], |
| 24 | + 'nl' => ['date' => 'd-m-Y', 'datetime' => 'd-m-Y H:i:s', 'time' => 'H:i:s'], |
| 25 | + ], |
| 26 | + 'weekDays' => [ |
| 27 | + 'en' => ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], |
| 28 | + 'de' => ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'], |
| 29 | + 'fr' => ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'], |
| 30 | + 'nl' => ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag', 'zondag'], |
| 31 | + ], |
| 32 | + 'monthNames' => [ |
| 33 | + 'en' => ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], |
| 34 | + 'de' => ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], |
| 35 | + 'fr' => ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], |
| 36 | + 'nl' => ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], |
| 37 | + ] |
| 38 | + |
| 39 | + ]; |
| 40 | + |
| 41 | + public static function price($price, $minDecimals = 2, $maxDecimals = 2): string |
| 42 | + { |
| 43 | + if ($price === null) return ''; |
| 44 | + return "€ " . self::currency($price, $minDecimals, $maxDecimals); |
| 45 | + } |
| 46 | + |
| 47 | + public static function currency($currency, $minDecimals = 2, $maxDecimals = 2): string |
| 48 | + { |
| 49 | + if ($currency === null) return ''; |
| 50 | + |
| 51 | + $formats = self::$formats['currency']; |
| 52 | + |
| 53 | + $number = rtrim(sprintf("%0.{$maxDecimals}F", $currency), '0'); |
| 54 | + $decimalPos = strpos($number, '.'); |
| 55 | + if ($decimalPos === false) { |
| 56 | + $number .= '.'; |
| 57 | + } |
| 58 | + list($whole, $fraction) = explode('.', $number); |
| 59 | + if ($number < 0) { |
| 60 | + $sign = '-'; |
| 61 | + $whole = -1 * (int)$whole; |
| 62 | + } else { |
| 63 | + $sign = ''; |
| 64 | + } |
| 65 | + $whole = (string) $whole; |
| 66 | + $format = $formats[self::$locale] ?? $formats[self::$defaultLocale]; |
| 67 | + $whole = strrev(implode($format['thousandSeparator'], str_split(strrev($whole), 3))); |
| 68 | + $fraction = str_pad($fraction, $minDecimals, '0'); |
| 69 | + return $sign . $whole . $format['decimalSeparator'] . $fraction; |
| 70 | + } |
| 71 | + |
| 72 | + public static function date($str): string |
| 73 | + { |
| 74 | + return $str ? self::formatDateTime('date', "$str") : ''; |
| 75 | + } |
| 76 | + |
| 77 | + public static function dateUtc($str): string |
| 78 | + { |
| 79 | + return $str ? self::formatDateTime('date', "$str UTC") : ''; |
| 80 | + } |
| 81 | + |
| 82 | + public static function duration(int $seconds, bool $trim = false): string |
| 83 | + { |
| 84 | + $hours = floor($seconds / 3600); |
| 85 | + $seconds -= $hours * 3600; |
| 86 | + $minutes = floor($seconds / 60); |
| 87 | + $seconds -= $minutes * 60; |
| 88 | + $formatted = sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds); |
| 89 | + if ($trim) { |
| 90 | + if (substr($formatted, 0, 3) == '00:') { |
| 91 | + $formatted = substr($formatted, 3); |
| 92 | + } |
| 93 | + } |
| 94 | + return $formatted; |
| 95 | + } |
| 96 | + |
| 97 | + public static function datetime($str): string |
| 98 | + { |
| 99 | + return $str ? self::formatDateTime('datetime', "$str") : ''; |
| 100 | + } |
| 101 | + |
| 102 | + public static function datetimeUtc($str): string |
| 103 | + { |
| 104 | + return $str ? self::formatDateTime('datetime', "$str UTC") : ''; |
| 105 | + } |
| 106 | + |
| 107 | + public static function time(int $hours, int $minutes, int $seconds = 0): string |
| 108 | + { |
| 109 | + return self::formatDateTime('time', date('Y-m-d ') . sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds)); |
| 110 | + } |
| 111 | + |
| 112 | + public static function timeUtc(int $hours, int $minutes, int $seconds = 0): string |
| 113 | + { |
| 114 | + return self::formatDateTime('time', date('Y-m-d ') . sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds) . 'UTC'); |
| 115 | + } |
| 116 | + |
| 117 | + public static function weekDay(int $dayOfWeek): string |
| 118 | + { |
| 119 | + $weekDays = self::$formats['weekDays']; |
| 120 | + return $weekDays[self::$locale][$dayOfWeek] ?? $weekDays[self::$defaultLocale][$dayOfWeek]; |
| 121 | + } |
| 122 | + |
| 123 | + public static function monthName(int $monthOfYear): string |
| 124 | + { |
| 125 | + $monthNames = self::$formats['monthNames']; |
| 126 | + return $monthNames[self::$locale][$monthOfYear - 1] ?? $monthNames[self::$defaultLocale][$monthOfYear - 1]; |
| 127 | + } |
| 128 | + |
| 129 | + private static function formatDateTime(string $type, string $str): string |
| 130 | + { |
| 131 | + $formats = self::$formats['datetime']; |
| 132 | + $format = $formats[self::$locale] ?? $formats[self::$defaultLocale]; |
| 133 | + return date($format[$type], strtotime($str)); |
| 134 | + } |
| 135 | + |
| 136 | + public static function datetimeShort($str): string |
| 137 | + { |
| 138 | + if (!$str) { |
| 139 | + return ''; |
| 140 | + } |
| 141 | + $sep = self::$formats['datetime']['en']['date'][1]; |
| 142 | + if (date('Y', strtotime($str)) != date('Y')) { |
| 143 | + return implode($sep, array_map('intval', explode($sep, self::formatDateTime('date', "$str")))); |
| 144 | + } |
| 145 | + if (time() - strtotime($str) < 24 * 60 * 60) { |
| 146 | + return implode(':', array_slice(explode(':', self::formatDateTime('time', "$str")), 0, 2)); |
| 147 | + } |
| 148 | + if (time() - strtotime($str) < 7 * 24 * 60 * 60) { |
| 149 | + $day = substr(self::weekDay(date('N', strtotime($str))), 0, 2); |
| 150 | + $time = implode(':', array_slice(explode(':', self::formatDateTime('time', "$str")), 0, 2)); |
| 151 | + return "$day $time"; |
| 152 | + } |
| 153 | + $day = substr(self::weekDay(date('N', strtotime($str))), 0, 2); |
| 154 | + $date = implode($sep, array_map('intval', array_slice(explode($sep, self::formatDateTime('date', "$str")), 0, 2))); |
| 155 | + return "$day $date"; |
| 156 | + } |
| 157 | + |
| 158 | + public static function translate(string $id) |
| 159 | + { |
| 160 | + // read from disk or cache |
| 161 | + if (!isset(self::$strings[self::$domain][self::$locale])) { |
| 162 | + // load from disk |
| 163 | + $filename = 'i18n/' . self::$domain . '_' . self::$locale . '.json'; |
| 164 | + if (file_exists($filename)) { |
| 165 | + self::$strings[self::$domain][self::$locale] = json_decode(file_get_contents($filename), true); |
| 166 | + } |
| 167 | + } |
| 168 | + // lookup id |
| 169 | + return self::$strings[self::$domain][self::$locale][$id] ?? $id; |
| 170 | + } |
| 171 | +} |
0 commit comments