LanguageLoader::languages()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Language;
6
7
use Closure;
8
9
class LanguageLoader
10
{
11
    /**
12
     * The languages array.
13
     *
14
     * @var array
15
     */
16
    protected static $languages;
17
18
    /**
19
     * Get the language by it's ISO ISO 639-1 code.
20
     *
21
     * @param string $code
22
     * @param bool   $hydrate
23
     *
24
     * @throws \Rinvex\Language\LanguageLoaderException
25
     *
26
     * @return \Rinvex\Language\Language|array
27
     */
28
    public static function language($code, $hydrate = true)
29
    {
30
        $code = mb_strtolower($code);
31
32
        if (! isset(static::$languages)) {
33
            static::$languages = json_decode(static::getFile(__DIR__.'/../resources/languages.json'), true);
34
        }
35
36
        if (! isset(static::$languages[$code])) {
37
            throw LanguageLoaderException::invalidLanguage();
38
        }
39
40
        return $hydrate ? new Language(static::$languages[$code]) : static::$languages[$code];
41
    }
42
43
    /**
44
     * Get all languages.
45
     *
46
     * @param bool $hydrate
47
     *
48
     * @return array
49
     */
50
    public static function languages($hydrate = false)
51
    {
52
        if (! isset(static::$languages)) {
53
            static::$languages = json_decode(static::getFile(__DIR__.'/../resources/languages.json'), true);
54
        }
55
56
        return $hydrate ? array_map(function ($language) {
57
            return new Language($language);
58
        }, static::$languages) : static::$languages;
59
    }
60
61
    /**
62
     * Get all language scripts.
63
     *
64
     * @return array
65
     */
66
    public static function scripts()
67
    {
68
        if (! isset(static::$languages)) {
69
            static::$languages = json_decode(static::getFile(__DIR__.'/../resources/languages.json'), true);
70
        }
71
72
        return static::pluck(static::$languages, 'script.name', 'script.iso_15924');
73
    }
74
75
    /**
76
     * Get all language families.
77
     *
78
     * @return array
79
     */
80
    public static function families()
81
    {
82
        if (! isset(static::$languages)) {
83
            static::$languages = json_decode(static::getFile(__DIR__.'/../resources/languages.json'), true);
84
        }
85
86
        return static::pluck(static::$languages, 'family.name', 'family.iso_639_5');
87
    }
88
89
    /**
90
     * Filter items by the given key value pair.
91
     *
92
     * @param string $key
93
     * @param mixed  $operator
94
     * @param mixed  $value
95
     *
96
     * @return array
97
     */
98
    public static function where($key, $operator, $value = null)
99
    {
100
        if (func_num_args() === 2) {
101
            $value = $operator;
102
            $operator = '=';
103
        }
104
105
        if (! isset(static::$languages)) {
106
            static::$languages = json_decode(static::getFile(__DIR__.'/../resources/languages.json'), true);
107
        }
108
109
        return static::filter(static::$languages, static::operatorForWhere($key, $operator, $value));
110
    }
111
112
    /**
113
     * Get an operator checker callback.
114
     *
115
     * @param string $key
116
     * @param string $operator
117
     * @param mixed  $value
118
     *
119
     * @return \Closure
120
     */
121
    protected static function operatorForWhere($key, $operator, $value)
122
    {
123
        return function ($item) use ($key, $operator, $value) {
124
            $retrieved = static::get($item, $key);
125
126
            switch ($operator) {
127
                default:
128
                case '=':
129
                case '==':  return $retrieved === $value;
130
                case '!=':
131
                case '<>':  return $retrieved !== $value;
132
                case '<':   return $retrieved < $value;
133
                case '>':   return $retrieved > $value;
134
                case '<=':  return $retrieved <= $value;
135
                case '>=':  return $retrieved >= $value;
136
                case '===': return $retrieved === $value;
137
                case '!==': return $retrieved !== $value;
138
            }
139
        };
140
    }
141
142
    /**
143
     * Run a filter over each of the items.
144
     *
145
     * @param array         $items
146
     * @param callable|null $callback
147
     *
148
     * @return array
149
     */
150
    protected static function filter($items, callable $callback = null)
151
    {
152
        if ($callback) {
153
            return array_filter($items, $callback, ARRAY_FILTER_USE_BOTH);
154
        }
155
156
        return array_filter($items);
157
    }
158
159
    /**
160
     * Get an item from an array or object using "dot" notation.
161
     *
162
     * @param mixed        $target
163
     * @param string|array $key
164
     * @param mixed        $default
165
     *
166
     * @return mixed
167
     */
168
    protected static function get($target, $key, $default = null)
169
    {
170
        if (is_null($key)) {
171
            return $target;
172
        }
173
174
        $key = is_array($key) ? $key : explode('.', $key);
175
176
        while (($segment = array_shift($key)) !== null) {
177
            if ($segment === '*') {
178
                if (! is_array($target)) {
179
                    return $default instanceof Closure ? $default() : $default;
180
                }
181
182
                $result = static::pluck($target, $key);
183
184
                return in_array('*', $key) ? static::collapse($result) : $result;
185
            }
186
187
            if (is_array($target) && array_key_exists($segment, $target)) {
188
                $target = $target[$segment];
189
            } elseif (is_object($target) && isset($target->{$segment})) {
190
                $target = $target->{$segment};
191
            } else {
192
                return $default instanceof Closure ? $default() : $default;
193
            }
194
        }
195
196
        return $target;
197
    }
198
199
    /**
200
     * Pluck an array of values from an array.
201
     *
202
     * @param array             $array
203
     * @param string|array      $value
204
     * @param string|array|null $key
205
     *
206
     * @return array
207
     */
208
    protected static function pluck($array, $value, $key = null)
209
    {
210
        $results = [];
211
212
        $value = is_string($value) ? explode('.', $value) : $value;
213
214
        $key = is_null($key) || is_array($key) ? $key : explode('.', $key);
215
216
        foreach ($array as $item) {
217
            $itemValue = static::get($item, $value);
218
219
            // If the key is "null", we will just append the value to the array and keep
220
            // looping. Otherwise we will key the array using the value of the key we
221
            // received from the developer. Then we'll return the final array form.
222
            if (is_null($key)) {
223
                $results[] = $itemValue;
224
            } else {
225
                $itemKey = static::get($item, $key);
226
227
                $results[$itemKey] = $itemValue;
228
            }
229
        }
230
231
        return $results;
232
    }
233
234
    /**
235
     * Collapse an array of arrays into a single array.
236
     *
237
     * @param array $array
238
     *
239
     * @return array
240
     */
241
    protected static function collapse($array)
242
    {
243
        $results = [];
244
245
        foreach ($array as $values) {
246
            if (! is_array($values)) {
247
                continue;
248
            }
249
250
            $results = array_merge($results, $values);
251
        }
252
253
        return $results;
254
    }
255
256
    /**
257
     * Get contents of the given file path.
258
     *
259
     * @param string $filePath
260
     *
261
     * @throws \Rinvex\Language\LanguageLoaderException
262
     *
263
     * @return string
264
     */
265
    public static function getFile($filePath)
266
    {
267
        if (! file_exists($filePath)) {
268
            throw LanguageLoaderException::invalidLanguage();
269
        }
270
271
        return file_get_contents($filePath);
272
    }
273
}
274