|
15 | 15 | use Symfony\Component\Translation\MessageCatalogue;
|
16 | 16 | use Symfony\Component\Translation\Exception\InvalidResourceException;
|
17 | 17 | use Symfony\Component\Translation\Exception\NotFoundResourceException;
|
18 |
| -use Symfony\Component\Translation\Exception\InvalidArgumentException; |
19 | 18 | use Symfony\Component\Config\Resource\FileResource;
|
| 19 | +use Symfony\Component\Translation\Util\XliffUtils; |
20 | 20 |
|
21 | 21 | /**
|
22 | 22 | * XliffFileLoader loads translations from XLIFF files.
|
@@ -56,8 +56,10 @@ private function extract($resource, MessageCatalogue $catalogue, $domain)
|
56 | 56 | throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $resource, $e->getMessage()), $e->getCode(), $e);
|
57 | 57 | }
|
58 | 58 |
|
59 |
| - $xliffVersion = $this->getVersionNumber($dom); |
60 |
| - $this->validateSchema($xliffVersion, $dom, $this->getSchema($xliffVersion)); |
| 59 | + $xliffVersion = XliffUtils::getVersionNumber($dom); |
| 60 | + if ($errors = XliffUtils::validateSchema($dom)) { |
| 61 | + throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $xliffVersion, XliffUtils::getErrorsAsString($errors))); |
| 62 | + } |
61 | 63 |
|
62 | 64 | if ('1.2' === $xliffVersion) {
|
63 | 65 | $this->extractXliff1($dom, $catalogue, $domain);
|
@@ -169,123 +171,6 @@ private function utf8ToCharset(string $content, string $encoding = null): string
|
169 | 171 | return $content;
|
170 | 172 | }
|
171 | 173 |
|
172 |
| - /** |
173 |
| - * Validates and parses the given file into a DOMDocument. |
174 |
| - * |
175 |
| - * @throws InvalidResourceException |
176 |
| - */ |
177 |
| - private function validateSchema(string $file, \DOMDocument $dom, string $schema) |
178 |
| - { |
179 |
| - $internalErrors = libxml_use_internal_errors(true); |
180 |
| - |
181 |
| - $disableEntities = libxml_disable_entity_loader(false); |
182 |
| - |
183 |
| - if (!@$dom->schemaValidateSource($schema)) { |
184 |
| - libxml_disable_entity_loader($disableEntities); |
185 |
| - |
186 |
| - throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $file, implode("\n", $this->getXmlErrors($internalErrors)))); |
187 |
| - } |
188 |
| - |
189 |
| - libxml_disable_entity_loader($disableEntities); |
190 |
| - |
191 |
| - $dom->normalizeDocument(); |
192 |
| - |
193 |
| - libxml_clear_errors(); |
194 |
| - libxml_use_internal_errors($internalErrors); |
195 |
| - } |
196 |
| - |
197 |
| - private function getSchema($xliffVersion) |
198 |
| - { |
199 |
| - if ('1.2' === $xliffVersion) { |
200 |
| - $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd'); |
201 |
| - $xmlUri = 'http://www.w3.org/2001/xml.xsd'; |
202 |
| - } elseif ('2.0' === $xliffVersion) { |
203 |
| - $schemaSource = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-2.0.xsd'); |
204 |
| - $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd'; |
205 |
| - } else { |
206 |
| - throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion)); |
207 |
| - } |
208 |
| - |
209 |
| - return $this->fixXmlLocation($schemaSource, $xmlUri); |
210 |
| - } |
211 |
| - |
212 |
| - /** |
213 |
| - * Internally changes the URI of a dependent xsd to be loaded locally. |
214 |
| - */ |
215 |
| - private function fixXmlLocation(string $schemaSource, string $xmlUri): string |
216 |
| - { |
217 |
| - $newPath = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd'; |
218 |
| - $parts = explode('/', $newPath); |
219 |
| - $locationstart = 'file:///'; |
220 |
| - if (0 === stripos($newPath, 'phar://')) { |
221 |
| - $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); |
222 |
| - if ($tmpfile) { |
223 |
| - copy($newPath, $tmpfile); |
224 |
| - $parts = explode('/', str_replace('\\', '/', $tmpfile)); |
225 |
| - } else { |
226 |
| - array_shift($parts); |
227 |
| - $locationstart = 'phar:///'; |
228 |
| - } |
229 |
| - } |
230 |
| - |
231 |
| - $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; |
232 |
| - $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts)); |
233 |
| - |
234 |
| - return str_replace($xmlUri, $newPath, $schemaSource); |
235 |
| - } |
236 |
| - |
237 |
| - /** |
238 |
| - * Returns the XML errors of the internal XML parser. |
239 |
| - */ |
240 |
| - private function getXmlErrors(bool $internalErrors): array |
241 |
| - { |
242 |
| - $errors = array(); |
243 |
| - foreach (libxml_get_errors() as $error) { |
244 |
| - $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', |
245 |
| - LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', |
246 |
| - $error->code, |
247 |
| - trim($error->message), |
248 |
| - $error->file ?: 'n/a', |
249 |
| - $error->line, |
250 |
| - $error->column |
251 |
| - ); |
252 |
| - } |
253 |
| - |
254 |
| - libxml_clear_errors(); |
255 |
| - libxml_use_internal_errors($internalErrors); |
256 |
| - |
257 |
| - return $errors; |
258 |
| - } |
259 |
| - |
260 |
| - /** |
261 |
| - * Gets xliff file version based on the root "version" attribute. |
262 |
| - * Defaults to 1.2 for backwards compatibility. |
263 |
| - * |
264 |
| - * @throws InvalidArgumentException |
265 |
| - */ |
266 |
| - private function getVersionNumber(\DOMDocument $dom): string |
267 |
| - { |
268 |
| - /** @var \DOMNode $xliff */ |
269 |
| - foreach ($dom->getElementsByTagName('xliff') as $xliff) { |
270 |
| - $version = $xliff->attributes->getNamedItem('version'); |
271 |
| - if ($version) { |
272 |
| - return $version->nodeValue; |
273 |
| - } |
274 |
| - |
275 |
| - $namespace = $xliff->attributes->getNamedItem('xmlns'); |
276 |
| - if ($namespace) { |
277 |
| - if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) { |
278 |
| - throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s"', $namespace)); |
279 |
| - } |
280 |
| - |
281 |
| - return substr($namespace, 34); |
282 |
| - } |
283 |
| - } |
284 |
| - |
285 |
| - // Falls back to v1.2 |
286 |
| - return '1.2'; |
287 |
| - } |
288 |
| - |
289 | 174 | private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array
|
290 | 175 | {
|
291 | 176 | $notes = array();
|
|
0 commit comments