Yaffs site version 1.1
[yaffs-website] / vendor / drupal / console / src / Command / Develop / TranslationPendingCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Console\Command\Develop\TranslationPendingCommand.
6  */
7
8 namespace Drupal\Console\Command\Develop;
9
10 use Drupal\Console\Command\Shared\TranslationTrait;
11 use Symfony\Component\Console\Input\InputInterface;
12 use Symfony\Component\Console\Input\InputOption;
13 use Symfony\Component\Console\Output\OutputInterface;
14 use Symfony\Component\Console\Input\InputArgument;
15 use Symfony\Component\Yaml\Exception\ParseException;
16 use Symfony\Component\Finder\Finder;
17 use Symfony\Component\Yaml\Parser;
18 use Symfony\Component\Console\Command\Command;
19 use Drupal\Console\Core\Style\DrupalStyle;
20 use Drupal\Console\Core\Command\Shared\CommandTrait;
21 use Drupal\Console\Core\Utils\ConfigurationManager;
22 use Drupal\Console\Core\Utils\NestedArray;
23
24 class TranslationPendingCommand extends Command
25 {
26     use TranslationTrait;
27     use CommandTrait;
28
29     /**
30      * @var string
31      */
32     protected $consoleRoot;
33
34     /**
35      * @var ConfigurationManager
36      */
37     protected $configurationManager;
38
39     /**
40       * @var NestedArray
41       */
42     protected $nestedArray;
43
44
45     /**
46      * TranslationPendingCommand constructor.
47      *
48      * @param $consoleRoot
49      * @param $configurationManager
50      * @param NestedArray          $nestedArray
51      */
52     public function __construct(
53         $consoleRoot,
54         ConfigurationManager $configurationManager,
55         NestedArray $nestedArray
56     ) {
57         $this->consoleRoot = $consoleRoot;
58         $this->configurationManager = $configurationManager;
59         $this->nestedArray = $nestedArray;
60         parent::__construct();
61     }
62
63
64     /**
65      * {@inheritdoc}
66      */
67     protected function configure()
68     {
69         $this
70             ->setName('translation:pending')
71             ->setDescription($this->trans('commands.translation.pending.description'))
72             ->addArgument(
73                 'language',
74                 InputArgument::REQUIRED,
75                 $this->trans('commands.translation.pending.arguments.language'),
76                 null
77             )
78             ->addOption(
79                 'file',
80                 null,
81                 InputOption::VALUE_OPTIONAL,
82                 $this->trans('commands.translation.pending.options.file'),
83                 null
84             );
85     }
86
87     /**
88      * {@inheritdoc}
89      */
90     protected function execute(InputInterface $input, OutputInterface $output)
91     {
92         $io = new DrupalStyle($input, $output);
93
94         $language = $input->getArgument('language');
95         $file = $input->getOption('file');
96
97         $languages = $this->configurationManager->getConfiguration()->get('application.languages');
98         unset($languages['en']);
99
100         if ($language && !isset($languages[$language])) {
101             $io->error(
102                 sprintf(
103                     $this->trans('commands.translation.pending.messages.invalid-language'),
104                     $language
105                 )
106             );
107             return 1;
108         }
109
110         if ($language) {
111             $languages = [$language => $languages[$language]];
112         }
113
114         $pendingTranslations = $this->determinePendingTranslation($io, $language, $languages, $file);
115
116         if ($file) {
117             $io->success(
118                 sprintf(
119                     $this->trans('commands.translation.pending.messages.success-language-file'),
120                     $pendingTranslations,
121                     $languages[$language],
122                     $file
123                 )
124             );
125         } else {
126             $io->success(
127                 sprintf(
128                     $this->trans('commands.translation.pending.messages.success-language'),
129                     $pendingTranslations,
130                     $languages[$language]
131                 )
132             );
133         }
134     }
135
136     protected function determinePendingTranslation($io, $language = null, $languages, $fileFilter)
137     {
138         $englishFilesFinder = new Finder();
139         $yaml = new Parser();
140         $statistics = [];
141
142         $englishDirectory = $this->consoleRoot .
143             sprintf(
144                 DRUPAL_CONSOLE_LANGUAGE,
145                 'en'
146             );
147
148         $englishFiles = $englishFilesFinder->files()->name('*.yml')->in($englishDirectory);
149
150         $pendingTranslations = 0;
151         foreach ($englishFiles as $file) {
152             $resource = $englishDirectory . '/' . $file->getBasename();
153             $filename = $file->getBasename('.yml');
154
155             if ($fileFilter && $fileFilter != $file->getBasename()) {
156                 continue;
157             }
158
159             try {
160                 $englishFileParsed = $yaml->parse(file_get_contents($resource));
161             } catch (ParseException $e) {
162                 $io->error($filename . '.yml: ' . $e->getMessage());
163                 continue;
164             }
165
166             foreach ($languages as $langCode => $languageName) {
167                 $languageDir = $this->consoleRoot .
168                                         sprintf(
169                                             DRUPAL_CONSOLE_LANGUAGE,
170                                             $langCode
171                                         );
172                 if (isset($language) && $langCode != $language) {
173                     continue;
174                 }
175
176                 $resourceTranslated = $languageDir . '/' . $file->getBasename();
177                 if (!file_exists($resourceTranslated)) {
178                     $io->info(
179                         sprintf(
180                             $this->trans('commands.translation.pending.messages.missing-file'),
181                             $languageName,
182                             $file->getBasename()
183                         )
184                     );
185                     continue;
186                 }
187
188                 try {
189                     $resourceTranslatedParsed = $yaml->parse(file_get_contents($resourceTranslated));
190                 } catch (ParseException $e) {
191                     $io->error($resourceTranslated . ':' . $e->getMessage());
192                 }
193
194                 $diffStatistics = ['total' => 0, 'equal' => 0, 'diff' => 0];
195                 $diff = $this->nestedArray->arrayDiff($englishFileParsed, $resourceTranslatedParsed, true, $diffStatistics);
196
197                 if (!empty($diff)) {
198                     $diffFlatten = [];
199                     $keyFlatten = '';
200                     $this->nestedArray->yamlFlattenArray($diff, $diffFlatten, $keyFlatten);
201
202                     $tableHeader = [
203                         $this->trans('commands.yaml.diff.messages.key'),
204                         $this->trans('commands.yaml.diff.messages.value'),
205                     ];
206
207                     $tableRows = [];
208                     foreach ($diffFlatten as $yamlKey => $yamlValue) {
209                         if ($this->isYamlKey($yamlValue)) {
210                             unset($diffFlatten[$yamlKey]);
211                         } else {
212                             $tableRows[] = [
213                                 $yamlKey,
214                                 $yamlValue
215                             ];
216                         }
217                     }
218
219                     if (count($diffFlatten)) {
220                         $io->writeln(
221                             sprintf(
222                                 $this->trans('commands.translation.pending.messages.pending-translations'),
223                                 $languageName,
224                                 $file->getBasename()
225                             )
226                         );
227
228                         $io->table($tableHeader, $tableRows, 'compact');
229                         $pendingTranslations+= count($diffFlatten);
230                     }
231                 }
232             }
233         }
234
235         return $pendingTranslations;
236     }
237 }