consoleRoot = $consoleRoot; $this->configurationManager = $configurationManager; $this->renderer = $renderer; $this->nestedArray = $nestedArray; parent::__construct(); } /** * {@inheritdoc} */ protected function configure() { $this ->setName('translation:stats') ->setDescription($this->trans('commands.translation.stats.description')) ->addArgument( 'language', InputArgument::OPTIONAL, $this->trans('commands.translation.stats.arguments.language'), null ) ->addOption( 'format', null, InputOption::VALUE_OPTIONAL, $this->trans('commands.translation.stats.options.format'), 'table' ); } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $language = $input->getArgument('language'); $format = $input->getOption('format'); $languages = $this->configurationManager->getConfiguration()->get('application.languages'); unset($languages['en']); if ($language && !isset($languages[$language])) { $io->error( sprintf( $this->trans('commands.translation.stats.messages.invalid-language'), $language ) ); return 1; } if ($language) { $languages = [$language => $languages[$language]]; } $stats = $this->calculateStats($io, $language, $languages); if ($format == 'table') { $tableHeaders = [ $this->trans('commands.translation.stats.messages.language'), $this->trans('commands.translation.stats.messages.percentage'), $this->trans('commands.translation.stats.messages.iso') ]; $io->table($tableHeaders, $stats); return 0; } if ($format == 'markdown') { $arguments['language'] = $this->trans('commands.translation.stats.messages.language'); $arguments['percentage'] = $this->trans('commands.translation.stats.messages.percentage'); $arguments['languages'] = $stats; $io->writeln( $this->renderFile( 'core/translation/stats.md.twig', null, $arguments ) ); } } protected function calculateStats($io, $language = null, $languages) { $englishFilesFinder = new Finder(); $yaml = new Parser(); $statistics = []; $englishDirectory = $this->consoleRoot . sprintf( DRUPAL_CONSOLE_LANGUAGE, 'en' ); $englishFiles = $englishFilesFinder->files()->name('*.yml')->in($englishDirectory); foreach ($englishFiles as $file) { $resource = $englishDirectory . '/' . $file->getBasename(); $filename = $file->getBasename('.yml'); try { $englishFileParsed = $yaml->parse(file_get_contents($resource)); } catch (ParseException $e) { $io->error($filename . '.yml: ' . $e->getMessage()); continue; } foreach ($languages as $langCode => $languageName) { $languageDir = $this->consoleRoot . sprintf( DRUPAL_CONSOLE_LANGUAGE, $langCode ); //don't show that language if that repo isn't present if (!file_exists($languageDir)) { continue; } if (isset($language) && $langCode != $language) { continue; } if (!isset($statistics[$langCode])) { $statistics[$langCode] = ['total' => 0, 'equal'=> 0 , 'diff' => 0]; } $resourceTranslated = $languageDir . '/' . $file->getBasename(); if (!file_exists($resourceTranslated)) { $englishFileEntries = count($englishFileParsed, COUNT_RECURSIVE); $statistics[$langCode]['total'] += $englishFileEntries; $statistics[$langCode]['equal'] += $englishFileEntries; continue; } try { $resourceTranslatedParsed = $yaml->parse(file_get_contents($resourceTranslated)); } catch (ParseException $e) { $io->error($resourceTranslated . ':' . $e->getMessage()); } $diffStatistics = ['total' => 0, 'equal' => 0, 'diff' => 0]; $diff = $this->nestedArray->arrayDiff($englishFileParsed, $resourceTranslatedParsed, true, $diffStatistics); $yamlKeys = 0; if (!empty($diff)) { $diffFlatten = []; $keyFlatten = ''; $this->nestedArray->yamlFlattenArray($diff, $diffFlatten, $keyFlatten); // Determine how many yaml keys were returned as values foreach ($diffFlatten as $yamlKey => $yamlValue) { if ($this->isYamlKey($yamlValue)) { $yamlKeys++; } } } $statistics[$langCode]['total'] += $diffStatistics['total']; $statistics[$langCode]['equal'] += ($diffStatistics['equal'] - $yamlKeys); $statistics[$langCode]['diff'] += $diffStatistics['diff'] + $yamlKeys; } } $stats = []; foreach ($statistics as $langCode => $statistic) { $index = isset($languages[$langCode])? $languages[$langCode]: $langCode; $stats[] = [ 'name' => $index, 'percentage' => round($statistic['diff']/$statistic['total']*100, 2), 'iso' => $langCode ]; } usort( $stats, function ($a, $b) { return $a["percentage"] < $b["percentage"]; } ); return $stats; } }