Completed
Push — master ( b453a3...b1e9d6 )
by Ruud
40:05 queued 27:14
created

ImportCommandHandler   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 259
Duplicated Lines 12.74 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 40.96%

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 4
dl 33
loc 259
ccs 34
cts 83
cp 0.4096
rs 9.52
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A importAllBundlesTranslationFiles() 17 17 3
A importOwnBundlesTranslationFiles() 0 19 4
A importCustomBundlesTranslationFiles() 16 16 3
A importSingleBundleTranslationFiles() 0 12 2
A validateBundleName() 0 11 2
A determineLocalesToImport() 0 8 3
A setTranslationFileExplorer() 0 4 1
A setImporter() 0 4 1
A executeImportCommand() 0 8 4
A importGlobalTranslationFiles() 0 9 3
A importBundleTranslationFiles() 0 22 5
A importTranslationFiles() 0 14 3
A importSf4TranslationFiles() 0 10 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 Kunstmaan\TranslatorBundle\Service\Command\Importer;
4
5
use Kunstmaan\TranslatorBundle\Model\Import\ImportCommand;
6
use Kunstmaan\TranslatorBundle\Service\Command\AbstractCommandHandler;
7
use Kunstmaan\TranslatorBundle\Service\Exception\TranslationsNotFoundException;
8
use Kunstmaan\TranslatorBundle\Service\TranslationFileExplorer;
9
use Symfony\Component\Finder\Finder;
10
use Symfony\Component\HttpKernel\Kernel;
11
12
/**
13
 * Parses an ImportCommand
14
 */
15
class ImportCommandHandler extends AbstractCommandHandler
16
{
17
    /**
18
     * TranslationFileExplorer
19
     *
20
     * @var TranslationFileExplorer
21
     */
22
    private $translationFileExplorer;
23
24
    /**
25
     * Importer
26
     *
27
     * @var Importer
28
     */
29
    private $importer;
30
31
    /**
32
     * Execute an import command
33
     *
34
     * @param ImportCommand $importCommand
35
     *
36
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be false|integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
37
     */
38 1
    public function executeImportCommand(ImportCommand $importCommand)
39
    {
40 1
        if ($importCommand->getGlobals() || $importCommand->getDefaultBundle() === false || $importCommand->getDefaultBundle() === null) {
41 1
            return $this->importGlobalTranslationFiles($importCommand);
42
        }
43
44
        return $this->importBundleTranslationFiles($importCommand);
45
    }
46
47
    /**
48
     * Import all translation files from app resources
49
     *
50
     * @param ImportCommand $importCommand
51
     *
52
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be false|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
53
     */
54 1
    private function importGlobalTranslationFiles(ImportCommand $importCommand)
55
    {
56 1
        $baseDir = Kernel::VERSION_ID >= 40000 ? $this->kernel->getProjectDir() : $this->kernel->getRootDir();
57 1
        $translationsDir = Kernel::VERSION_ID >= 40000 ? 'translations' : null;
58 1
        $locales = $this->determineLocalesToImport($importCommand);
59 1
        $finder = $this->translationFileExplorer->find($baseDir, $locales, $translationsDir);
60
61 1
        return $this->importTranslationFiles($finder, $importCommand->getForce());
62
    }
63
64
    /**
65
     * Import all translation files from a specific bundle, bundle name will be lowercased so cases don't matter
66
     *
67
     * @param ImportCommand $importCommand
68
     *
69
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
70
     */
71 1
    public function importBundleTranslationFiles(ImportCommand $importCommand)
72
    {
73 1
        $importBundle = strtolower($importCommand->getDefaultBundle());
74
75 1
        if ($importBundle == 'all') {
76
            $importCount = $this->importAllBundlesTranslationFiles($importCommand);
77
78
            if (Kernel::VERSION_ID >= 40000) {
79
                $importCount += $this->importSf4TranslationFiles($importCommand);
80
            }
81
82
            return $importCount;
83 1
        } elseif ($importBundle == 'custom') {
84
            return $this->importCustomBundlesTranslationFiles($importCommand);
85
        } else {
86 1
            if (Kernel::VERSION_ID >= 40000) {
87 1
                return $this->importSf4TranslationFiles($importCommand);
88
            }
89
90
            return $this->importOwnBundlesTranslationFiles($importCommand);
91
        }
92
    }
93
94
    /**
95
     * Import all translation files from all registered bundles (in AppKernel)
96
     *
97
     * @param ImportCommand $importCommand
98
     *
99
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
100
     */
101 View Code Duplication
    private function importAllBundlesTranslationFiles(ImportCommand $importCommand)
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...
102
    {
103
        $bundles = array_map('strtolower', array_keys($this->kernel->getBundles()));
104
        $imported = 0;
105
106
        foreach ($bundles as $bundle) {
107
            $importCommand->setDefaultBundle($bundle);
108
109
            try {
110
                $imported += $this->importSingleBundleTranslationFiles($importCommand);
111
            } catch (TranslationsNotFoundException $e) {
112
                continue;
113
            }
114
        }
115
116
        return $imported;
117
    }
118
119
    /**
120
     * Import all translation files from your own registered bundles (in src/ directory)
121
     *
122
     * @param ImportCommand $importCommand
123
     *
124
     * @return int The total number of imported files
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
125
     */
126
    private function importOwnBundlesTranslationFiles(ImportCommand $importCommand)
127
    {
128
        $imported = 0;
129
        $srcDir = dirname($this->kernel->getRootDir()) . '/src';
130
131
        foreach ($this->kernel->getBundles() as $name => $bundle) {
132
            if (strpos($bundle->getPath(), $srcDir) !== false) {
133
                $importCommand->setDefaultBundle(strtolower($name));
134
135
                try {
136
                    $imported += $this->importSingleBundleTranslationFiles($importCommand);
137
                } catch (TranslationsNotFoundException $e) {
138
                    continue;
139
                }
140
            }
141
        }
142
143
        return $imported;
144
    }
145
146
    /**
147
     * Import the translation files from the defined bundles.
148
     *
149
     * @param ImportCommand $importCommand
150
     *
151
     * @return int The total number of imported files
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
152
     */
153 View Code Duplication
    private function importCustomBundlesTranslationFiles(ImportCommand $importCommand)
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...
154
    {
155
        $imported = 0;
156
157
        foreach ($importCommand->getBundles() as $bundle) {
158
            $importCommand->setDefaultBundle(strtolower($bundle));
159
160
            try {
161
                $imported += $this->importSingleBundleTranslationFiles($importCommand);
162
            } catch (TranslationsNotFoundException $e) {
163
                continue;
164
            }
165
        }
166
167
        return $imported;
168
    }
169
170
    /**
171
     * Import all translation files from a single bundle
172
     *
173
     * @param ImportCommand $importCommand
174
     *
175
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
176
     */
177
    private function importSingleBundleTranslationFiles(ImportCommand $importCommand)
178
    {
179
        $this->validateBundleName($importCommand->getDefaultBundle());
0 ignored issues
show
Documentation introduced by
$importCommand->getDefaultBundle() is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
        $bundles = array_change_key_case($this->kernel->getBundles(), CASE_LOWER);
181
        $finder = $this->translationFileExplorer->find($bundles[strtolower($importCommand->getDefaultBundle())]->getPath(), $this->determineLocalesToImport($importCommand));
182
183
        if ($finder === null) {
184
            return 0;
185
        }
186
187
        return $this->importTranslationFiles($finder, $importCommand->getForce());
188
    }
189
190
    /**
191
     * Import translation files from a specific Finder object
192
     * The finder object shoud already have the files to look for defined;
193
     * Forcing the import will override all existing translations in the stasher
194
     *
195
     * @param Finder $finder
196
     * @param bool   $force  override identical translations in the stasher (domain/locale and keyword combination)
197
     *
198
     * @return int total number of files imported
0 ignored issues
show
Documentation introduced by
Should the return type not be false|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
199
     */
200 2
    private function importTranslationFiles(Finder $finder, $force = flase)
201
    {
202 2
        if (!$finder instanceof Finder) {
203
            return false;
204
        }
205
206 2
        $imported = 0;
207
208 2
        foreach ($finder as $file) {
209 2
            $imported += $this->importer->import($file, $force);
210
        }
211
212 2
        return $imported;
213
    }
214
215
    /**
216
     * Validates that a bundle is registered in the AppKernel
217
     *
218
     * @param string $bundle
219
     *
220
     * @return bool bundle is valid or not
221
     *
222
     * @throws \Exception If the bundlename isn't valid
223
     */
224
    public function validateBundleName($bundle)
225
    {
226
        // strtolower all bundle names
227
        $bundles = array_map('strtolower', array_keys($this->kernel->getBundles()));
228
229
        if (in_array(strtolower(trim($bundle)), $bundles)) {
230
            return true;
231
        }
232
233
        throw new \Exception(sprintf('bundle "%s" not found in available bundles: %s', $bundle, implode(', ', $bundles)));
234
    }
235
236
    /**
237
     * Gives an array with all languages that needs to be imported (from the given ImportCommand)
238
     * If non is given, all managed locales will be used (defined in config)
239
     *
240
     * @param ImportCommand $importCommand
241
     *
242
     * @return array all locales to import by the given ImportCommand
243
     */
244 3
    public function determineLocalesToImport(ImportCommand $importCommand)
245
    {
246 3
        if ($importCommand->getLocales() === false || $importCommand->getLocales() === null) {
247 3
            return $this->managedLocales;
248
        }
249
250
        return $this->parseRequestedLocales($importCommand->getLocales());
0 ignored issues
show
Documentation introduced by
$importCommand->getLocales() is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
251
    }
252
253 6
    public function setTranslationFileExplorer($translationFileExplorer)
254
    {
255 6
        $this->translationFileExplorer = $translationFileExplorer;
256 6
    }
257
258 6
    public function setImporter($importer)
259
    {
260 6
        $this->importer = $importer;
261 6
    }
262
263 1
    private function importSf4TranslationFiles($importCommand)
264
    {
265 1
        $finder = $this->translationFileExplorer->find($this->kernel->getProjectDir(), $this->determineLocalesToImport($importCommand), 'translations');
266
267 1
        if ($finder === null) {
268
            return 0;
269
        }
270
271 1
        return $this->importTranslationFiles($finder, $importCommand->getForce());
272
    }
273
}
274