1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the Laravel MultiLang package. |
4
|
|
|
* |
5
|
|
|
* (c) Avtandil Kikabidze aka LONGMAN <[email protected]> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Longman\LaravelMultiLang\Console; |
12
|
|
|
|
13
|
|
|
use App; |
14
|
|
|
use Illuminate\Console\Command; |
15
|
|
|
use InvalidArgumentException; |
16
|
|
|
use Illuminate\Database\DatabaseManager as Database; |
17
|
|
|
use Symfony\Component\Yaml\Yaml; |
18
|
|
|
|
19
|
|
|
class ExportCommand extends Command |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* The name and signature of the console command. |
23
|
|
|
* |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
protected $signature = 'multilang:export |
27
|
|
|
{--path=storage/multilang : The path to multilang folder} |
28
|
|
|
{--lang= : Comma separated langs to export, default all} |
29
|
|
|
{--scope= : Comma separated scopes, default all} |
30
|
|
|
{--force : Force update existing texts in files} |
31
|
|
|
{--clear : Clear texts from files before export} |
32
|
|
|
'; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* The console command description. |
36
|
|
|
* |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
protected $description = 'Export texts from database to yml files.'; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The name of texts table. |
43
|
|
|
* |
44
|
|
|
* @var string |
45
|
|
|
*/ |
46
|
|
|
protected $table; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* The database connection instance. |
50
|
|
|
* |
51
|
|
|
* @var \Illuminate\Database\Connection |
52
|
|
|
*/ |
53
|
|
|
protected $db; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* The path to texts files. |
57
|
|
|
* |
58
|
|
|
* @var string |
59
|
|
|
*/ |
60
|
|
|
protected $path; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* The langs. |
64
|
|
|
* |
65
|
|
|
* @var array |
66
|
|
|
*/ |
67
|
|
|
protected $langs; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* The available scopes. |
71
|
|
|
* |
72
|
|
|
* @var array |
73
|
|
|
*/ |
74
|
|
|
protected $scopes = ['global', 'site', 'admin']; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Execute the console command. |
78
|
|
|
* |
79
|
|
|
* @return mixed |
80
|
|
|
*/ |
81
|
|
|
public function handle() |
82
|
|
|
{ |
83
|
|
|
$this->table = config('multilang.db.texts_table', 'texts'); |
84
|
|
|
$this->db = $this->getDatabase(); |
85
|
|
|
|
86
|
|
|
$lang = $this->option('lang'); |
87
|
|
|
if (! empty($lang)) { |
88
|
|
|
$this->langs = explode(',', $lang); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
$scopes = $this->scopes; |
92
|
|
|
$scope = $this->option('scope'); |
93
|
|
View Code Duplication |
if (! empty($scope)) { |
|
|
|
|
94
|
|
|
$scopes = explode(',', $scope); |
95
|
|
|
foreach ($scopes as $scope) { |
96
|
|
|
if (! in_array($scope, $this->scopes)) { |
97
|
|
|
throw new InvalidArgumentException('Scope "' . $scope . '" is not found! Available scopes is ' . implode(', ', $this->scopes)); |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$path = $this->option('path', 'storage/multilang'); |
|
|
|
|
103
|
|
|
$this->path = base_path($path); |
|
|
|
|
104
|
|
|
if (! is_dir($this->path)) { |
105
|
|
|
throw new InvalidArgumentException('Folder "' . $this->path . '" is not accessible!'); |
106
|
|
|
} |
107
|
|
|
if (! is_writable($this->path)) { |
108
|
|
|
throw new InvalidArgumentException('Folder "' . $this->path . '" is not writable!'); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
$force = $this->option('force'); |
112
|
|
|
$clear = $this->option('clear'); |
113
|
|
|
foreach ($scopes as $scope) { |
114
|
|
|
$this->export($scope, $force, $clear); |
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
return; |
118
|
|
|
|
119
|
|
|
/*$texts = Text::where('scope', 'site')->where('lang', 'en')->get()->toArray(); |
|
|
|
|
120
|
|
|
|
121
|
|
|
|
122
|
|
|
$newTexts = []; |
123
|
|
|
foreach($texts as $text) { |
124
|
|
|
$arr = []; |
125
|
|
|
$arr['key'] = $text['key']; |
126
|
|
|
$arr['texts']['en'] = $text['value']; |
127
|
|
|
$arr['texts']['ir'] = $text['value']; |
128
|
|
|
|
129
|
|
|
$newTexts[] = $arr; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
$yaml = Yaml::dump($newTexts, 3, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK);*/ |
133
|
|
|
|
134
|
|
|
$path = storage_path('texts/site.yml'); |
|
|
|
|
135
|
|
|
|
136
|
|
|
//dump(file_put_contents($path, $yaml)); |
|
|
|
|
137
|
|
|
//die; |
138
|
|
|
|
139
|
|
|
$value = Yaml::parse(file_get_contents($path)); |
140
|
|
|
dump($value); |
141
|
|
|
die; |
|
|
|
|
142
|
|
|
|
143
|
|
|
//$this->info('Database backup restored successfully'); |
|
|
|
|
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
protected function export($scope = 'global', $force = false, $clear = false) |
147
|
|
|
{ |
148
|
|
|
$dbTexts = $this->getTextsFromDb($scope); |
149
|
|
|
|
150
|
|
|
$fileTexts = ! $clear ? $this->getTextsFromFile($scope) : []; |
151
|
|
|
|
152
|
|
|
$textsToWrite = $force ? array_replace_recursive($fileTexts, $dbTexts) : array_replace_recursive($dbTexts, $fileTexts); |
153
|
|
|
|
154
|
|
|
// Reset keys |
155
|
|
|
$textsToWrite = array_values($textsToWrite); |
156
|
|
|
|
157
|
|
|
$yaml = Yaml::dump($textsToWrite, 3, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); |
158
|
|
|
|
159
|
|
|
$path = $this->path . '/' . $scope . '.yml'; |
160
|
|
|
$written = file_put_contents($path, $yaml); |
161
|
|
|
if (! $written) { |
162
|
|
|
$this->error('Export texts of "' . $scope . '" is failed!'); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
$this->info('Export texts of "' . $scope . '" is finished in "' . $path . '"'); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Get a texts from file. |
170
|
|
|
* |
171
|
|
|
* @return array |
172
|
|
|
*/ |
173
|
|
|
protected function getTextsFromFile($scope) |
174
|
|
|
{ |
175
|
|
|
$fileTexts = []; |
176
|
|
|
$path = $this->path . '/' . $scope . '.yml'; |
177
|
|
|
if (is_readable($path)) { |
178
|
|
|
$fileTexts = Yaml::parse(file_get_contents($path)); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
$formattedFileTexts = []; |
182
|
|
|
foreach ($fileTexts as $text) { |
|
|
|
|
183
|
|
|
$formattedFileTexts[$text['key']] = $text; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
return $formattedFileTexts; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* Get a texts from database. |
191
|
|
|
* |
192
|
|
|
* @return array |
193
|
|
|
*/ |
194
|
|
|
protected function getTextsFromDb($scope) |
195
|
|
|
{ |
196
|
|
|
$dbTexts = $this->db |
197
|
|
|
->table($this->table) |
198
|
|
|
->where('scope', $scope) |
199
|
|
|
->get(); |
200
|
|
|
|
201
|
|
|
$formattedDbTexts = []; |
202
|
|
|
foreach ($dbTexts as $text) { |
203
|
|
|
$key = $text->key; |
204
|
|
|
$lang = $text->lang; |
205
|
|
|
if (! isset($formattedDbTexts[$key])) { |
206
|
|
|
$formattedDbTexts[$key] = ['key' => $key]; |
207
|
|
|
} |
208
|
|
|
$formattedDbTexts[$key]['texts'][$lang] = $text->value; |
209
|
|
|
} |
210
|
|
|
return $formattedDbTexts; |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* Get a database connection instance. |
215
|
|
|
* |
216
|
|
|
* @return \Illuminate\Database\Connection |
217
|
|
|
*/ |
218
|
|
View Code Duplication |
protected function getDatabase() |
|
|
|
|
219
|
|
|
{ |
220
|
|
|
$connection = config('multilang.db.connection', 'default'); |
221
|
|
|
$db = App::make(Database::class); |
222
|
|
|
if ($connection == 'default') { |
223
|
|
|
return $db->connection(); |
224
|
|
|
} |
225
|
|
|
return $db->connection($connection); |
226
|
|
|
} |
227
|
|
|
} |
228
|
|
|
|
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.