diff --git a/src/Bundle/ChillMainBundle/Command/DetectTranslationDuplicatesCommand.php b/src/Bundle/ChillMainBundle/Command/DetectTranslationDuplicatesCommand.php
index 56ccebba2..16e0c0b24 100644
--- a/src/Bundle/ChillMainBundle/Command/DetectTranslationDuplicatesCommand.php
+++ b/src/Bundle/ChillMainBundle/Command/DetectTranslationDuplicatesCommand.php
@@ -15,118 +15,115 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Yaml\Yaml;
+use Symfony\Component\HttpKernel\KernelInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+use Symfony\Component\Console\Helper\Table;
class DetectTranslationDuplicatesCommand extends Command
{
protected static $defaultName = 'app:detect-duplicate-translations';
- private const string BASE_DIR = 'vendor/chill-project/chill-bundles';
+ public function __construct(private readonly TranslatorInterface $translator, private readonly KernelInterface $kernel)
+ {
+ parent::__construct();
+ }
protected function configure(): void
{
$this
->setDescription('Detects duplicate translations in YAML files.')
- ->addOption('path', null, InputOption::VALUE_REQUIRED, 'The directory or file path containing translation files', 'translations');
-// ->addOption('output', null, InputOption::VALUE_OPTIONAL, 'The file path to write the output to', 'php://stdout');
+ ->addOption('locale', null, InputOption::VALUE_REQUIRED, 'Locale to check for duplicate translations', 'en');
}
- protected function execute(InputInterface $input, OutputInterface $output)
+ protected function execute(InputInterface $input, OutputInterface $output): int
{
- $relativePath = $input->getOption('path');
- $basePath = self::BASE_DIR;
- $fullPath = $basePath . '/' . $relativePath;
+ $locale = $input->getOption('locale');
-// $outputPath = $input->getOption('output');
+ // Loop through all bundles and get the translation directories
+ foreach ($this->kernel->getBundles() as $bundle) {
+ $bundlePath = $bundle->getPath();
+ $translationDir = $this->getTranslationDirectory($bundle->getName(), $bundlePath);
- if (!file_exists($fullPath)) {
- $output->writeln("The path '$fullPath' does not exist.");
- return Command::FAILURE;
- }
-
- $translationMap = [];
-
- if (is_dir($fullPath)) {
- // Process all YAML files in the directory
- foreach (glob($fullPath . '/*.yaml') as $file) {
- $this->processFile($file, $translationMap);
+ if ($translationDir && is_dir($translationDir)) {
+ foreach (glob($translationDir . '/*.yaml') as $file) {
+ $this->translator->addResource('yaml', $file, $locale);
+ }
}
- } elseif (is_file($fullPath)) {
- // Process the specific YAML file
- $this->processFile($fullPath, $translationMap);
- } else {
- $output->writeln("The path '$fullPath' is neither a directory nor a file.");
- return Command::FAILURE;
}
- $duplicates = array_filter($translationMap, function($keys) {
+ $catalogue = $this->translator->getCatalogue($locale);
+
+ $allTranslations = [];
+
+ // Iterate through each domain in the catalogue
+ foreach ($catalogue->all() as $domain => $translations) {
+ foreach ($translations as $key => $value) {
+ if (is_array($value)) {
+ $this->flattenTranslation($value, "$domain.$key", $allTranslations);
+ } else {
+ if (!isset($allTranslations[$value])) {
+ $allTranslations[$value] = [];
+ }
+ $allTranslations[$value][] = "$domain.$key";
+ }
+ }
+ }
+
+ // Detect values that appear in more than one key
+ $duplicates = array_filter($allTranslations, function ($keys) {
return count($keys) > 1;
});
if (empty($duplicates)) {
- $output->writeln("No duplicate translations found.");
+ $output->writeln("No duplicate translations found for locale '$locale'.");
} else {
- $output->writeln("Duplicate translations found:");
- foreach ($duplicates as $translation => $keys) {
- $output->writeln("Translation: '$translation' is used in keys: " . implode(', ', $keys));
- }
- }
+ $output->writeln("Duplicate translations found for locale '$locale':");
-/* $outputText = "";
- if (empty($duplicates)) {
- $outputText .= "No duplicate translations found.\n";
- } else {
- $outputText .= "Duplicate translations found:\n";
- foreach ($duplicates as $translation => $keys) {
- $outputText .= "Translation: '$translation' is used in keys: " . implode(', ', $keys) . "\n";
- }
- }
+ // Display the duplicates in a table
+ $table = new Table($output);
+ $table->setHeaders(['Translation', 'Used in Keys']);
- // Write output to the specified file or to stdout
- if ($outputPath === 'php://stdout') {
- $output->writeln($outputText);
- } else {
- try {
- file_put_contents($outputPath, $outputText);
- $output->writeln("Output written to '$outputPath'");
- } catch (\Exception $e) {
- $output->writeln("Failed to write to '$outputPath': " . $e->getMessage() . "");
- return Command::FAILURE;
+ foreach ($duplicates as $translation => $keys) {
+ $wrappedTranslation = $this->wrapText($translation, 40);
+ $wrappedKeys = $this->wrapText(implode(', ', $keys), 80);
+
+ $table->addRow([$wrappedTranslation, $wrappedKeys]);
}
- }*/
+
+ $table->render();
+ }
return Command::SUCCESS;
}
- private function processFile($file, &$translationMap): void
+ private function flattenTranslation(array $translations, string $prefix, array &$allTranslations): void
{
- try {
- $translations = Yaml::parseFile($file);
-
- // Flatten the array to handle nested keys
- $this->flattenArray($translations, '', $translationMap);
-
- } catch (\Exception $e) {
- // Handle YAML parsing exceptions
- // You might want to log the error or notify the user
- }
- }
-
- private function flattenArray(array $array, $prefix, &$translationMap): void
- {
- foreach ($array as $key => $value) {
- $fullKey = $prefix ? $prefix . '.' . $key : $key;
+ foreach ($translations as $key => $value) {
+ $fullKey = "$prefix.$key";
if (is_array($value)) {
- // Recursively process nested arrays
- $this->flattenArray($value, $fullKey, $translationMap);
+ $this->flattenTranslation($value, $fullKey, $allTranslations);
} else {
- // Handle translation value
- if (isset($translationMap[$value])) {
- $translationMap[$value][] = $fullKey;
- } else {
- $translationMap[$value] = [$fullKey];
+ if (!isset($allTranslations[$value])) {
+ $allTranslations[$value] = [];
}
+ $allTranslations[$value][] = $fullKey;
}
}
}
+
+ private function getTranslationDirectory(string $bundleName, string $bundlePath): ?string
+ {
+ $translationDir = $bundlePath . '/translations';
+
+ if ($bundleName === 'ChillAsideActivityBundle') {
+ $translationDir = $bundlePath . '/src/translations';
+ }
+
+ return is_dir($translationDir) ? $translationDir : null;
+ }
+
+ private function wrapText(string $text, int $width): string
+ {
+ return wordwrap($text, $width, "\n", true);
+ }
}