ImportTranslationsCommand::generateCatalogues()   B
last analyzed

Complexity

Conditions 8
Paths 9

Size

Total Lines 55
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 55
ccs 0
cts 39
cp 0
rs 7.4033
cc 8
eloc 32
nc 9
nop 1
crap 72

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the AsmTranslationLoaderBundle package.
5
 *
6
 * (c) Marc Aschmann <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Asm\TranslationLoaderBundle\Command;
13
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Symfony\Component\Finder\Finder;
17
use Symfony\Component\Finder\SplFileInfo;
18
use Symfony\Component\Translation\MessageCatalogue;
19
use Symfony\Component\Translation\MessageCatalogueInterface;
20
21
/**
22
 * Class DumpTranslationFiles
23
 *
24
 * @package Asm\TranslationLoaderBundle\Command
25
 * @author marc aschmann <[email protected]>
26
 * @uses Symfony\Component\Console\Input\InputArgument
27
 * @uses Symfony\Component\Console\Input\InputInterface
28
 * @uses Symfony\Component\Console\Input\InputOption
29
 * @uses Symfony\Component\Console\Output\OutputInterface
30
 * @uses Symfony\Component\Translation\Catalogue\DiffOperation
31
 * @uses Symfony\Component\Translation\Catalogue\MergeOperation
32
 * @uses Symfony\Component\Translation\MessageCatalogue
33
 * @uses Symfony\Component\Finder\Finder
34
 * @uses Asm\TranslationLoaderBundle\Entity\Translation
35
 */
36
class ImportTranslationsCommand extends BaseTranslationCommand
37
{
38
    /**
39
     * message catalogue container
40
     *
41
     * @var MessageCatalogueInterface[]
42
     */
43
    private $catalogues = array();
44
45
    /**
46
     * {@inheritDoc}
47
     */
48 6
    protected function configure()
49
    {
50 6
        $this
51 6
            ->setName('asm:translations:import')
52 6
            ->setDescription('Import translations from all bundles')
53 6
            ->addOption(
54 6
                'clear',
55 6
                'c',
56 6
                null,
57
                'clear database before import'
58 6
            );
59 6
    }
60
61
62
    /**
63
     * {@inheritDoc}
64
     */
65
    protected function execute(InputInterface $input, OutputInterface $output)
66
    {
67
        $output->writeln(
68
            '<info>--------------------------------------------------------------------------------</info>'
69
        );
70
        $output->writeln('<info>Translation file importer</info>');
71
        $output->writeln(
72
            '<info>--------------------------------------------------------------------------------</info>'
73
        );
74
        $output->writeln('<info>importing all available translation files ...</info>');
75
76
        if ($input->getOption('clear')) {
77
            $output->writeln('<comment>deleting all translations from database...</comment>');
78
            $output->writeln(
79
                '<info>--------------------------------------------------------------------------------</info>'
80
            );
81
            $output->writeln('');
82
83
            $translationManager = $this->getTranslationManager();
84
            $translations       = $translationManager->findAllTranslations();
85
            foreach ($translations as $translation) {
86
                $translationManager->removeTranslation($translation);
87
            }
88
        }
89
90
        $this->generateCatalogues($output);
91
        $this->importCatalogues($output);
92
93
        $output->writeln(
94
            '<info>--------------------------------------------------------------------------------</info>'
95
        );
96
        $output->writeln('<comment>finished!</comment>');
97
    }
98
99
100
    /**
101
     * iterate all bundles and generate a message catalogue for each locale
102
     *
103
     * @param OutputInterface $output
104
     * @throws \ErrorException
105
     */
106
    private function generateCatalogues($output)
107
    {
108
        $translationWriter = $this->getTranslationWriter();
109
        $supportedFormats  = $translationWriter->getFormats();
110
111
        // iterate all bundles and get their translations
112
        foreach (array_keys($this->getContainer()->getParameter('kernel.bundles')) as $bundle) {
113
            $currentBundle   = $this->getKernel()->getBundle($bundle);
114
            $translationPath = $currentBundle->getPath() . '/Resources/translations';
115
116
            // load any existing translation files
117
            if (is_dir($translationPath)) {
118
                $output->writeln('<info>searching ' . $bundle . ' translations</info>');
119
                $output->writeln(
120
                    '<info>--------------------------------------------------------------------------------</info>'
121
                );
122
123
                $finder = new Finder();
124
                $files  = $finder
125
                    ->files()
126
                    ->in($translationPath);
127
128
                foreach ($files as $file) {
129
                    /** @var SplFileInfo $file */
130
                    $extension = explode('.', $file->getFilename());
131
                    // domain.locale.extension
132
                    if (3 == count($extension)) {
133
                        $fileExtension = array_pop($extension);
134
                        if (in_array($fileExtension, $supportedFormats)) {
135
                            $locale = array_pop($extension);
136
                            $domain = array_pop($extension);
137
138
                            if (empty($this->catalogues[$locale])) {
139
                                $this->catalogues[$locale] = new MessageCatalogue($locale);
140
                            }
141
142
                            $fileLoader = $this->getFileLoaderResolver()->resolveLoader($fileExtension);
143
144
                            if (null === $fileLoader) {
145
                                throw new \ErrorException('could not find loader for ' . $fileExtension . ' files!');
146
                            }
147
148
                            $output->writeln(
149
                                '<comment>loading ' . $file->getFilename(
150
                                ) . ' with locale ' . $locale . ' and domain ' . $domain . '</comment>'
151
                            );
152
                            $currentCatalogue = $fileLoader->load($file->getPathname(), $locale, $domain);
153
                            $this->catalogues[$locale]->addCatalogue($currentCatalogue);
154
                        }
155
                    }
156
                }
157
                $output->writeln('');
158
            }
159
        }
160
    }
161
162
163
    /**
164
     * look through the catalogs and store them to database
165
     *
166
     * @param OutputInterface $output
167
     */
168
    private function importCatalogues($output)
169
    {
170
        $translationManager = $this->getTranslationManager();
171
172
        $output->writeln('<info>inserting all translations</info>');
173
        $output->writeln(
174
            '<info>--------------------------------------------------------------------------------</info>'
175
        );
176
177
        foreach ($this->catalogues as $locale => $catalogue) {
178
179
            $output->write('<comment>' . $locale . ': </comment>');
180
            foreach ($catalogue->getDomains() as $domain) {
181
                foreach ($catalogue->all($domain) as $key => $message) {
182
                    if ('' !== $key) {
183
                        $translation = $translationManager->findTranslationBy(
184
                            array(
185
                                'transKey'      => $key,
186
                                'transLocale'   => $locale,
187
                                'messageDomain' => $domain,
188
                            )
189
                        );
190
191
                        if (!$translation) {
192
                            // create a new translation if no entry does exist yet
193
                            $translation = $translationManager->createTranslation();
194
                            $translation->setTransKey($key);
195
                            $translation->setTransLocale($locale);
196
                            $translation->setMessageDomain($domain);
197
                            $translation->setTranslation($message);
198
                            $translationManager->updateTranslation($translation);
199
                        } elseif ($translation->getTranslation() != $message) {
200
                            // update only if we've got a changed message
201
                            $translation->setTranslation($message);
202
                            $translationManager->updateTranslation($translation);
203
                        }
204
                    }
205
                }
206
                $output->write('<info> ... ' . $domain . '.' . $locale . '</info>');
207
                // force garbage collection
208
                gc_collect_cycles();
209
            }
210
            $output->writeln('');
211
        }
212
    }
213
214
    /**
215
     * @return \Asm\TranslationLoaderBundle\Translation\FileLoaderResolver
216
     */
217
    private function getFileLoaderResolver()
218
    {
219
        return $this->getContainer()->get('asm_translation_loader.file_loader_resolver');
220
    }
221
}
222