mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-09 16:24:59 +00:00
Revert "Merge branch 'manage-translations' into 'master'"
This reverts commitcd99633d15
, reversing changes made toa9384bf734
.
This commit is contained in:
@@ -1,181 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\HttpKernel\KernelInterface;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
|
||||
class DetectTranslationDuplicatesCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'chill:detect-duplicate-translations';
|
||||
|
||||
public function __construct(private readonly Translator $translator, private readonly KernelInterface $kernel)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
->setDescription('Detects duplicate translations in YAML files.')
|
||||
->addOption('locale', null, InputOption::VALUE_REQUIRED, 'Locale to check for duplicate translations', 'en')
|
||||
->addOption('exclude-namespaces', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'Namespaces to exclude from duplicate detection', [])
|
||||
->addArgument('verify-hash', InputArgument::OPTIONAL, 'The expected hash to verify translation integrity');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$locale = $input->getOption('locale');
|
||||
$excludedNamespaces = $input->getOption('exclude-namespaces');
|
||||
$expectedHash = $input->getArgument('verify-hash');
|
||||
|
||||
// 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 (null !== $translationDir && is_dir($translationDir)) {
|
||||
foreach (glob($translationDir.'/*.yaml') as $file) {
|
||||
$this->translator->addResource('yaml', $file, $locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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 ($this->isExcludedNamespace("{$domain}.{$key}", $excludedNamespaces)) {
|
||||
continue;
|
||||
}
|
||||
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, fn ($keys) => count($keys) > 1);
|
||||
|
||||
$duplicatesHash = $this->generateDuplicatesHash($duplicates);
|
||||
|
||||
if ('' !== $expectedHash) {
|
||||
if ($duplicatesHash === $expectedHash) {
|
||||
$output->writeln('<info>Translations are consistent with the expected hash.</info>');
|
||||
|
||||
$output->writeln("<info>Current duplicate hash: {$duplicatesHash}</info>");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
$output->writeln('<error>Translation hash mismatch! Potential duplicate added.</error>');
|
||||
$this->renderDuplicatesTable($output, $duplicates, $locale);
|
||||
|
||||
$output->writeln("<info>Current duplicate hash: {$duplicatesHash}</info>");
|
||||
|
||||
return Command::FAILURE;
|
||||
|
||||
}
|
||||
|
||||
$this->renderDuplicatesTable($output, $duplicates, $locale);
|
||||
|
||||
$output->writeln("<info>Current duplicate hash: {$duplicatesHash}</info>");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function flattenTranslation(array $translations, string $prefix, array &$allTranslations): void
|
||||
{
|
||||
foreach ($translations as $key => $value) {
|
||||
$fullKey = "{$prefix}.{$key}";
|
||||
if (is_array($value)) {
|
||||
$this->flattenTranslation($value, $fullKey, $allTranslations);
|
||||
} else {
|
||||
if (!isset($allTranslations[$value])) {
|
||||
$allTranslations[$value] = [];
|
||||
}
|
||||
$allTranslations[$value][] = $fullKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getTranslationDirectory(string $bundleName, string $bundlePath): ?string
|
||||
{
|
||||
$translationDir = $bundlePath.'/translations';
|
||||
|
||||
if ('ChillAsideActivityBundle' === $bundleName) {
|
||||
$translationDir = $bundlePath.'/src/translations';
|
||||
}
|
||||
|
||||
return is_dir($translationDir) ? $translationDir : null;
|
||||
}
|
||||
|
||||
private function wrapText(string $text, int $width): string
|
||||
{
|
||||
return wordwrap($text, $width, "\n", true);
|
||||
}
|
||||
|
||||
private function isExcludedNamespace(string $key, array $excludedNamespaces): bool
|
||||
{
|
||||
foreach ($excludedNamespaces as $namespace) {
|
||||
if (str_starts_with($key, (string) $namespace)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function generateDuplicatesHash(array $duplicates): string
|
||||
{
|
||||
ksort($duplicates);
|
||||
foreach ($duplicates as $translation => $keys) {
|
||||
sort($keys);
|
||||
}
|
||||
|
||||
return hash('md5', serialize($duplicates));
|
||||
}
|
||||
|
||||
private function renderDuplicatesTable(OutputInterface $output, array $duplicates, string $locale): void
|
||||
{
|
||||
if ([] === $duplicates) {
|
||||
$output->writeln("<info>No duplicate translations found for locale '{$locale}'.</info>");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln("<comment>Duplicate translations found for locale '{$locale}':</comment>");
|
||||
$table = new Table($output);
|
||||
$table->setHeaders(['Translation', 'Used in Keys']);
|
||||
|
||||
foreach ($duplicates as $translation => $keys) {
|
||||
$wrappedTranslation = $this->wrapText($translation, 40);
|
||||
$wrappedKeys = $this->wrapText(implode(', ', $keys), 80);
|
||||
$table->addRow([$wrappedTranslation, $wrappedKeys]);
|
||||
}
|
||||
|
||||
$table->render();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user