Completed
Push — master ( 380f31...e108fc )
by Pascal
13:31 queued 08:36
created

TranslationConverterCommand   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 172
Duplicated Lines 11.63 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 84.06%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 21
c 1
b 0
f 0
lcom 1
cbo 10
dl 20
loc 172
ccs 58
cts 69
cp 0.8406
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A configure() 0 14 1
C execute() 0 59 12
A getTranslationWriter() 0 4 1
A getLoader() 10 10 2
A getDumper() 10 10 2
A getTranslationPath() 0 8 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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