Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,279 +0,0 @@
1
-<?php
2
-
3
-/*
4
- * This file is part of the Symfony package.
5
- *
6
- * (c) Fabien Potencier <fabien@symfony.com>
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 Symfony\Component\Translation\Command;
13
-
14
-use Symfony\Component\Console\Command\Command;
15
-use Symfony\Component\Console\Exception\RuntimeException;
16
-use Symfony\Component\Console\Input\InputArgument;
17
-use Symfony\Component\Console\Input\InputInterface;
18
-use Symfony\Component\Console\Input\InputOption;
19
-use Symfony\Component\Console\Output\OutputInterface;
20
-use Symfony\Component\Console\Style\SymfonyStyle;
21
-use Symfony\Component\Translation\Util\XliffUtils;
22
-
23
-/**
24
- * Validates XLIFF files syntax and outputs encountered errors.
25
- *
26
- * @author Grégoire Pineau <lyrixx@lyrixx.info>
27
- * @author Robin Chalas <robin.chalas@gmail.com>
28
- * @author Javier Eguiluz <javier.eguiluz@gmail.com>
29
- */
30
-class XliffLintCommand extends Command
31
-{
32
-    protected static $defaultName = 'lint:xliff';
33
-
34
-    private $format;
35
-    private $displayCorrectFiles;
36
-    private $directoryIteratorProvider;
37
-    private $isReadableProvider;
38
-    private $requireStrictFileNames;
39
-
40
-    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
41
-    {
42
-        parent::__construct($name);
43
-
44
-        $this->directoryIteratorProvider = $directoryIteratorProvider;
45
-        $this->isReadableProvider = $isReadableProvider;
46
-        $this->requireStrictFileNames = $requireStrictFileNames;
47
-    }
48
-
49
-    /**
50
-     * {@inheritdoc}
51
-     */
52
-    protected function configure()
53
-    {
54
-        $this
55
-            ->setDescription('Lints a XLIFF file and outputs encountered errors')
56
-            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file or a directory or STDIN')
57
-            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
58
-            ->setHelp(<<<EOF
59
-The <info>%command.name%</info> command lints a XLIFF file and outputs to STDOUT
60
-the first encountered syntax error.
61
-
62
-You can validates XLIFF contents passed from STDIN:
63
-
64
-  <info>cat filename | php %command.full_name%</info>
65
-
66
-You can also validate the syntax of a file:
67
-
68
-  <info>php %command.full_name% filename</info>
69
-
70
-Or of a whole directory:
71
-
72
-  <info>php %command.full_name% dirname</info>
73
-  <info>php %command.full_name% dirname --format=json</info>
74
-
75
-EOF
76
-            )
77
-        ;
78
-    }
79
-
80
-    protected function execute(InputInterface $input, OutputInterface $output)
81
-    {
82
-        $io = new SymfonyStyle($input, $output);
83
-        $filenames = (array) $input->getArgument('filename');
84
-        $this->format = $input->getOption('format');
85
-        $this->displayCorrectFiles = $output->isVerbose();
86
-
87
-        if (0 === \count($filenames)) {
88
-            if (!$stdin = $this->getStdin()) {
89
-                throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
90
-            }
91
-
92
-            return $this->display($io, [$this->validate($stdin)]);
93
-        }
94
-
95
-        $filesInfo = [];
96
-        foreach ($filenames as $filename) {
97
-            if (!$this->isReadable($filename)) {
98
-                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
99
-            }
100
-
101
-            foreach ($this->getFiles($filename) as $file) {
102
-                $filesInfo[] = $this->validate(file_get_contents($file), $file);
103
-            }
104
-        }
105
-
106
-        return $this->display($io, $filesInfo);
107
-    }
108
-
109
-    private function validate($content, $file = null)
110
-    {
111
-        $errors = [];
112
-
113
-        // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
114
-        if ('' === trim($content)) {
115
-            return ['file' => $file, 'valid' => true];
116
-        }
117
-
118
-        $internal = libxml_use_internal_errors(true);
119
-
120
-        $document = new \DOMDocument();
121
-        $document->loadXML($content);
122
-
123
-        if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
124
-            $normalizedLocale = preg_quote(str_replace('-', '_', $targetLanguage), '/');
125
-            // strict file names require translation files to be named '____.locale.xlf'
126
-            // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
127
-            // also, the regexp matching must be case-insensitive, as defined for 'target-language' values
128
-            // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
129
-            $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.xlf/', $normalizedLocale) : sprintf('/^(.*\.(?i:%s)\.xlf|(?i:%s)\..*\.xlf)/', $normalizedLocale, $normalizedLocale);
130
-
131
-            if (0 === preg_match($expectedFilenamePattern, basename($file))) {
132
-                $errors[] = [
133
-                    'line' => -1,
134
-                    'column' => -1,
135
-                    'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
136
-                ];
137
-            }
138
-        }
139
-
140
-        foreach (XliffUtils::validateSchema($document) as $xmlError) {
141
-            $errors[] = [
142
-                'line' => $xmlError['line'],
143
-                'column' => $xmlError['column'],
144
-                'message' => $xmlError['message'],
145
-            ];
146
-        }
147
-
148
-        libxml_clear_errors();
149
-        libxml_use_internal_errors($internal);
150
-
151
-        return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors];
152
-    }
153
-
154
-    private function display(SymfonyStyle $io, array $files)
155
-    {
156
-        switch ($this->format) {
157
-            case 'txt':
158
-                return $this->displayTxt($io, $files);
159
-            case 'json':
160
-                return $this->displayJson($io, $files);
161
-            default:
162
-                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
163
-        }
164
-    }
165
-
166
-    private function displayTxt(SymfonyStyle $io, array $filesInfo)
167
-    {
168
-        $countFiles = \count($filesInfo);
169
-        $erroredFiles = 0;
170
-
171
-        foreach ($filesInfo as $info) {
172
-            if ($info['valid'] && $this->displayCorrectFiles) {
173
-                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
174
-            } elseif (!$info['valid']) {
175
-                ++$erroredFiles;
176
-                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
177
-                $io->listing(array_map(function ($error) {
178
-                    // general document errors have a '-1' line number
179
-                    return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
180
-                }, $info['messages']));
181
-            }
182
-        }
183
-
184
-        if (0 === $erroredFiles) {
185
-            $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
186
-        } else {
187
-            $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
188
-        }
189
-
190
-        return min($erroredFiles, 1);
191
-    }
192
-
193
-    private function displayJson(SymfonyStyle $io, array $filesInfo)
194
-    {
195
-        $errors = 0;
196
-
197
-        array_walk($filesInfo, function (&$v) use (&$errors) {
198
-            $v['file'] = (string) $v['file'];
199
-            if (!$v['valid']) {
200
-                ++$errors;
201
-            }
202
-        });
203
-
204
-        $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
205
-
206
-        return min($errors, 1);
207
-    }
208
-
209
-    private function getFiles($fileOrDirectory)
210
-    {
211
-        if (is_file($fileOrDirectory)) {
212
-            yield new \SplFileInfo($fileOrDirectory);
213
-
214
-            return;
215
-        }
216
-
217
-        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
218
-            if (!\in_array($file->getExtension(), ['xlf', 'xliff'])) {
219
-                continue;
220
-            }
221
-
222
-            yield $file;
223
-        }
224
-    }
225
-
226
-    private function getStdin()
227
-    {
228
-        if (0 !== ftell(STDIN)) {
229
-            return;
230
-        }
231
-
232
-        $inputs = '';
233
-        while (!feof(STDIN)) {
234
-            $inputs .= fread(STDIN, 1024);
235
-        }
236
-
237
-        return $inputs;
238
-    }
239
-
240
-    private function getDirectoryIterator($directory)
241
-    {
242
-        $default = function ($directory) {
243
-            return new \RecursiveIteratorIterator(
244
-                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
245
-                \RecursiveIteratorIterator::LEAVES_ONLY
246
-            );
247
-        };
248
-
249
-        if (null !== $this->directoryIteratorProvider) {
250
-            return ($this->directoryIteratorProvider)($directory, $default);
251
-        }
252
-
253
-        return $default($directory);
254
-    }
255
-
256
-    private function isReadable($fileOrDirectory)
257
-    {
258
-        $default = function ($fileOrDirectory) {
259
-            return is_readable($fileOrDirectory);
260
-        };
261
-
262
-        if (null !== $this->isReadableProvider) {
263
-            return ($this->isReadableProvider)($fileOrDirectory, $default);
264
-        }
265
-
266
-        return $default($fileOrDirectory);
267
-    }
268
-
269
-    private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
270
-    {
271
-        foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) {
272
-            if ('target-language' === $attribute->nodeName) {
273
-                return $attribute->nodeValue;
274
-            }
275
-        }
276
-
277
-        return null;
278
-    }
279
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,279 @@
1
+<?php
2
+
3
+/*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
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 Symfony\Component\Translation\Command;
13
+
14
+use Symfony\Component\Console\Command\Command;
15
+use Symfony\Component\Console\Exception\RuntimeException;
16
+use Symfony\Component\Console\Input\InputArgument;
17
+use Symfony\Component\Console\Input\InputInterface;
18
+use Symfony\Component\Console\Input\InputOption;
19
+use Symfony\Component\Console\Output\OutputInterface;
20
+use Symfony\Component\Console\Style\SymfonyStyle;
21
+use Symfony\Component\Translation\Util\XliffUtils;
22
+
23
+/**
24
+ * Validates XLIFF files syntax and outputs encountered errors.
25
+ *
26
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
27
+ * @author Robin Chalas <robin.chalas@gmail.com>
28
+ * @author Javier Eguiluz <javier.eguiluz@gmail.com>
29
+ */
30
+class XliffLintCommand extends Command
31
+{
32
+    protected static $defaultName = 'lint:xliff';
33
+
34
+    private $format;
35
+    private $displayCorrectFiles;
36
+    private $directoryIteratorProvider;
37
+    private $isReadableProvider;
38
+    private $requireStrictFileNames;
39
+
40
+    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
41
+    {
42
+        parent::__construct($name);
43
+
44
+        $this->directoryIteratorProvider = $directoryIteratorProvider;
45
+        $this->isReadableProvider = $isReadableProvider;
46
+        $this->requireStrictFileNames = $requireStrictFileNames;
47
+    }
48
+
49
+    /**
50
+     * {@inheritdoc}
51
+     */
52
+    protected function configure()
53
+    {
54
+        $this
55
+            ->setDescription('Lints a XLIFF file and outputs encountered errors')
56
+            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file or a directory or STDIN')
57
+            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
58
+            ->setHelp(<<<EOF
59
+The <info>%command.name%</info> command lints a XLIFF file and outputs to STDOUT
60
+the first encountered syntax error.
61
+
62
+You can validates XLIFF contents passed from STDIN:
63
+
64
+  <info>cat filename | php %command.full_name%</info>
65
+
66
+You can also validate the syntax of a file:
67
+
68
+  <info>php %command.full_name% filename</info>
69
+
70
+Or of a whole directory:
71
+
72
+  <info>php %command.full_name% dirname</info>
73
+  <info>php %command.full_name% dirname --format=json</info>
74
+
75
+EOF
76
+            )
77
+        ;
78
+    }
79
+
80
+    protected function execute(InputInterface $input, OutputInterface $output)
81
+    {
82
+        $io = new SymfonyStyle($input, $output);
83
+        $filenames = (array) $input->getArgument('filename');
84
+        $this->format = $input->getOption('format');
85
+        $this->displayCorrectFiles = $output->isVerbose();
86
+
87
+        if (0 === \count($filenames)) {
88
+            if (!$stdin = $this->getStdin()) {
89
+                throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
90
+            }
91
+
92
+            return $this->display($io, [$this->validate($stdin)]);
93
+        }
94
+
95
+        $filesInfo = [];
96
+        foreach ($filenames as $filename) {
97
+            if (!$this->isReadable($filename)) {
98
+                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
99
+            }
100
+
101
+            foreach ($this->getFiles($filename) as $file) {
102
+                $filesInfo[] = $this->validate(file_get_contents($file), $file);
103
+            }
104
+        }
105
+
106
+        return $this->display($io, $filesInfo);
107
+    }
108
+
109
+    private function validate($content, $file = null)
110
+    {
111
+        $errors = [];
112
+
113
+        // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
114
+        if ('' === trim($content)) {
115
+            return ['file' => $file, 'valid' => true];
116
+        }
117
+
118
+        $internal = libxml_use_internal_errors(true);
119
+
120
+        $document = new \DOMDocument();
121
+        $document->loadXML($content);
122
+
123
+        if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
124
+            $normalizedLocale = preg_quote(str_replace('-', '_', $targetLanguage), '/');
125
+            // strict file names require translation files to be named '____.locale.xlf'
126
+            // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
127
+            // also, the regexp matching must be case-insensitive, as defined for 'target-language' values
128
+            // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
129
+            $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.xlf/', $normalizedLocale) : sprintf('/^(.*\.(?i:%s)\.xlf|(?i:%s)\..*\.xlf)/', $normalizedLocale, $normalizedLocale);
130
+
131
+            if (0 === preg_match($expectedFilenamePattern, basename($file))) {
132
+                $errors[] = [
133
+                    'line' => -1,
134
+                    'column' => -1,
135
+                    'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
136
+                ];
137
+            }
138
+        }
139
+
140
+        foreach (XliffUtils::validateSchema($document) as $xmlError) {
141
+            $errors[] = [
142
+                'line' => $xmlError['line'],
143
+                'column' => $xmlError['column'],
144
+                'message' => $xmlError['message'],
145
+            ];
146
+        }
147
+
148
+        libxml_clear_errors();
149
+        libxml_use_internal_errors($internal);
150
+
151
+        return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors];
152
+    }
153
+
154
+    private function display(SymfonyStyle $io, array $files)
155
+    {
156
+        switch ($this->format) {
157
+            case 'txt':
158
+                return $this->displayTxt($io, $files);
159
+            case 'json':
160
+                return $this->displayJson($io, $files);
161
+            default:
162
+                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
163
+        }
164
+    }
165
+
166
+    private function displayTxt(SymfonyStyle $io, array $filesInfo)
167
+    {
168
+        $countFiles = \count($filesInfo);
169
+        $erroredFiles = 0;
170
+
171
+        foreach ($filesInfo as $info) {
172
+            if ($info['valid'] && $this->displayCorrectFiles) {
173
+                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
174
+            } elseif (!$info['valid']) {
175
+                ++$erroredFiles;
176
+                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
177
+                $io->listing(array_map(function ($error) {
178
+                    // general document errors have a '-1' line number
179
+                    return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
180
+                }, $info['messages']));
181
+            }
182
+        }
183
+
184
+        if (0 === $erroredFiles) {
185
+            $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
186
+        } else {
187
+            $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
188
+        }
189
+
190
+        return min($erroredFiles, 1);
191
+    }
192
+
193
+    private function displayJson(SymfonyStyle $io, array $filesInfo)
194
+    {
195
+        $errors = 0;
196
+
197
+        array_walk($filesInfo, function (&$v) use (&$errors) {
198
+            $v['file'] = (string) $v['file'];
199
+            if (!$v['valid']) {
200
+                ++$errors;
201
+            }
202
+        });
203
+
204
+        $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
205
+
206
+        return min($errors, 1);
207
+    }
208
+
209
+    private function getFiles($fileOrDirectory)
210
+    {
211
+        if (is_file($fileOrDirectory)) {
212
+            yield new \SplFileInfo($fileOrDirectory);
213
+
214
+            return;
215
+        }
216
+
217
+        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
218
+            if (!\in_array($file->getExtension(), ['xlf', 'xliff'])) {
219
+                continue;
220
+            }
221
+
222
+            yield $file;
223
+        }
224
+    }
225
+
226
+    private function getStdin()
227
+    {
228
+        if (0 !== ftell(STDIN)) {
229
+            return;
230
+        }
231
+
232
+        $inputs = '';
233
+        while (!feof(STDIN)) {
234
+            $inputs .= fread(STDIN, 1024);
235
+        }
236
+
237
+        return $inputs;
238
+    }
239
+
240
+    private function getDirectoryIterator($directory)
241
+    {
242
+        $default = function ($directory) {
243
+            return new \RecursiveIteratorIterator(
244
+                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
245
+                \RecursiveIteratorIterator::LEAVES_ONLY
246
+            );
247
+        };
248
+
249
+        if (null !== $this->directoryIteratorProvider) {
250
+            return ($this->directoryIteratorProvider)($directory, $default);
251
+        }
252
+
253
+        return $default($directory);
254
+    }
255
+
256
+    private function isReadable($fileOrDirectory)
257
+    {
258
+        $default = function ($fileOrDirectory) {
259
+            return is_readable($fileOrDirectory);
260
+        };
261
+
262
+        if (null !== $this->isReadableProvider) {
263
+            return ($this->isReadableProvider)($fileOrDirectory, $default);
264
+        }
265
+
266
+        return $default($fileOrDirectory);
267
+    }
268
+
269
+    private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
270
+    {
271
+        foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) {
272
+            if ('target-language' === $attribute->nodeName) {
273
+                return $attribute->nodeValue;
274
+            }
275
+        }
276
+
277
+        return null;
278
+    }
279
+}