Completed
Push — master ( af5131...20ae7d )
by Simonas
151:41 queued 86:43
created

ImportCommand::validateBundleNamespace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4286
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\TranslationsBundle\Command;
13
14
use ONGR\TranslationsBundle\Service\Import;
15
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
16
use Symfony\Component\Console\Input\InputArgument;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
/**
22
 * Translations import command.
23
 */
24
class ImportCommand extends ContainerAwareCommand
25
{
26
    /**
27
     * @var InputInterface
28
     */
29
    private $input;
30
31
    /**
32
     * @var OutputInterface
33
     */
34
    private $output;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    protected function configure()
40 6
    {
41
        $this->setName('ongr:translations:import');
42 6
        $this->setDescription('Import all translations from flat files (xliff, yml, php) into the database.');
43 6
        $this->addOption('globals', 'g', InputOption::VALUE_NONE, 'Import only globals (app/Resources/translations.');
44 6
        $this->addOption('config-only', 'c', InputOption::VALUE_NONE, 'Import only bundles specified in config.');
45 6
        $this->addOption(
46 6
            'locales',
47 6
            'l',
48 6
            InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
49 6
            'Import only for these locales, instead of using the managed locales.'
50 6
        );
51
        $this->addOption(
52 6
            'domains',
53 6
            'd',
54 6
            InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
55 6
            'Import only these domains.',
56 6
            []
57 6
        );
58
        $this->addArgument(
59 6
            'bundle',
60 6
            InputArgument::OPTIONAL,
61 6
            'Import translations for this specific bundle. Provide full bundles namespace.',
62 6
            null
63 6
        );
64
    }
65 6
66
    /**
67
     * {@inheritdoc}
68
     */
69
    protected function execute(InputInterface $input, OutputInterface $output)
70 3
    {
71
        $this->input = $input;
72 3
        $this->output = $output;
73 3
74
        /** @var Import $import */
75
        $import = $this->getContainer()->get('ongr_translations.import');
76 3
77
        $locales = $this->input->getOption('locales');
78 3
        if (empty($locales)) {
79 3
            $locales = $this->getContainer()->getParameter('ongr_translations.managed_locales');
80 2
        }
81
        $domains = $input->getOption('domains');
82 3
83
        $bundleName = $this->input->getArgument('bundle');
84 3
85
        $import->setLocales($locales);
86 3
        $import->setDomains($domains);
87 3
88
        if ($input->getOption('config-only')) {
89 3
            $this->output->writeln('<info>*** Importing configured bundles translation files ***</info>');
90
            $import->importBundlesTranslationFiles($import->getConfigBundles());
91
        } else {
92
            if ($bundleName) {
93 3
                $this->output->writeln("<info>*** Importing {$bundleName} translation files ***</info>");
94 2
                $bundle = $this->getApplication()->getKernel()->getBundle($bundleName);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Console\Application as the method getKernel() does only exist in the following sub-classes of Symfony\Component\Console\Application: Symfony\Bundle\FrameworkBundle\Console\Application. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
95 1
                $import->importBundlesTranslationFiles([$bundle], true);
96 1
            } else {
97
                $this->output->writeln('<info>*** Importing application translation files ***</info>');
98 1
                $import->importAppTranslationFiles();
99 1
                if (!$this->input->getOption('globals')) {
100 1
                    $this->output->writeln('<info>*** Importing bundles translation files ***</info>');
101 1
                    $import->importBundlesTranslationFiles(
102 1
                        array_merge($import->getBundles(), $import->getConfigBundles())
103 1
                    );
104
                    $this->output->writeln('<info>*** Importing component translation files ***</info>');
105 1
                    $import->importComponentTranslationFiles();
106 1
                }
107
            }
108
        }
109
        $import->writeToStorage();
110 2
    }
111
}
112