Completed
Push — master ( 3260ca...0c0ec5 )
by Christian
02:12
created

DowngradeVersionsCommand   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 6
dl 0
loc 118
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 12 1
A execute() 0 15 3
B processModule() 0 26 8
A needsDowngrade() 0 21 2
A getModuleVersions() 0 4 1
1
<?php
2
/*
3
 * @author Tom Klingenberg <https://github.com/ktomk>
4
 */
5
6
namespace N98\Magento\Command\System\Setup;
7
8
use N98\Magento\Api\ModuleInterface;
9
use N98\Magento\Api\ModuleListVersionIterator;
10
use N98\Magento\Api\ModuleVersion;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
/**
16
 * Class DowngradeVersionsCommand
17
 * @package N98\Magento\Command\System\Setup
18
 */
19
class DowngradeVersionsCommand extends AbstractSetupCommand
20
{
21
    /**
22
     * @var OutputInterface
23
     */
24
    private $output;
25
26
    /**
27
     * @var bool
28
     */
29
    private $dryRun;
30
31
    /**
32
     * Setup
33
     */
34
    protected function configure()
35
    {
36
        $this
37
            ->setName('sys:setup:downgrade-versions')
38
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Write what to change but do not do any changes')
39
            ->setDescription('Automatically downgrade schema and module versions');
40
        $help
41
            = <<<HELP
42
If version numbers are too high - normally happens while developing - this command will lower them to the expected ones.
43
HELP;
44
        $this->setHelp($help);
45
    }
46
47
    /**
48
     * @param InputInterface $input
49
     * @param OutputInterface $output
50
     * @return int|null|void
51
     * @throws \Exception
52
     */
53
    protected function execute(InputInterface $input, OutputInterface $output)
54
    {
55
        $this->detectMagento($output, true);
56
57
        if (!$this->initMagento()) {
58
            return;
59
        }
60
61
        $this->output = $output;
62
        $this->dryRun = $input->getOption('dry-run');
0 ignored issues
show
Documentation Bug introduced by
It seems like $input->getOption('dry-run') can also be of type string or array<integer,string>. However, the property $dryRun is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
63
64
        foreach ($this->getModuleVersions() as $moduleVersion) {
65
            $this->processModule($output, $moduleVersion);
66
        }
67
    }
68
69
    /**
70
     * @param OutputInterface $output
71
     * @param ModuleVersion $module
72
     */
73
    private function processModule(OutputInterface $output, ModuleVersion $module)
74
    {
75
        try {
76
            // db version
77
            try {
78
                $dbVersion = $module->getDbVersion();
79
                if ($this->needsDowngrade($module, 'db', $dbVersion)) {
80
                    $this->dryRun || $module->setDbVersion($module->getVersion());
81
                }
82
            } catch (\BadMethodCallException $e) {
83
                // do not print anything
84
            }
85
86
            try {
87
                $dataVersion = $module->getDataVersion();
88
89
                if ($this->needsDowngrade($module, 'data', $dataVersion)) {
90
                    $this->dryRun || $module->setDataVersion($module->getVersion());
91
                }
92
            } catch (\BadMethodCallException $e) {
93
                // do not print anything
94
            }
95
        } catch (\Exception $e) {
96
            $output->writeln('<error>' . $e->getMessage() . '</error>');
97
        }
98
    }
99
100
    /**
101
     * @param ModuleInterface $module
102
     * @param string $what
103
     * @param string $currentVersion
104
     *
105
     * @return bool
106
     */
107
    private function needsDowngrade(ModuleInterface $module, $what, $currentVersion): bool
108
    {
109
        $targetVersion = $module->getVersion();
110
        $needsDowngrade = 1 === \version_compare($currentVersion, $targetVersion);
111
112
        if (!$needsDowngrade) {
113
            return false;
114
        }
115
116
        $this->output->writeln(
117
            sprintf(
118
                "<info>Change module '%s' %s-version from %s to %s.</info>",
119
                $module->getName(),
120
                $what,
121
                $currentVersion,
122
                $targetVersion
123
            )
124
        );
125
126
        return true;
127
    }
128
129
    /**
130
     * @return ModuleListVersionIterator
131
     */
132
    private function getModuleVersions()
133
    {
134
        return new ModuleListVersionIterator($this->moduleList, $this->resource);
135
    }
136
}
137