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

Service/Command/Importer/ImportCommandHandler.php (6 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)
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
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
154
     */
155 View Code Duplication
    private function importCustomBundlesTranslationFiles(ImportCommand $importCommand)
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());
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