Skip to content

Commit fd1d4ec

Browse files
committed
add support for vendor translations
1 parent b39a63e commit fd1d4ec

16 files changed

+202
-197
lines changed

database/factories/TranslationFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'language_id' => function () {
3232
return factory(Language::class)->create()->id;
3333
},
34-
'group' => null,
34+
'group' => 'single',
3535
'key' => $faker->word,
3636
'value' => $faker->sentence,
3737
];

resources/helpers.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function array_diff_assoc_recursive($arrayOne, $arrayTwo)
6363
}
6464
}
6565

66-
return ! isset($difference) ? false : $difference;
66+
return ! isset($difference) ? [] : $difference;
6767
}
6868
}
6969

resources/views/languages/translations/index.blade.php

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -47,46 +47,32 @@
4747

4848
<tbody>
4949
@foreach($translations as $type => $items)
50+
51+
@foreach($items as $group => $translations)
52+
53+
@foreach($translations as $key => $value)
54+
55+
@if(!is_array($value[config('app.locale')]))
56+
<tr>
57+
<td>{{ $group }}</td>
58+
<td>{{ $key }}</td>
59+
<td>{{ $value[config('app.locale')] }}</td>
60+
<td>
61+
<translation-input
62+
initial-translation="{{ $value[$language] }}"
63+
language="{{ $language }}"
64+
group="{{ $group }}"
65+
translation-key="{{ $key }}"
66+
route="{{ config('translation.ui_url') }}">
67+
</translation-input>
68+
</td>
69+
</tr>
70+
@endif
5071

51-
@if($type === 'group')
52-
@foreach($items as $group => $translations)
53-
@foreach($translations as $key => $value)
54-
@if(!is_array($value[config('app.locale')]))
55-
<tr>
56-
<td>{{ $group }}</td>
57-
<td>{{ $key }}</td>
58-
<td>{{ $value[config('app.locale')] }}</td>
59-
<td>
60-
<translation-input
61-
initial-translation="{{ $value[$language] }}"
62-
language="{{ $language }}"
63-
group="{{ $group }}"
64-
translation-key="{{ $key }}"
65-
route="{{ config('translation.ui_url') }}">
66-
</translation-input>
67-
</td>
68-
</tr>
69-
@endif
70-
@endforeach
71-
@endforeach
72-
@else
73-
@foreach($items as $key => $value)
74-
<tr>
75-
<td>{{ __('translation::translation.single') }}</td>
76-
<td>{{ $key }}</td>
77-
<td>{{ $value[config('app.locale')] }}</td>
78-
<td>
79-
<translation-input
80-
initial-translation="{{ $value[$language] }}"
81-
language="{{ $language }}"
82-
translation-key="{{ $key }}"
83-
route="{{ config('translation.ui_url') }}">
84-
</translation-input>
85-
</td>
86-
</tr>
8772
@endforeach
88-
@endif
89-
73+
74+
@endforeach
75+
9076
@endforeach
9177
</tbody>
9278

src/Console/Commands/AddTranslationKeyCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function handle()
4242
// exception is thrown
4343
if ($type === 'single') {
4444
try {
45-
$this->translation->addSingleTranslation($language, $key, $value);
45+
$this->translation->addSingleTranslation($language, 'single', $key, $value);
4646

4747
return $this->info(__('translation::translation.language_key_added'));
4848
} catch (\Exception $e) {

src/Console/Commands/ListMissingTranslationKeys.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,9 @@ public function handle()
5454
foreach ($types as $type => $keys) {
5555
// iterate over each of the keys
5656
foreach ($keys as $key => $value) {
57-
// at this point, if we have an array, we are confident of
58-
// an array file type as they will have an additional layer
59-
// due to the need to store the filename, so handle accordingly
60-
if (is_array($value)) {
61-
foreach ($value as $k => $v) {
62-
$rows[] = [$language, $type, $key, $k];
63-
}
64-
}
65-
// handle json file type
66-
else {
67-
$rows[] = [$language, $type, strtolower(__('translation::translation.single')), $key];
57+
// populate the array with the relevant data to fill the table
58+
foreach ($value as $k => $v) {
59+
$rows[] = [$language, $type, $key, $k];
6860
}
6961
}
7062
}

src/Console/Commands/SynchroniseTranslationsCommand.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ private function mergeLanguages($driver, $languages)
114114

115115
private function mergeTranslations($driver, $language, $translations)
116116
{
117-
$this->mergeGroupTranlsations($driver, $language, $translations['group']);
118-
$this->mergeSingleTranlsations($driver, $language, $translations['single']);
117+
$this->mergeGroupTranslations($driver, $language, $translations['group']);
118+
$this->mergeSingleTranslations($driver, $language, $translations['single']);
119119
}
120120

121-
private function mergeGroupTranlsations($driver, $language, $groups)
121+
private function mergeGroupTranslations($driver, $language, $groups)
122122
{
123123
foreach ($groups as $group => $translations) {
124124
foreach ($translations as $key => $value) {
@@ -130,10 +130,15 @@ private function mergeGroupTranlsations($driver, $language, $groups)
130130
}
131131
}
132132

133-
private function mergeSingleTranlsations($driver, $language, $translations)
133+
private function mergeSingleTranslations($driver, $language, $vendors)
134134
{
135-
foreach ($translations as $key => $value) {
136-
$driver->addSingleTranslation($language, $key, $value);
135+
foreach ($vendors as $vendor => $translations) {
136+
foreach ($translations as $key => $value) {
137+
if (is_array($value)) {
138+
continue;
139+
}
140+
$driver->addSingleTranslation($language, $vendor, $key, $value);
141+
}
137142
}
138143
}
139144
}

src/Drivers/Database.php

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct($sourceLanguage, $scanner)
2727
public function allLanguages()
2828
{
2929
return Language::all()->mapWithKeys(function ($language) {
30-
return [$language->language => $language->name];
30+
return [$language->language => $language->name ?: $language->language];
3131
});
3232
}
3333

@@ -126,7 +126,7 @@ public function addGroupTranslation($language, $key, $value = '')
126126
* @param string $value
127127
* @return void
128128
*/
129-
public function addSingleTranslation($language, $key, $value = '')
129+
public function addSingleTranslation($language, $vendor, $key, $value = '')
130130
{
131131
if (! $this->languageExists($language)) {
132132
$this->addLanguage($language);
@@ -136,7 +136,7 @@ public function addSingleTranslation($language, $key, $value = '')
136136
->first()
137137
->translations()
138138
->updateOrCreate([
139-
'group' => null,
139+
'group' => $vendor,
140140
'key' => $key,
141141
], [
142142
'key' => $key,
@@ -154,11 +154,24 @@ public function getSingleTranslationsFor($language)
154154
{
155155
$translations = $this->getLanguage($language)
156156
->translations()
157-
->whereNull('group')
158-
->get();
157+
->where('group', 'like', '%single')
158+
->orWhereNull('group')
159+
->get()
160+
->groupBy('group');
161+
162+
// if there is no group, this is a legacy translation so we need to
163+
// update to 'single'. We do this here so it only happens once.
164+
if ($this->hasLegacyGroups($translations->keys())) {
165+
TranslationModel::whereNull('group')->update(['group' => 'single']);
166+
// if any legacy groups exist, rerun the method so we get the
167+
// updated keys.
168+
return $this->getSingleTranslationsFor($language);
169+
}
159170

160-
return $translations->mapWithKeys(function ($translation) {
161-
return [$translation->key => $translation->value];
171+
return $translations->map(function ($translations, $group) use ($language) {
172+
return $translations->mapWithKeys(function ($translation) {
173+
return [$translation->key => $translation->value];
174+
});
162175
});
163176
}
164177

@@ -173,15 +186,14 @@ public function getGroupTranslationsFor($language)
173186
$translations = $this->getLanguage($language)
174187
->translations()
175188
->whereNotNull('group')
189+
->where('group', 'not like', '%single')
176190
->get()
177191
->groupBy('group');
178192

179193
return $translations->map(function ($translations) {
180194
return $translations->mapWithKeys(function ($translation) {
181195
return [$translation->key => $translation->value];
182196
});
183-
})->map(function ($translation) {
184-
return $translation->toArray();
185197
});
186198
}
187199

@@ -217,4 +229,19 @@ private function getLanguage($language)
217229
{
218230
return Language::where('language', $language)->first();
219231
}
232+
233+
/**
234+
* Determine if a set of single translations contains any legacy groups.
235+
* Previously, this was handled by setting the group value to NULL, now
236+
* we use 'single' to cater for vendor JSON language files.
237+
*
238+
* @param Collection $groups
239+
* @return boolean
240+
*/
241+
private function hasLegacyGroups($groups)
242+
{
243+
return $groups->filter(function ($key) {
244+
return $key === '';
245+
})->count() > 0;
246+
}
220247
}

src/Drivers/DriverInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function addGroupTranslation($language, $key, $value = '');
5959
* @param string $value
6060
* @return void
6161
*/
62-
public function addSingleTranslation($language, $key, $value = '');
62+
public function addSingleTranslation($language, $vendor, $key, $value = '');
6363

6464
/**
6565
* Get all of the single translations for a given language.

src/Drivers/File.php

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function addLanguage($language, $name = null)
105105

106106
$this->disk->makeDirectory("{$this->languageFilesPath}/$language");
107107
if (! $this->disk->exists("{$this->languageFilesPath}/{$language}.json")) {
108-
$this->saveSingleTranslations($language, []);
108+
$this->saveSingleTranslations($language, collect(['single' => collect()]));
109109
}
110110
}
111111

@@ -128,12 +128,12 @@ public function addGroupTranslation($language, $key, $value = '')
128128

129129
// does the group exist? If not, create it.
130130
if (! $translations->keys()->contains($group)) {
131-
$translations->put($group, []);
131+
$translations->put($group, collect());
132132
}
133133

134134
$values = $translations->get($group);
135135
$values[$key] = $value;
136-
$translations->put($group, $values);
136+
$translations->put($group, collect($values));
137137

138138
$this->saveGroupTranslations($language, $group, $translations->get($group));
139139
}
@@ -146,15 +146,15 @@ public function addGroupTranslation($language, $key, $value = '')
146146
* @param string $value
147147
* @return void
148148
*/
149-
public function addSingleTranslation($language, $key, $value = '')
149+
public function addSingleTranslation($language, $vendor, $key, $value = '')
150150
{
151151
if (! $this->languageExists($language)) {
152152
$this->addLanguage($language);
153153
}
154154

155155
$translations = $this->getSingleTranslationsFor($language);
156-
157-
$translations->put($key, $value);
156+
$translations->get($vendor) ?: $translations->put($vendor, collect());
157+
$translations->get($vendor)->put($key, $value);
158158

159159
$this->saveSingleTranslations($language, $translations);
160160
}
@@ -167,13 +167,16 @@ public function addSingleTranslation($language, $key, $value = '')
167167
*/
168168
public function getSingleTranslationsFor($language)
169169
{
170-
$singlePath = $this->languageFilesPath."/$language.json";
171-
172-
if ($this->disk->exists($singlePath)) {
173-
return new Collection(json_decode($this->disk->get($singlePath), true));
174-
}
175-
176-
return new Collection;
170+
$files = new Collection($this->disk->allFiles($this->languageFilesPath));
171+
return $files->filter(function ($file) use ($language) {
172+
return strpos($file, "{$language}.json");
173+
})->flatMap(function ($file) {
174+
if (strpos($file->getPathname(), 'vendor')) {
175+
$vendor = str_before(str_after($file->getPathname(), 'vendor/'), '/');
176+
return ["{$vendor}::single" => new Collection(json_decode($this->disk->get($file), true))];
177+
}
178+
return ['single' => new Collection(json_decode($this->disk->get($file), true))];
179+
});
177180
}
178181

179182
/**
@@ -190,10 +193,10 @@ public function getGroupTranslationsFor($language)
190193
if (str_contains($group->getPathname(), 'vendor')) {
191194
$vendor = str_before(str_after($group->getPathname(), 'vendor/'), '/');
192195

193-
return ["{$vendor}::{$group->getBasename('.php')}" => $this->disk->getRequire($group->getPathname())];
196+
return ["{$vendor}::{$group->getBasename('.php')}" => new Collection($this->disk->getRequire($group->getPathname()))];
194197
}
195198

196-
return [$group->getBasename('.php') => $this->disk->getRequire($group->getPathname())];
199+
return [$group->getBasename('.php') => new Collection($this->disk->getRequire($group->getPathname()))];
197200
});
198201
}
199202

@@ -252,6 +255,7 @@ private function saveGroupTranslations($language, $group, $translations)
252255
{
253256
// here we check if it's a namespaced translation which need saving to a
254257
// different path
258+
$translations = $translations instanceof Collection ? $translations->toArray() : $translations;
255259
if (str_contains($group, '::')) {
256260
return $this->saveNamespacedGroupTranslations($language, $group, $translations);
257261
}
@@ -287,10 +291,14 @@ private function saveNamespacedGroupTranslations($language, $group, $translation
287291
*/
288292
private function saveSingleTranslations($language, $translations)
289293
{
290-
$this->disk->put(
291-
"{$this->languageFilesPath}/$language.json",
292-
json_encode((object) $translations, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
293-
);
294+
foreach ($translations as $group => $translation) {
295+
$vendor = str_before($group, '::single');
296+
$languageFilePath = $vendor !== 'single' ? "vendor/{$vendor}/{$language}.json" : "{$language}.json";
297+
$this->disk->put(
298+
"{$this->languageFilesPath}/$languageFilePath",
299+
json_encode((object) $translations->get($group), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
300+
);
301+
}
294302
}
295303

296304
/**

0 commit comments

Comments
 (0)