Writer::groupTranslationsByFile()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 2
cts 2
cp 1
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
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\Commands\Output;
10
use Nikaia\TranslationSheet\Sheet\TranslationsSheet;
11
use Nikaia\TranslationSheet\Spreadsheet;
12
use Nikaia\TranslationSheet\Util;
13
14
class Writer
15
{
16
    use Output;
17
18
    /** @var Collection */
19
    protected $translations;
20
21
    /** @var Spreadsheet */
22
    protected $spreadsheet;
23
24
    /** @var Filesystem */
25
    protected $files;
26
27
    /** @var Application */
28
    protected $app;
29 2
30
    /** @var TranslationsSheet */
31 2
    protected $translationSheet;
32 2
33 2
    public function __construct(Spreadsheet $spreadsheet, Filesystem $files, Application $app)
34
    {
35 2
        $this->spreadsheet = $spreadsheet;
36 2
        $this->files = $files;
37
        $this->app = $app;
38 2
39
        $this->nullOutput();
40 2
    }
41
42 2
    /**
43
     * Set the translation sheets for reader.
44
     *
45 2
     * @param TranslationsSheet $translationSheet
46
     * @return Writer
47
     */
48 2
    public function setTranslationsSheet(TranslationsSheet $translationSheet)
49
    {
50 2
        $this->translationSheet = $translationSheet;
51 2
52
        return $this;
53
    }
54 2
55 2
56
    public function setTranslations($translations)
57 2
    {
58
        $this->translations = $translations;
59 2
60
        return $this;
61 2
    }
62
63 2
    public function write()
64 1
    {
65
        $this
66
            ->groupTranslationsByFile()
67 2
            ->each(function ($items, $sourceFile) {
68 2
69
                if ($this->files->extension($sourceFile) === 'json') {
70 2
                    $this->writeJsonFile(
71
                        $this->translationSheet->getPath() . '/' . $sourceFile,
72
                        $items
73 2
                    );
74 2
                    return;
75
                }
76 2
77 2
                $this->writeFile(
78
                    $this->translationSheet->getPath() . '/' . $sourceFile,
79
                    $items
80 2
                );
81 2
            });
82 2
    }
83
84
    protected function writeFile($file, $items)
85 2
    {
86
        $this->output->writeln('    <comment>php</comment> ' . $file);
87
88 2
        $content = sprintf('<?php%s%sreturn %s;%s', PHP_EOL, PHP_EOL, Util::varExport($items), PHP_EOL);
89
90 2 View Code Duplication
        if (!$this->files->isDirectory($dir = dirname($file))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91 2
            $this->files->makeDirectory($dir, 0755, true);
92
        }
93 2
94 2
        $this->files->put($file, $content);
95
    }
96
97
    protected function writeJsonFile($file, $items)
98
    {
99
        $this->output->writeln('    <comment>json</comment> ' . $file);
100 2
101 View Code Duplication
        if (!$this->files->isDirectory($dir = dirname($file))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
            $this->files->makeDirectory($dir, 0755, true);
103
        }
104 2
        $this->files->put($file, json_encode($items, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL);
105 2
    }
106 2
107
    protected function groupTranslationsByFile()
108
    {
109 2
        $items = $this
110
            ->translations
111
            ->groupBy('sourceFile')
112
            ->map(function ($fileTranslations) {
113 2
                return $this->buildTranslationsForFile($fileTranslations);
114
            });
115
116
        // flatten does not seem to work for every case. !!! refactor !!!
117
        $result = [];
118
        foreach ($items as $subitems) {
119
            $result = array_merge($result, $subitems);
120
        }
121
122
        return new Collection($result);
123
    }
124
125
    protected function buildTranslationsForFile($fileTranslations)
126
    {
127
        $files = [];
128
        $locales = $this->spreadsheet->getLocales();
129
130
        foreach ($locales as $locale) {
131
            foreach ($fileTranslations as $translation) {
132
133
                // We will only write non empty translations
134
                // For instance, we have `app.title` that is the same for each locale,
135
                // We dont want to translate it to every locale, and prefer letting
136
                // Laravel default back to the default locale.
137
                if ($this->skipToDefault($translation, $locale)) {
138
                    continue;
139
                }
140
141
                $localeFile = $this->fileIsJson($translation['sourceFile']) ?
142
                    $locale . '.json' :
143
                    str_replace('{locale}/', $locale . '/', $translation['sourceFile']);
144
145
                if (empty($files[$localeFile])) {
146
                    $files[$localeFile] = [];
147
                }
148
149
                if ($this->fileIsJson($translation['sourceFile'])) {
150
                    $files[$localeFile][$translation['key']] = $translation[$locale];
151
                } else {
152
                    Arr::set($files[$localeFile], $translation['key'], $translation[$locale]);
153
                }
154
            }
155
        }
156
157
        return $files;
158
    }
159
160
    protected function skipToDefault($translation, $locale)
161
    {
162
        if (!isset($translation[$locale])) {
163
            return true;
164
        }
165
166
        return empty($translation[$locale]) && $this->fileIsJson($translation['sourceFile']);
167
    }
168
169
    protected function fileIsJson($sourceFile)
170
    {
171
        return $sourceFile === '{locale}.json';
172
    }
173
174
}
175