Reader   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 90.63%

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 6
dl 0
loc 257
ccs 58
cts 64
cp 0.9063
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setTranslationsSheet() 0 6 1
A setLocale() 0 6 1
A scan() 0 8 1
A scanDirectory() 0 14 4
A scanVendorDirectory() 0 9 3
A loadTranslationsInDirectory() 0 12 3
A loadTranslations() 0 29 5
A fullKey() 0 7 2
A sourceFile() 0 4 1
A toRelative() 0 7 1
A requestedLocale() 0 8 2
A getLocaleFromDirectory() 0 4 1
A isVendorDirectory() 0 4 1
1
<?php
2
3
namespace Nikaia\TranslationSheet\Translation;
4
5
use Illuminate\Filesystem\Filesystem;
6
use Illuminate\Foundation\Application;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Collection;
9
use Nikaia\TranslationSheet\Sheet\TranslationsSheet;
10
11
class Reader
12
{
13
    /**
14
     * Translation items.
15
     *
16
     * @var \Illuminate\Support\Collection
17
     */
18
    protected $translations;
19
20
    /**
21
     * @var Application
22
     */
23
    protected $app;
24
25
    /**
26
     * @var \Illuminate\Filesystem\Filesystem
27
     */
28
    protected $files;
29
30
    /**
31
     * @var string specify locale that we need to scan.
32
     * Returns all if no locale specified.
33
     */
34
    private $locale;
35
36
    /**
37
     * @var TranslationsSheet
38
     */
39
    protected $translationSheet;
40
41 5
    /**
42
     * Reader.
43 5
     *
44 5
     * @param Application $app
45 5
     * @param Filesystem $files
46
     */
47
    public function __construct(Application $app, Filesystem $files)
48
    {
49
        $this->app = $app;
50
        $this->files = $files;
51
    }
52
53
    /**
54
     * Set the translation sheets for reader.
55
     *
56
     * @param TranslationsSheet $translationSheet
57
     * @return Reader
58
     */
59
    public function setTranslationsSheet(TranslationsSheet $translationSheet)
60
    {
61
        $this->translationSheet = $translationSheet;
62
63
        return $this;
64
    }
65
66
    /**
67 4
     * Set reader locale.
68
     *
69
     * @param $locale
70 4
     * @return $this
71
     */
72
    public function setLocale($locale)
73 4
    {
74
        $this->locale = $locale;
75 4
76
        return $this;
77
    }
78
79
    /**
80
     * Scan modules, app and overridden packages lang
81
     * and return all defined translations.
82
     *
83 4
     * @return Collection
84
     * @return array
85 4
     */
86 4
    public function scan()
87 4
    {
88
        $this->translations = new Collection;
89
90 4
        $this->scanDirectory($this->translationSheet->getPath());
91
92
        return $this->translations;
93 4
    }
94
95
    /**
96
     * Scan a directory.
97
     *
98
     * @param string $path to directory to scan
99
     */
100 4
    protected function scanDirectory($path)
101
    {
102 4
        foreach ($this->files->directories($path) as $directory) {
103 4
            if ($this->isVendorDirectory($directory)) {
104 4
                $this->scanVendorDirectory($directory);
105 4
            } else {
106
                $this->loadTranslationsInDirectory($directory, $this->getLocaleFromDirectory($directory), null);
107
            }
108 4
        }
109
110
        foreach ($this->files->files($path) as $file) {
111
            $this->loadTranslations($file->getBasename('.json'), '*', '*', $file);
112
        }
113
    }
114
115
    /**
116
     * Scan overridden packages lang.
117 4
     *
118
     * @param $vendorsDirectory
119 4
     */
120
    private function scanVendorDirectory($vendorsDirectory)
121
    {
122
        foreach ($this->files->directories($vendorsDirectory) as $vendorPath) {
123 4
            $namespace = basename($vendorPath);
124 4
            foreach ($this->files->directories($vendorPath) as $localePath) {
125 4
                $this->loadTranslationsInDirectory($localePath, basename($localePath), $namespace);
126 4
            }
127
        }
128 4
    }
129
130
    /**
131
     * Load all directory file translation (multiple group) into translations collection.
132
     *
133
     * @param $directory
134
     * @param $locale
135
     * @param $namespace
136
     */
137
    private function loadTranslationsInDirectory($directory, $locale, $namespace)
138 4
    {
139
        if (!$this->requestedLocale($locale)) {
140 4
            return;
141
        }
142 4
143
        foreach ($this->files->files($directory) as $file) {
144
            $info = pathinfo($file);
145
            $group = $info['filename'];
146
            $this->loadTranslations($locale, $group, $namespace, $file);
147 4
        }
148
    }
149
150
    /**
151 4
     * Load file translation (group) into translations collection.
152 4
     *
153 4
     * @param $locale
154 4
     * @param $group
155 4
     * @param $namespace
156 4
     * @param $file
157 4
     */
158 4
    private function loadTranslations($locale, $group, $namespace, $file)
159
    {
160 4
        if ($this->translationSheet->isExtraSheet()) {
161
            $translations = Arr::dot(json_decode(file_get_contents($file), true));
162 4
        } else {
163
            $translations = Arr::dot($this->app['translator']->getLoader()->load($locale, $group, $namespace));
164
        }
165
166
        foreach ($translations as $key => $value) {
167
168
            // Avoid break in this case :
169
            // Case of 'car.messages = []', the key 'messages' is specified in the translation
170
            // file but no items defined inside.
171
            if (is_array($value) && count($value) === 0) {
172 4
                continue;
173
            }
174
175 4
            $entity = new Item;
176 4
            $entity->namespace = $namespace;
177 4
            $entity->locale = $locale;
178
            $entity->group = $group;
179
            $entity->key = $key;
180
            $entity->full_key = $this->fullKey($namespace, $group, $key);
181
            $entity->value = (string)$value;
182
            $entity->source_file = $this->sourceFile($file);
183
184
            $this->translations->push($entity);
185
        }
186 4
    }
187
188 4
    /**
189
     * Return a full lang key.
190
     *
191
     * @param $namespace
192
     * @param $group
193
     * @param $key
194
     * @return string
195
     */
196
    private function fullKey($namespace, $group, $key)
197 4
    {
198
        return
199 4
            ($namespace ? "$namespace::" : '')
200 4
            . $group . '.'
201
            . $key;
202 4
    }
203
204
    /**
205
     * Return relative path of language file.
206
     *
207
     * @param $file
208
     * @return mixed
209
     */
210
    private function sourceFile($file)
211
    {
212 4
        return $this->toRelative(realpath($file));
213
    }
214 4
215 4
    /**
216
     * Return relative path related to base_path().
217
     *
218
     * @param $path
219
     * @return string
220
     */
221
    private function toRelative($path)
222
    {
223
        $relative = str_replace($this->translationSheet->getPath() . DIRECTORY_SEPARATOR, '', $path);
224
        $relative = str_replace('\\', '/', $relative);
225
226
        return $relative;
227
    }
228 4
229
    /**
230 4
     *  Determine if a found locale is requested for scanning.
231
     *  If $this->locale is not set, we assume that all the locales were requested.
232
     *
233
     * @param string $locale the locale to check
234
     * @return bool
235
     */
236
    private function requestedLocale($locale)
237
    {
238
        if (empty($this->locale)) {
239 5
            return true;
240
        }
241 5
242
        return $locale === $this->locale;
243
    }
244
245
    /**
246
     * Return locale from directory
247
     *  ie. resources/lang/en -> en.
248
     *
249
     * @param $directory
250
     * @return string
251
     */
252
    private function getLocaleFromDirectory($directory)
253
    {
254
        return basename($directory);
255
    }
256
257
    /**
258
     * Return true if it is the vendor directory.
259
     *
260
     * @param $directory
261
     * @return bool
262
     */
263
    private function isVendorDirectory($directory)
264
    {
265
        return basename($directory) === 'vendor';
266
    }
267
}
268