5 * Contains \Drupal\Console\Command\Develop\TranslationPendingCommand.
8 namespace Drupal\Console\Command\Develop;
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;
24 class TranslationPendingCommand extends Command
32 protected $consoleRoot;
35 * @var ConfigurationManager
37 protected $configurationManager;
42 protected $nestedArray;
46 * TranslationPendingCommand constructor.
49 * @param $configurationManager
50 * @param NestedArray $nestedArray
52 public function __construct(
54 ConfigurationManager $configurationManager,
55 NestedArray $nestedArray
57 $this->consoleRoot = $consoleRoot;
58 $this->configurationManager = $configurationManager;
59 $this->nestedArray = $nestedArray;
60 parent::__construct();
67 protected function configure()
70 ->setName('translation:pending')
71 ->setDescription($this->trans('commands.translation.pending.description'))
74 InputArgument::REQUIRED,
75 $this->trans('commands.translation.pending.arguments.language'),
81 InputOption::VALUE_OPTIONAL,
82 $this->trans('commands.translation.pending.options.file'),
90 protected function execute(InputInterface $input, OutputInterface $output)
92 $io = new DrupalStyle($input, $output);
94 $language = $input->getArgument('language');
95 $file = $input->getOption('file');
97 $languages = $this->configurationManager->getConfiguration()->get('application.languages');
98 unset($languages['en']);
100 if ($language && !isset($languages[$language])) {
103 $this->trans('commands.translation.pending.messages.invalid-language'),
111 $languages = [$language => $languages[$language]];
114 $pendingTranslations = $this->determinePendingTranslation($io, $language, $languages, $file);
119 $this->trans('commands.translation.pending.messages.success-language-file'),
120 $pendingTranslations,
121 $languages[$language],
128 $this->trans('commands.translation.pending.messages.success-language'),
129 $pendingTranslations,
130 $languages[$language]
136 protected function determinePendingTranslation($io, $language = null, $languages, $fileFilter)
138 $englishFilesFinder = new Finder();
139 $yaml = new Parser();
142 $englishDirectory = $this->consoleRoot .
144 DRUPAL_CONSOLE_LANGUAGE,
148 $englishFiles = $englishFilesFinder->files()->name('*.yml')->in($englishDirectory);
150 $pendingTranslations = 0;
151 foreach ($englishFiles as $file) {
152 $resource = $englishDirectory . '/' . $file->getBasename();
153 $filename = $file->getBasename('.yml');
155 if ($fileFilter && $fileFilter != $file->getBasename()) {
160 $englishFileParsed = $yaml->parse(file_get_contents($resource));
161 } catch (ParseException $e) {
162 $io->error($filename . '.yml: ' . $e->getMessage());
166 foreach ($languages as $langCode => $languageName) {
167 $languageDir = $this->consoleRoot .
169 DRUPAL_CONSOLE_LANGUAGE,
172 if (isset($language) && $langCode != $language) {
176 $resourceTranslated = $languageDir . '/' . $file->getBasename();
177 if (!file_exists($resourceTranslated)) {
180 $this->trans('commands.translation.pending.messages.missing-file'),
189 $resourceTranslatedParsed = $yaml->parse(file_get_contents($resourceTranslated));
190 } catch (ParseException $e) {
191 $io->error($resourceTranslated . ':' . $e->getMessage());
194 $diffStatistics = ['total' => 0, 'equal' => 0, 'diff' => 0];
195 $diff = $this->nestedArray->arrayDiff($englishFileParsed, $resourceTranslatedParsed, true, $diffStatistics);
200 $this->nestedArray->yamlFlattenArray($diff, $diffFlatten, $keyFlatten);
203 $this->trans('commands.yaml.diff.messages.key'),
204 $this->trans('commands.yaml.diff.messages.value'),
208 foreach ($diffFlatten as $yamlKey => $yamlValue) {
209 if ($this->isYamlKey($yamlValue)) {
210 unset($diffFlatten[$yamlKey]);
219 if (count($diffFlatten)) {
222 $this->trans('commands.translation.pending.messages.pending-translations'),
228 $io->table($tableHeader, $tableRows, 'compact');
229 $pendingTranslations+= count($diffFlatten);
235 return $pendingTranslations;