Passed
Push — main ( c702a3...9b65d9 )
by Sammy
01:42
created

Lezer::month()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * i18n class called Lezer, shorthand L
5
 * honnors Ludwik *Lejzer* Zamenhof (Polish: Ludwik Łazarz Zamenhof;
6
 * 15 December [O.S. 3 December] 1859 – 14 April [O.S. 1 April] 1917),
7
 * a medical doctor, inventor, and writer; most widely known for creating Esperanto.
8
 *
9
 * also Lezer is dutch for Reader, and it sounds like LASER, which is kinda cool.
10
 */
11
namespace HexMakina\Lezer;
12
13
use HexMakina\LocalFS\FileSystem;
14
use HexMakina\Tempus\{Dato,DatoTempo,Tempo};
15
16
class Lezer extends \i18n
17
{
18
    private $detected_language_files = [];
19
    private $detected_language_env = [];
20
21
  // protected $basePath = 'locale';
22
  // protected $filePath = 'locale/{LANGUAGE}/user_interface.ini'; // uses gettext hierarchy
23
  // protected $cachePath = 'locale/cache/';
24
  // protected $fallbackLang = 'fra';  // uses ISO-639-3
25
    protected $currentLang = null;
26
27
    public function availableLanguage()
28
    {
29
        $the_one_language = current(array_intersect($this->detectLanguageFiles(), $this->detectLanguageEnv()));
30
31
        if ($the_one_language) {
32
            $this->setForcedLang($the_one_language);
33
        }
34
35
        return $the_one_language;
36
    }
37
38
    private function detectLanguageFiles()
39
    {
40
        $files = FileSystem::preg_scandir(dirname($this->filePath), '/.json$/');
41
        if (empty($files)) {
42
            return [];
43
        }
44
45
        $files = implode('', $files);
46
        $res = preg_match_all('/([a-z]{3})\.json/', $files, $m);
47
        if ($res) { // false or 0 is none found
48
            $this->detected_language_files = $m[1];
49
        }
50
        return $this->detected_language_files;
51
    }
52
53
  /**
54
   * getUserLangs()
55
   * Returns the user languages
56
   * Normally it returns an array like this:
57
   * 1. Forced language
58
   * 2. Language in $_GET['lang']
59
   * 3. Language in $_SESSION['lang']
60
   * 4. COOKIE
61
   * 5. Fallback language
62
   * Note: duplicate values are deleted.
63
   *
64
   * @return array with the user languages sorted by priority.
65
   */
66
    private function detectLanguageEnv()
67
    {
68
        $userLangs = array();
69
70
        // 1. forced language
71
        if ($this->forcedLang != null) {
72
            $userLangs['forced'] = $this->forcedLang;
73
        }
74
75
        // 2. GET parameter 'lang'
76
        if (isset($_GET['lang']) && is_string($_GET['lang'])) {
77
            $userLangs['get'] = $_GET['lang'];
78
        }
79
80
        // 3. SESSION parameter 'lang'
81
        if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) {
82
            $userLangs['session'] = $_SESSION['lang'];
83
        }
84
85
        // 4. COOKIES
86
        if (isset($_COOKIE['lang']) && is_string($_COOKIE['lang'])) {
87
            $userLangs['cookie'] = $_COOKIE['lang'];
88
        }
89
90
        // Lowest priority: fallback
91
        $userLangs['fallback'] = $this->fallbackLang;
92
        // remove duplicate elements
93
        $userLangs = array_unique($userLangs);
94
95
        // remove illegal userLangs
96
        foreach ($userLangs as $key => $value) {
97
            // only allow a-z, A-Z and 0-9 and _ and -
98
            if (preg_match('/^[a-zA-Z0-9_-]*$/', $value) === 1) {
99
                $this->detected_language_env[$key] = $value;
100
            }
101
        }
102
103
        return $this->detected_language_env;
104
    }
105
106
107
    public function compileFunction()
108
    {
109
        return ''
110
        . "function " . $this->prefix . '($string, $args=NULL) {' . "\n"
111
        . '    if (!defined("' . $this->prefix . '::".$string))'
112
        . '       return $string;'
113
        . '    $return = constant("' . $this->prefix . '::".$string);' . "\n"
114
        . '    return $args ? vsprintf($return,$args) : $return;'
115
        . "\n}";
116
    }
117
118
    public function l($message, $context = []): string
119
    {
120
        return call_user_func($this->prefix, $message, $context);
121
    }
122
123
124
  // options['decimals'] = int
125
  // options['abbrev'] = mixed: key needs to be set
126
    public function when($event, $options = [])
127
    {
128
        try {
129
            $amount_of_days = DatoTempo::days_diff(new \DateTime($event), new \DateTime());
130
        } catch (\Exception $e) {
131
            return __FUNCTION__ . ': error';
132
        }
133
134
        if ($amount_of_days === -1) {
135
            return $this->l('DATETIME_RANGE_YESTERDAY');
136
        } elseif ($amount_of_days === 0) {
137
            return $this->l('DATETIME_RANGE_TODAY');
138
        } elseif ($amount_of_days === 1) {
139
            return $this->l('DATETIME_RANGE_TOMORROW');
140
        }
141
142
143
        $datetime_parts = [
144
        'y' => 'DATETIME_UNIT_YEAR',
145
        'm' => 'DATETIME_UNIT_MONTH',
146
        'w' => 'DATETIME_UNIT_WEEK',
147
        'd' => 'DATETIME_UNIT_DAY',
148
        'h' => 'DATETIME_UNIT_HOUR',
149
        'i' => 'DATETIME_UNIT_MINUTE',
150
        's' => 'DATETIME_UNIT_SECOND'
151
        ];
152
153
        $date_diff = DatoTempo::days_diff_in_parts(abs($amount_of_days));
154
        $ordering = [];
155
        foreach ($datetime_parts as $unit => $label) {
156
            if (!isset($date_diff[$unit])) {
157
                continue;
158
            }
159
160
            $qty = (int)$date_diff[$unit];
161
162
            if ($qty === 0) {
163
                continue;
164
            }
165
166
            if (isset($options['abbrev'])) {
167
                $label .= '_ABBREV';
168
            } elseif ($qty > 1) {
169
                $label .= '_PLURAL';
170
            }
171
172
            $ordering[$unit] = $qty . ' ' . $this->l($label) . '.';
173
        }
174
        $ret = (isset($amount_of_days) && $amount_of_days >= 0)
175
          ? 'DATETIME_RANGE_PREFIX_FUTURE' : 'DATETIME_RANGE_PREFIX_PAST';
176
        $ret .= $this->l($ret) . ' ' . implode(' & ', array_slice($ordering, 0, 2));
177
178
        return $ret;
179
    }
180
181
    public function time($time_string, $short = true)
182
    {
183
        if ($short === true) {
184
            $time_string = substr($time_string, 0, 5);
185
        }
186
        return $time_string;
187
    }
188
189
    public function date($date_string, $short = true)
190
    {
191
        if ($date_string === '0000-00-00' || empty($date_string)) {
192
            return $this->l('MODEL_common_VALUE_EMPTY');
193
        }
194
195
        if (preg_match('/^[0-9]{4}$/', $date_string) === 1) {
196
            return intval($date_string);
197
        }
198
199
        list($year, $month, $day) = explode('-', $date_string);
200
201
        $ret = intval($day) . ' ' . $this->l("DATETIME_CALENDAR_MONTH_$month");
202
203
        if ($short === true && Dato::format(null, 'Y') === $year) {
204
            return $ret;
205
        } else {
206
            return "$ret $year";
207
        }
208
    }
209
210
    public function month($date_string)
211
    {
212
        return $this->l('DATETIME_CALENDAR_MONTH_' . Dato::format($date_string, 'm'));
213
    }
214
215
    public function day($date_string)
216
    {
217
        return $this->l('DATETIME_CALENDAR_DAY_' . Dato::format($date_string, 'N'));
218
    }
219
220
    public function seconds($seconds)
221
    {
222
        $hours = floor($seconds / 3600);
223
        $mins = floor(($seconds - $hours * 3600) / 60);
224
        $secs = floor($seconds % 60);
225
226
        $hours_format = '%dh %dm %ds';
227
        return sprintf($hours_format, $hours, $mins, $secs);
228
    }
229
}
230