Passed
Push — main ( 624711...00ee18 )
by Sammy
01:46
created

Lezer::l()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
/*
4
 * i18n class called Lezer, shorthand L
5
 * honnors Ludwik *Lejzer* Zamenhof (Polish: Ludwik Łazarz Zamenhof; 15 December [O.S. 3 December] 1859 – 14 April [O.S. 1 April] 1917),
6
 * a medical doctor, inventor, and writer; most widely known for creating Esperanto.
7
 *
8
 * also Lezer is dutch for Reader, and it sounds like LASER, which is kinda cool.
9
 */
10
namespace HexMakina\Lezer;
11
12
use HexMakina\LocalFS\FileSystem;
13
use HexMakina\Tempus\{Dato,DatoTempo,Tempo};
14
15
class Lezer extends \i18n
16
{
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 one_language()
28
    {
29
        $this->detect_language_files();
30
        $this->detect_language_env();
31
        $the_one_language = current(array_intersect($this->detect_language_files(), $this->detect_language_env()));
32
33
        if ($the_one_language) {
34
            $this->setForcedLang($the_one_language);
35
        }
36
37
        return $the_one_language;
38
    }
39
40
    public function detect_language_files()
41
    {
42
        $files = FileSystem::preg_scandir(dirname($this->filePath), '/.json$/');
43
        if (empty($files)) {
44
            return [];
45
        }
46
47
        $files = implode('', $files);
48
        $res = preg_match_all('/([a-z]{3})\.json/', $files, $m);
49
        if ($res) { // false or 0 is none found
50
            $this->detected_language_files = $m[1];
51
        }
52
        return $this->detected_language_files;
53
    }
54
55
  /**
56
   * getUserLangs()
57
   * Returns the user languages
58
   * Normally it returns an array like this:
59
   * 1. Forced language
60
   * 2. Language in $_GET['lang']
61
   * 3. Language in $_SESSION['lang']
62
   * 4. COOKIE
63
   * 5. Fallback language
64
   * Note: duplicate values are deleted.
65
   *
66
   * @return array with the user languages sorted by priority.
67
   */
68
    public function detect_language_env()
69
    {
70
        $userLangs = array();
71
72
        // 1. forced language
73
        if ($this->forcedLang != null) {
74
            $userLangs['forced'] = $this->forcedLang;
75
        }
76
77
        // 2. GET parameter 'lang'
78
        if (isset($_GET['lang']) && is_string($_GET['lang'])) {
79
            $userLangs['get'] = $_GET['lang'];
80
        }
81
82
        // 3. SESSION parameter 'lang'
83
        if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) {
84
            $userLangs['session'] = $_SESSION['lang'];
85
        }
86
87
        // 4. COOKIES
88
        if (isset($_COOKIE['lang']) && is_string($_COOKIE['lang'])) {
89
            $userLangs['cookie'] = $_COOKIE['lang'];
90
        }
91
92
        // Lowest priority: fallback
93
        $userLangs['fallback'] = $this->fallbackLang;
94
        // remove duplicate elements
95
        $userLangs = array_unique($userLangs);
96
97
        // remove illegal userLangs
98
        foreach ($userLangs as $key => $value) {
99
            // only allow a-z, A-Z and 0-9 and _ and -
100
            if (preg_match('/^[a-zA-Z0-9_-]*$/', $value) === 1) {
101
                $this->detected_language_env[$key] = $value;
102
            }
103
        }
104
105
        return $this->detected_language_env;
106
    }
107
108
109
    public function compileFunction()
110
    {
111
        return ''
112
        . "function " . $this->prefix . '($string, $args=NULL) {' . "\n"
113
        . '    if (!defined("' . $this->prefix . '::".$string))'
114
        . '       return $string;'
115
        . '    $return = constant("' . $this->prefix . '::".$string);' . "\n"
116
        . '    return $args ? vsprintf($return,$args) : $return;'
117
        . "\n}";
118
    }
119
120
    public function l($message, $context=[]) : string
121
    {
122
        return call_user_func($this->prefix, $message, $context);
123
    }
124
125
    public static function model_type_to_label($form_model)
126
    {
127
        return $this->l(sprintf('MODEL_%s_INSTANCE', get_class($form_model)::model_type()));
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
128
    }
129
    public static function field_name_to_label($form_model, $field_name)
130
    {
131
        return $this->l(sprintf('MODEL_%s_FIELD_%s', (get_class($form_model))::model_type(), $field_name));
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
132
    }
133
134
  // options['decimals'] = int
135
  // options['abbrev'] = mixed: key needs to be set
136
    public static function when($event, $options = [])
137
    {
138
        try {
139
            $amount_of_days = DatoTempo::days_diff(new \DateTime($event), new \DateTime());
140
        } catch (\Exception $e) {
141
            return __FUNCTION__ . ': error';
142
        }
143
144
        if ($amount_of_days === -1) {
145
            return $this->l('DATETIME_RANGE_YESTERDAY');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
146
        } elseif ($amount_of_days === 0) {
147
            return $this->l('DATETIME_RANGE_TODAY');
148
        } elseif ($amount_of_days === 1) {
149
            return $this->l('DATETIME_RANGE_TOMORROW');
150
        }
151
152
153
        $datetime_parts = [
154
        'y' => 'DATETIME_UNIT_YEAR',
155
        'm' => 'DATETIME_UNIT_MONTH',
156
        'w' => 'DATETIME_UNIT_WEEK',
157
        'd' => 'DATETIME_UNIT_DAY',
158
        'h' => 'DATETIME_UNIT_HOUR',
159
        'i' => 'DATETIME_UNIT_MINUTE',
160
        's' => 'DATETIME_UNIT_SECOND'
161
        ];
162
163
        $date_diff = DatoTempo::days_diff_in_parts(abs($amount_of_days));
164
        $ordering = [];
165
        foreach ($datetime_parts as $unit => $label) {
166
            if (!isset($date_diff[$unit])) {
167
                continue;
168
            }
169
170
            $qty = (int)$date_diff[$unit];
171
172
            if ($qty === 0) {
173
                continue;
174
            }
175
176
            if (isset($options['abbrev'])) {
177
                $label .= '_ABBREV';
178
            } elseif ($qty > 1) {
179
                $label .= '_PLURAL';
180
            }
181
182
            $ordering[$unit] = $qty . ' ' . L($label) . '.';
0 ignored issues
show
Bug introduced by
The function L was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

182
            $ordering[$unit] = $qty . ' ' . /** @scrutinizer ignore-call */ L($label) . '.';
Loading history...
183
        }
184
        $ret = (isset($amount_of_days) && $amount_of_days >= 0) ? L('DATETIME_RANGE_PREFIX_FUTURE') : L('DATETIME_RANGE_PREFIX_PAST');
185
        $ret .= ' ' . implode(' & ', array_slice($ordering, 0, 2));
186
187
        return $ret;
188
    }
189
190
    public static function time($time_string, $short = true)
191
    {
192
        if ($short === true) {
193
            $time_string = substr($time_string, 0, 5);
194
        }
195
        return $time_string;
196
    }
197
198
    public static function human_date($date_string, $short = true)
199
    {
200
        if ($date_string === '0000-00-00' || empty($date_string)) {
201
            return $this->l('MODEL_common_VALUE_EMPTY');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
202
        }
203
204
        if (preg_match('/^[0-9]{4}$/', $date_string) === 1) {
205
            return intval($date_string);
206
        }
207
208
        list($year, $month, $day) = explode('-', $date_string);
209
210
        $ret = intval($day) . ' ' . L("DATETIME_CALENDAR_MONTH_$month");
0 ignored issues
show
Bug introduced by
The function L was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

210
        $ret = intval($day) . ' ' . /** @scrutinizer ignore-call */ L("DATETIME_CALENDAR_MONTH_$month");
Loading history...
211
212
        if ($short === true && Dato::format(null, 'Y') === $year) {
213
            return $ret;
214
        } else {
215
            return "$ret $year";
216
        }
217
    }
218
219
    public static function human_month($date_string)
220
    {
221
        return $this->l('DATETIME_CALENDAR_MONTH_' . Dato::format($date_string, 'm'));
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
222
    }
223
224
    public static function human_day($date_string)
225
    {
226
        return $this->l('DATETIME_CALENDAR_DAY_' . Dato::format($date_string, 'N'));
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using $this inside a static method is generally not recommended and can lead to errors in newer PHP versions.
Loading history...
227
    }
228
229
    public static function human_seconds($seconds)
230
    {
231
        $hours = floor($seconds / 3600);
232
        $mins = floor(($seconds - $hours * 3600) / 60);
233
        $secs = floor($seconds % 60);
234
235
        $hours_format = '%dh %dm %ds';
236
        return sprintf($hours_format, $hours, $mins, $secs);
237
    }
238
}
239