CheckMissingCommand   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
c 1
b 0
f 0
dl 0
loc 126
ccs 0
cts 77
cp 0
rs 10
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfiguredFinder() 0 14 3
A execute() 0 45 3
A __construct() 0 12 1
A configure() 0 7 1
A countEmptyTranslations() 0 16 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Translation\Bundle\Command;
6
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Style\SymfonyStyle;
12
use Symfony\Component\Finder\Finder;
13
use Symfony\Component\Translation\MessageCatalogueInterface;
14
use Translation\Bundle\Catalogue\CatalogueCounter;
15
use Translation\Bundle\Catalogue\CatalogueFetcher;
16
use Translation\Bundle\Model\Configuration;
17
use Translation\Bundle\Service\ConfigurationManager;
18
use Translation\Bundle\Service\Importer;
19
20
final class CheckMissingCommand extends Command
21
{
22
    protected static $defaultName = 'translation:check-missing';
23
24
    /**
25
     * @var ConfigurationManager
26
     */
27
    private $configurationManager;
28
29
    /**
30
     * @var CatalogueFetcher
31
     */
32
    private $catalogueFetcher;
33
34
    /**
35
     * @var Importer
36
     */
37
    private $importer;
38
39
    /**
40
     * @var CatalogueCounter
41
     */
42
    private $catalogueCounter;
43
44
    public function __construct(
45
        ConfigurationManager $configurationManager,
46
        CatalogueFetcher $catalogueFetcher,
47
        Importer $importer,
48
        CatalogueCounter $catalogueCounter
49
    ) {
50
        parent::__construct();
51
52
        $this->configurationManager = $configurationManager;
53
        $this->catalogueFetcher = $catalogueFetcher;
54
        $this->importer = $importer;
55
        $this->catalogueCounter = $catalogueCounter;
56
    }
57
58
    protected function configure(): void
59
    {
60
        $this
61
            ->setName(self::$defaultName)
62
            ->setDescription('Check that all translations for a given locale are extracted.')
63
            ->addArgument('locale', InputArgument::REQUIRED, 'The locale to check')
64
            ->addArgument('configuration', InputArgument::OPTIONAL, 'The configuration to use', 'default');
65
    }
66
67
    protected function execute(InputInterface $input, OutputInterface $output): int
68
    {
69
        $config = $this->configurationManager->getConfiguration($input->getArgument('configuration'));
70
71
        $locale = $input->getArgument('locale');
72
73
        $catalogues = $this->catalogueFetcher->getCatalogues($config, [$locale]);
74
        $finder = $this->getConfiguredFinder($config);
75
76
        $result = $this->importer->extractToCatalogues(
77
            $finder,
78
            $catalogues,
79
            [
80
                'blacklist_domains' => $config->getBlacklistDomains(),
81
                'whitelist_domains' => $config->getWhitelistDomains(),
82
                'project_root' => $config->getProjectRoot(),
83
            ]
84
        );
85
86
        $definedBefore = $this->catalogueCounter->getNumberOfDefinedMessages($catalogues[0]);
87
        $definedAfter = $this->catalogueCounter->getNumberOfDefinedMessages($result->getMessageCatalogues()[0]);
88
89
        $newMessages = $definedAfter - $definedBefore;
90
91
        $io = new SymfonyStyle($input, $output);
92
93
        if ($newMessages > 0) {
94
            $io->error(\sprintf('%d new message(s) have been found, run bin/console translation:extract', $newMessages));
95
96
            return 1;
97
        }
98
99
        $emptyTranslations = $this->countEmptyTranslations($result->getMessageCatalogues()[0]);
100
101
        if ($emptyTranslations > 0) {
102
            $io->error(
103
                \sprintf('%d messages have empty translations, please provide translations for them', $emptyTranslations)
104
            );
105
106
            return 1;
107
        }
108
109
        $io->success('No new translation messages');
110
111
        return 0;
112
    }
113
114
    private function getConfiguredFinder(Configuration $config): Finder
115
    {
116
        $finder = new Finder();
117
        $finder->in($config->getDirs());
118
119
        foreach ($config->getExcludedDirs() as $exclude) {
120
            $finder->notPath($exclude);
121
        }
122
123
        foreach ($config->getExcludedNames() as $exclude) {
124
            $finder->notName($exclude);
125
        }
126
127
        return $finder;
128
    }
129
130
    private function countEmptyTranslations(MessageCatalogueInterface $catalogue): int
131
    {
132
        $total = 0;
133
134
        foreach ($catalogue->getDomains() as $domain) {
135
            $emptyTranslations = \array_filter(
136
                $catalogue->all($domain),
137
                function (string $message = null): bool {
138
                    return null === $message || '' === $message;
139
                }
140
            );
141
142
            $total += \count($emptyTranslations);
143
        }
144
145
        return $total;
146
    }
147
}
148