1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the PHP Translation package. |
5
|
|
|
* |
6
|
|
|
* (c) PHP Translation team <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Translation\SymfonyStorage; |
13
|
|
|
|
14
|
|
|
use Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader as SymfonyTranslationLoader; |
15
|
|
|
use Symfony\Component\Translation\MessageCatalogue; |
16
|
|
|
use Symfony\Component\Translation\MessageCatalogueInterface; |
17
|
|
|
use Symfony\Component\Translation\Reader\TranslationReader; |
18
|
|
|
use Symfony\Component\Translation\Writer\TranslationWriter; |
19
|
|
|
use Symfony\Component\Translation\Writer\TranslationWriterInterface; |
20
|
|
|
use Translation\Common\Model\Message; |
21
|
|
|
use Translation\Common\Storage; |
22
|
|
|
use Translation\Common\TransferableStorage; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* This storage uses Symfony's writer and loader. |
26
|
|
|
* |
27
|
|
|
* @author Tobias Nyholm <[email protected]> |
28
|
|
|
*/ |
29
|
|
|
final class FileStorage implements Storage, TransferableStorage |
30
|
|
|
{ |
31
|
|
|
/** |
32
|
|
|
* @var TranslationWriterInterface|LegacyTranslationWriter |
33
|
|
|
*/ |
34
|
|
|
private $writer; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var TranslationLoader|SymfonyTranslationLoader |
38
|
|
|
*/ |
39
|
|
|
private $loader; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var array directory path |
43
|
|
|
*/ |
44
|
|
|
private $dir; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var array with option to the dumper |
48
|
|
|
*/ |
49
|
|
|
private $options; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @var MessageCatalogue[] Fetched catalogies |
53
|
|
|
*/ |
54
|
|
|
private $catalogues; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @param TranslationWriter $writer |
58
|
|
|
* @param SymfonyTranslationLoader|TranslationLoader|TranslationReader $loader |
59
|
|
|
* @param array $dir |
60
|
|
|
* @param array $options |
61
|
|
|
*/ |
62
|
10 |
|
public function __construct(TranslationWriter $writer, $loader, array $dir, array $options = []) |
63
|
|
|
{ |
64
|
|
|
// Create a legacy writer which is a wrapper for TranslationWriter |
65
|
10 |
|
if (!$writer instanceof TranslationWriterInterface) { |
66
|
10 |
|
$writer = new LegacyTranslationWriter($writer); |
67
|
10 |
|
} |
68
|
|
|
// Create a legacy loader which is a wrapper for TranslationReader |
69
|
10 |
|
if ($loader instanceof TranslationReader) { |
70
|
|
|
$loader = new LegacyTranslationLoader($loader); |
71
|
|
|
} |
72
|
10 |
|
if (!$loader instanceof SymfonyTranslationLoader && !$loader instanceof TranslationLoader) { |
|
|
|
|
73
|
1 |
|
throw new \LogicException('Second parameter of FileStorage must be a Symfony translation loader or implement Translation\SymfonyStorage\TranslationLoader'); |
74
|
|
|
} |
75
|
|
|
|
76
|
9 |
|
if (empty($dir)) { |
77
|
1 |
|
throw new \LogicException('Third parameter of FileStorage cannot be empty'); |
78
|
|
|
} |
79
|
|
|
|
80
|
8 |
|
if (!array_key_exists('xliff_version', $options)) { |
81
|
|
|
// Set default value for xliff version. |
82
|
8 |
|
$options['xliff_version'] = '2.0'; |
83
|
8 |
|
} |
84
|
|
|
|
85
|
8 |
|
$this->writer = $writer; |
86
|
8 |
|
$this->loader = $loader; |
87
|
8 |
|
$this->dir = $dir; |
88
|
8 |
|
$this->options = $options; |
89
|
8 |
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* {@inheritdoc} |
93
|
|
|
*/ |
94
|
1 |
|
public function get($locale, $domain, $key) |
95
|
|
|
{ |
96
|
1 |
|
$catalogue = $this->getCatalogue($locale); |
97
|
1 |
|
$translation = $catalogue->get($key, $domain); |
98
|
|
|
|
99
|
1 |
|
return new Message($key, $domain, $locale, $translation); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* {@inheritdoc} |
104
|
|
|
*/ |
105
|
2 |
|
public function create(Message $m) |
106
|
|
|
{ |
107
|
2 |
|
$catalogue = $this->getCatalogue($m->getLocale()); |
108
|
2 |
|
if (!$catalogue->defines($m->getKey(), $m->getDomain())) { |
109
|
2 |
|
$catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain()); |
110
|
2 |
|
$this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain()); |
111
|
2 |
|
} |
112
|
2 |
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* {@inheritdoc} |
116
|
|
|
*/ |
117
|
1 |
|
public function update(Message $m) |
118
|
|
|
{ |
119
|
1 |
|
$catalogue = $this->getCatalogue($m->getLocale()); |
120
|
1 |
|
$catalogue->set($m->getKey(), $m->getTranslation(), $m->getDomain()); |
121
|
1 |
|
$this->writeCatalogue($catalogue, $m->getLocale(), $m->getDomain()); |
122
|
1 |
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* {@inheritdoc} |
126
|
|
|
*/ |
127
|
1 |
|
public function delete($locale, $domain, $key) |
128
|
|
|
{ |
129
|
1 |
|
$catalogue = $this->getCatalogue($locale); |
130
|
1 |
|
$messages = $catalogue->all($domain); |
131
|
1 |
|
unset($messages[$key]); |
132
|
|
|
|
133
|
1 |
|
$catalogue->replace($messages, $domain); |
134
|
1 |
|
$this->writeCatalogue($catalogue, $locale, $domain); |
135
|
1 |
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* {@inheritdoc} |
139
|
|
|
*/ |
140
|
1 |
|
public function export(MessageCatalogueInterface $catalogue) |
141
|
|
|
{ |
142
|
1 |
|
$locale = $catalogue->getLocale(); |
143
|
1 |
|
$catalogue->addCatalogue($this->getCatalogue($locale)); |
144
|
1 |
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* {@inheritdoc} |
148
|
|
|
*/ |
149
|
1 |
|
public function import(MessageCatalogueInterface $catalogue) |
150
|
|
|
{ |
151
|
1 |
|
$domains = $catalogue->getDomains(); |
152
|
1 |
|
foreach ($domains as $domain) { |
153
|
1 |
|
$this->writeCatalogue($catalogue, $catalogue->getLocale(), $domain); |
|
|
|
|
154
|
1 |
|
} |
155
|
1 |
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Save catalogue back to file. |
159
|
|
|
* |
160
|
|
|
* @param MessageCatalogue $catalogue |
161
|
|
|
* @param string $domain |
162
|
|
|
*/ |
163
|
5 |
|
private function writeCatalogue(MessageCatalogue $catalogue, $locale, $domain) |
164
|
|
|
{ |
165
|
5 |
|
$resources = $catalogue->getResources(); |
166
|
5 |
|
$options = $this->options; |
167
|
5 |
|
$written = false; |
168
|
5 |
|
foreach ($resources as $resource) { |
169
|
3 |
|
$path = (string) $resource; |
170
|
3 |
|
if (preg_match('|/'.$domain.'\.'.$locale.'\.([a-z]+)$|', $path, $matches)) { |
171
|
3 |
|
$options['path'] = str_replace($matches[0], '', $path); |
172
|
3 |
|
$this->writer->write($catalogue, $matches[1], $options); |
173
|
3 |
|
$written = true; |
174
|
3 |
|
} |
175
|
5 |
|
} |
176
|
|
|
|
177
|
5 |
|
if ($written) { |
178
|
|
|
// We have written the translation to a file. |
179
|
3 |
|
return; |
180
|
|
|
} |
181
|
|
|
|
182
|
2 |
|
$options['path'] = reset($this->dir); |
183
|
2 |
|
$format = isset($options['default_output_format']) ? $options['default_output_format'] : 'xlf'; |
184
|
2 |
|
$this->writer->write($catalogue, $format, $options); |
185
|
2 |
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* @param string $locale |
189
|
|
|
* |
190
|
|
|
* @return MessageCatalogue |
191
|
|
|
*/ |
192
|
6 |
|
private function getCatalogue($locale) |
193
|
|
|
{ |
194
|
6 |
|
if (empty($this->catalogues[$locale])) { |
195
|
6 |
|
$this->loadCatalogue($locale, $this->dir); |
196
|
6 |
|
} |
197
|
|
|
|
198
|
6 |
|
return $this->catalogues[$locale]; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Load catalogue from files. |
203
|
|
|
* |
204
|
|
|
* @param string $locale |
205
|
|
|
* @param array $dirs |
206
|
|
|
*/ |
207
|
6 |
|
private function loadCatalogue($locale, array $dirs) |
208
|
|
|
{ |
209
|
6 |
|
$currentCatalogue = new MessageCatalogue($locale); |
210
|
6 |
|
foreach ($dirs as $path) { |
211
|
6 |
|
if (is_dir($path)) { |
212
|
5 |
|
$this->loader->loadMessages($path, $currentCatalogue); |
213
|
5 |
|
} |
214
|
6 |
|
} |
215
|
|
|
|
216
|
6 |
|
$this->catalogues[$locale] = $currentCatalogue; |
217
|
6 |
|
} |
218
|
|
|
} |
219
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.