Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

Service/Command/Importer/ImportCommandHandler.php (11 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
     * @return int total number of files imported
0 ignored issues
show
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...
35
     */
36 1
    public function executeImportCommand(ImportCommand $importCommand)
37
    {
38 1
        $amount = 0;
39 1
        $defaultBundleNotSet = $importCommand->getDefaultBundle() === false || $importCommand->getDefaultBundle() === null;
40
41 1
        if ($importCommand->getGlobals()) {
42 1
            $amount = $this->importGlobalTranslationFiles($importCommand);
43 1
            if ($defaultBundleNotSet) {
44 1
                return $amount;
45
            }
46
        }
47
48
        if ($defaultBundleNotSet) {
49
            $importCommand->setDefaultBundle('all');
50
        }
51
52
        $amount += $this->importBundleTranslationFiles($importCommand);
53
54
        return $amount;
55
    }
56
57
    /**
58
     * Import all translation files from app resources
59
     *
60
     * @return int total number of files imported
0 ignored issues
show
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...
61
     */
62 1
    private function importGlobalTranslationFiles(ImportCommand $importCommand)
63
    {
64 1
        $baseDir = Kernel::VERSION_ID >= 40000 ? $this->kernel->getProjectDir() : $this->kernel->getRootDir();
65 1
        $translationsDir = Kernel::VERSION_ID >= 40000 ? 'translations' : null;
66 1
        $locales = $this->determineLocalesToImport($importCommand);
67 1
        $finder = $this->translationFileExplorer->find($baseDir, $locales, $translationsDir);
68
69 1
        return $this->importTranslationFiles($finder, $importCommand->getForce());
70
    }
71
72
    /**
73
     * Import all translation files from a specific bundle, bundle name will be lowercased so cases don't matter
74
     *
75
     * @return int total number of files imported
76
     */
77 1
    public function importBundleTranslationFiles(ImportCommand $importCommand)
78
    {
79 1
        $importBundle = strtolower($importCommand->getDefaultBundle());
80
81 1
        if ($importBundle === 'all') {
82
            $importCount = $this->importAllBundlesTranslationFiles($importCommand);
83
84
            if (Kernel::VERSION_ID >= 40000) {
85
                $importCount += $this->importSf4TranslationFiles($importCommand);
86
            }
87
88
            return $importCount;
89
        }
90
91 1
        if ($importBundle === 'custom') {
92
            return $this->importCustomBundlesTranslationFiles($importCommand);
93
        }
94
95 1
        if (Kernel::VERSION_ID >= 40000) {
96 1
            return $this->importSf4TranslationFiles($importCommand);
97
        }
98
99
        return $this->importOwnBundlesTranslationFiles($importCommand);
100
    }
101
102
    /**
103
     * Import all translation files from all registered bundles (in AppKernel)
104
     *
105
     * @return int total number of files imported
0 ignored issues
show
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...
106
     */
107 View Code Duplication
    private function importAllBundlesTranslationFiles(ImportCommand $importCommand)
0 ignored issues
show
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...
108
    {
109
        $bundles = array_map('strtolower', array_keys($this->kernel->getBundles()));
110
        $imported = 0;
111
112
        foreach ($bundles as $bundle) {
113
            $importCommand->setDefaultBundle($bundle);
114
115
            try {
116
                $imported += $this->importSingleBundleTranslationFiles($importCommand);
117
            } catch (TranslationsNotFoundException $e) {
118
                continue;
119
            }
120
        }
121
122
        return $imported;
123
    }
124
125
    /**
126
     * Import all translation files from your own registered bundles (in src/ directory)
127
     *
128
     * @return int The total number of imported files
0 ignored issues
show
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...
129
     */
130
    private function importOwnBundlesTranslationFiles(ImportCommand $importCommand)
131
    {
132
        $imported = 0;
133
        $srcDir = $this->kernel->getProjectDir() . '/src';
134
135
        foreach ($this->kernel->getBundles() as $name => $bundle) {
136
            if (strpos($bundle->getPath(), $srcDir) !== false) {
137
                $importCommand->setDefaultBundle(strtolower($name));
138
139
                try {
140
                    $imported += $this->importSingleBundleTranslationFiles($importCommand);
141
                } catch (TranslationsNotFoundException $e) {
142
                    continue;
143
                }
144
            }
145
        }
146
147
        return $imported;
148
    }
149
150
    /**
151
     * Import the translation files from the defined bundles.
152
     *
153
     * @return int The total number of imported files
0 ignored issues
show
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...
154
     */
155 View Code Duplication
    private function importCustomBundlesTranslationFiles(ImportCommand $importCommand)
0 ignored issues
show
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...
156
    {
157
        $imported = 0;
158
159
        foreach ($importCommand->getBundles() as $bundle) {
160
            $importCommand->setDefaultBundle(strtolower($bundle));
161
162
            try {
163
                $imported += $this->importSingleBundleTranslationFiles($importCommand);
164
            } catch (TranslationsNotFoundException $e) {
165
                continue;
166
            }
167
        }
168
169
        return $imported;
170
    }
171
172
    /**
173
     * Import all translation files from a single bundle
174
     *
175
     * @return int total number of files imported
0 ignored issues
show
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
$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 bool $force override identical translations in the stasher (domain/locale and keyword combination)
196
     *
197
     * @return int total number of files imported
0 ignored issues
show
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...
198
     */
199 2
    private function importTranslationFiles(Finder $finder, $force = false)
200
    {
201 2
        if (!$finder instanceof Finder) {
202
            return false;
203
        }
204
205 2
        $imported = 0;
206
207 2
        foreach ($finder as $file) {
208 2
            $imported += $this->importer->import($file, $force);
209
        }
210
211 2
        return $imported;
212
    }
213
214
    /**
215
     * Validates that a bundle is registered in the AppKernel
216
     *
217
     * @param string $bundle
218
     *
219
     * @return bool bundle is valid or not
220
     *
221
     * @throws \Exception If the bundlename isn't valid
222
     */
223
    public function validateBundleName($bundle)
224
    {
225
        // strtolower all bundle names
226
        $bundles = array_map('strtolower', array_keys($this->kernel->getBundles()));
227
228
        if (\in_array(strtolower(trim($bundle)), $bundles)) {
229
            return true;
230
        }
231
232
        throw new \Exception(sprintf('bundle "%s" not found in available bundles: %s', $bundle, implode(', ', $bundles)));
233
    }
234
235
    /**
236
     * Gives an array with all languages that needs to be imported (from the given ImportCommand)
237
     * If non is given, all managed locales will be used (defined in config)
238
     *
239
     * @return array all locales to import by the given ImportCommand
240
     */
241 3
    public function determineLocalesToImport(ImportCommand $importCommand)
242
    {
243 3
        if ($importCommand->getLocales() === false || $importCommand->getLocales() === null) {
244 3
            return $this->managedLocales;
245
        }
246
247
        return $this->parseRequestedLocales($importCommand->getLocales());
0 ignored issues
show
$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...
248
    }
249
250 6
    public function setTranslationFileExplorer($translationFileExplorer)
251
    {
252 6
        $this->translationFileExplorer = $translationFileExplorer;
253 6
    }
254
255 6
    public function setImporter($importer)
256
    {
257 6
        $this->importer = $importer;
258 6
    }
259
260 1
    private function importSf4TranslationFiles($importCommand)
261
    {
262 1
        $finder = $this->translationFileExplorer->find($this->kernel->getProjectDir(), $this->determineLocalesToImport($importCommand), 'translations');
263
264 1
        if ($finder === null) {
265
            return 0;
266
        }
267
268 1
        return $this->importTranslationFiles($finder, $importCommand->getForce());
269
    }
270
}
271