Completed
Pull Request — master (#1)
by Pascal
12:57
created

TranslationConverterCommand::execute()   C

Complexity

Conditions 12
Paths 52

Size

Total Lines 59
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 13.5797

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 59
ccs 28
cts 36
cp 0.7778
rs 6.4485
cc 12
eloc 33
nc 52
nop 2
crap 13.5797

How to fix   Long Method    Complexity   

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
namespace Itkg\TranslationBundle\Command;
4
5
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6
use Symfony\Component\Console\Input\InputOption;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\Filesystem\Filesystem;
10
use Symfony\Component\Finder\Finder;
11
use Symfony\Component\Translation\MessageCatalogue;
12
use Symfony\Component\Translation\Writer\TranslationWriter;
13
14
/**
15
 * Class TranslationConverterCommand
16
 */
17
class TranslationConverterCommand extends ContainerAwareCommand
18
{
19
    /**
20
     * @var Finder
21
     */
22
    protected $finder;
23
24
    /**
25
     * @var Filesystem
26
     */
27
    protected $filesystem;
28
29
    /**
30
     * @param Finder      $finder
31
     * @param Filesystem  $filesystem
32
     * @param null|string $name
33
     */
34 2
    public function __construct(Finder $finder, Filesystem $filesystem, $name = null)
35
    {
36 2
        $this->finder = $finder;
37 2
        $this->filesystem = $filesystem;
38
39 2
        parent::__construct($name);
40 2
    }
41
42
    /**
43
     * {@inheritDoc}
44
     */
45 2
    protected function configure()
46
    {
47 2
        parent::configure();
48
49 2
        $this
50 2
            ->setName('itkg:translation:convert')
51 2
            ->setDescription('Translation convert command from an input format to another format')
52 2
            ->setHelp('You must specify a path using the --path option.')
53 2
            ->addOption('path', null, InputOption::VALUE_REQUIRED, 'Specify a path of files')
54 2
            ->addOption('input', null, InputOption::VALUE_REQUIRED, 'Specifiy a input translation format')
55 2
            ->addOption('output', null, InputOption::VALUE_OPTIONAL, 'Specifiy an output translation format (default: xliff)')
56 2
            ->addOption('domain', null, InputOption::VALUE_OPTIONAL, 'All domains if not specified')
57 2
            ->addOption('output-path', null, InputOption::VALUE_OPTIONAL, 'Specify a path of output translations');
58 2
    }
59
60
    /**
61
     * {@inheritDoc}
62
     */
63 2
    protected function execute(InputInterface $input, OutputInterface $output)
64
    {
65 2
        $path = $input->getOption('path');
66 2
        $inputFormat = $input->getOption('input');
67 2
        $outputFormat = $input->getOption('output') ?: 'xliff';
68
69 2
        $catalogs = [];
70
71 2
        if (!$inputFormat) {
72
            throw new \InvalidArgumentException('You must specify a --input format option.');
73
        }
74
75 2
        if (!$path || !$this->filesystem->exists($path)) {
76
            throw new \InvalidArgumentException('You must specify a valid --path option.');
77
        }
78
79 2
        $dumper = $this->getDumper($outputFormat);
80 2
        $this->getTranslationWriter()->addDumper($outputFormat, $dumper);
81
82 2
        $files = $this->finder->files()->name('/[a-z]+\.[a-z]{2}\.'.$inputFormat.'/')->in($path);
83
84 2
        foreach ($files as $file) {
85 2
            list($domain, $language) = explode('.', $file->getFilename());
86 2
            if ($input->getOption('domain') && $domain !== $input->getOption('domain')) {
87
                continue;
88
            }
89 2
            $output->writeln(sprintf('Starts importing file %s', $file->getRealPath()));
90
            try {
91 2
                $msgCatalog = $this->getLoader($inputFormat)->load($file->getRealPath(), $language, $domain);
92
93 2
                $messages = $msgCatalog->all();
94
95 2
                if (!$messages) {
96
                    $output->writeln('No translations found in this file.');
97
98
                    continue;
99
                }
100
101 2
                if (isset($catalogs[$language])) {
102
                    $catalogs[$language]->addCatalogue($msgCatalog);
103
                } else {
104 2
                    $catalogs[$language] = $msgCatalog;
105
                }
106
107 2
                $output->writeln('Translation file saved.');
108 2
            } catch (\Exception $e) {
109
                $output->writeln(sprintf('An error has occured while trying to write translations: %s', $e->getMessage()));
110
            }
111 2
        }
112
113
        /** @var MessageCatalogue $catalog */
114 2
        foreach ($catalogs as $catalog) {
115 2
            $this->getTranslationWriter()->writeTranslations($catalog, $outputFormat, array(
116 2
                    'path' => $this->getTranslationPath($input->getOption('output-path')))
117 2
            );
118 2
        }
119
120
121 2
    }
122
123
    /**
124
     * Returns Symfony translation writer service
125
     *
126
     * @return TranslationWriter
127
     */
128 2
    protected function getTranslationWriter()
129
    {
130 2
        return $this->getContainer()->get('translation.writer');
131
    }
132
133
    /**
134
     * Returns Symfony requested format loader
135
     *
136
     * @param string $format
137
     *
138
     * @return \Symfony\Component\Translation\Loader\LoaderInterface
139
     *
140
     * @throws \InvalidArgumentException
141
     */
142 2 View Code Duplication
    protected function getLoader($format)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
    {
144 2
        $service = sprintf('translation.loader.%s', $format);
145
146 2
        if (!$this->getContainer()->has($service)) {
147
            throw new \InvalidArgumentException(sprintf('Unable to find Symfony Translation loader for format "%s"', $format));
148
        }
149
150 2
        return $this->getContainer()->get($service);
151
    }
152
153
    /**
154
     * Returns Symfony requested format dumper
155
     *
156
     * @param string $format
157
     *
158
     * @return \Symfony\Component\Translation\Dumper\DumperInterface
159
     *
160
     * @throws \InvalidArgumentException
161
     */
162 2 View Code Duplication
    protected function getDumper($format)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
    {
164 2
        $service = sprintf('translation.dumper.%s', $format);
165
166 2
        if (!$this->getContainer()->has($service)) {
167
            throw new \InvalidArgumentException(sprintf('Unable to find Symfony Translation dumper for format "%s"', $format));
168
        }
169
170 2
        return $this->getContainer()->get($service);
171
    }
172
173
    /**
174
     * Returns translation path
175
     *
176
     * @param string $outputPath
177
     *
178
     * @return string
179
     */
180 2
    protected function getTranslationPath($outputPath = null)
181
    {
182 2
        if ($outputPath) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $outputPath of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
183 2
            return $outputPath;
184
        }
185
186
        return $this->getContainer()->get('kernel')->getRootDir() . '/Resources/translations';
187
    }
188
}
189