Completed
Pull Request — master (#4286)
by Craig
20:17
created

UpgradeCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 8
dl 0
loc 16
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\Bundle\CoreInstallerBundle\Command;
15
16
use Symfony\Component\Console\Helper\ProgressBar;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Style\StyleInterface;
21
use Symfony\Component\Console\Style\SymfonyStyle;
22
use Symfony\Contracts\Translation\TranslatorInterface;
23
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
24
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
25
use Zikula\Bundle\CoreBundle\YamlDumper;
26
use Zikula\Bundle\CoreInstallerBundle\Controller\UpgraderController;
27
use Zikula\Bundle\CoreInstallerBundle\Form\Type\LoginType;
28
use Zikula\Bundle\CoreInstallerBundle\Helper\MigrationHelper;
29
use Zikula\Bundle\CoreInstallerBundle\Helper\PhpHelper;
30
use Zikula\Bundle\CoreInstallerBundle\Helper\StageHelper;
31
use Zikula\Bundle\CoreInstallerBundle\Stage\Upgrade\AjaxUpgraderStage;
32
use Zikula\SettingsModule\Api\ApiInterface\LocaleApiInterface;
33
34
class UpgradeCommand extends AbstractCoreInstallerCommand
35
{
36
    protected static $defaultName = 'zikula:upgrade';
37
38
    /**
39
     * @var string
40
     */
41
    private $installed;
42
43
    /**
44
     * @var PhpHelper
45
     */
46
    private $phpHelper;
47
48
    /**
49
     * @var MigrationHelper
50
     */
51
    private $migrationHelper;
52
53
    /**
54
     * @var StageHelper
55
     */
56
    private $stageHelper;
57
58
    /**
59
     * @var AjaxUpgraderStage
60
     */
61
    private $ajaxUpgraderStage;
62
63
    /**
64
     * @var array
65
     */
66
    private $upgradeSettings = [
67
        'username',
68
        'password',
69
        'locale',
70
        'router:request_context:host',
71
        'router:request_context:scheme',
72
        'router:request_context:base_url',
73
        'transport'
74
    ];
75
76
    public function __construct(
77
        ZikulaHttpKernelInterface $kernel,
78
        PhpHelper $phpHelper,
79
        MigrationHelper $migrationHelper,
80
        LocaleApiInterface $localeApi,
81
        StageHelper $stageHelper,
82
        AjaxUpgraderStage $ajaxUpgraderStage,
83
        TranslatorInterface $translator,
84
        string $installed
85
    ) {
86
        $this->phpHelper = $phpHelper;
87
        $this->migrationHelper = $migrationHelper;
88
        $this->stageHelper = $stageHelper;
89
        $this->ajaxUpgraderStage = $ajaxUpgraderStage;
90
        $this->installed = $installed;
91
        parent::__construct($kernel, $translator, $localeApi);
92
    }
93
94
    protected function configure()
95
    {
96
        $this->setDescription('Upgrade Zikula from the command line.');
97
98
        foreach ($this->settings as $name => $setting) {
99
            if (!in_array($name, $this->upgradeSettings, true)) {
100
                // only use selected settings for upgrade
101
                continue;
102
            }
103
            $this->addOption(
104
                $name,
105
                null,
106
                InputOption::VALUE_REQUIRED,
107
                $setting['description'],
108
                $setting['default']
109
            );
110
        }
111
    }
112
113
    protected function execute(InputInterface $input, OutputInterface $output): int
114
    {
115
        if (version_compare($this->installed, UpgraderController::ZIKULACORE_MINIMUM_UPGRADE_VERSION, '<')) {
116
            $output->writeln($this->translator->trans('The currently installed version of Zikula (%currentVersion%) is too old. You must upgrade to version %minimumVersion% before you can use this upgrade.', ['%currentVersion%' => $this->installed, '%minimumVersion%' => UpgraderController::ZIKULACORE_MINIMUM_UPGRADE_VERSION]));
117
118
            return 1;
119
        }
120
121
        $io = new SymfonyStyle($input, $output);
122
        if ($input->isInteractive()) {
123
            $io->title($this->translator->trans('Zikula Upgrader Script'));
124
            $io->section($this->translator->trans('*** UPGRADING TO ZIKULA CORE %version% ***', ['%version%' => ZikulaKernel::VERSION]));
125
            $io->text($this->translator->trans('Upgrading Zikula in %env% environment.', ['%env%' => $this->kernel->getEnvironment()]));
126
        }
127
128
        $iniWarnings = $this->phpHelper->setUp();
129
        if (!empty($iniWarnings)) {
130
            $this->printWarnings($output, $iniWarnings);
131
132
            return 2;
133
        }
134
135
        $yamlManager = new YamlDumper($this->kernel->getProjectDir() . '/config', 'services_custom.yaml');
136
        $yamlManager->setParameter('upgrading', true); // tell the core that we are upgrading
137
138
        $this->migrateUsers($input, $output, $io);
139
140
        // get the settings from user input
141
        $settings = $this->doLocale($input, $output, $io);
142
        $settings = array_merge($settings, $this->doAdminLogin($input, $output, $io));
143
        if (false === $mailSettings = $this->doMailer($input, $output, $io)) {
144
            $io->error($this->translator->trans('Cannot write mailer DSN to %file% file.', ['%file%' => '/.env.local']));
145
        } else {
146
            $settings = array_merge($settings, $mailSettings);
147
        }
148
        $settings = array_merge($settings, $this->doRequestContext($input, $output, $io));
149
150
        if ($input->isInteractive()) {
151
            $this->printSettings($settings, $io);
152
            $io->newLine();
153
        }
154
155
        $params = array_merge($yamlManager->getParameters(), $settings);
156
        $yamlManager->setParameters($params);
157
158
        // upgrade!
159
        $this->stageHelper->handleAjaxStage($this->ajaxUpgraderStage, $io, $input->isInteractive());
160
161
        $io->success($this->translator->trans('Upgrade successful!'));
162
163
        return 0;
164
    }
165
166
    private function migrateUsers(InputInterface $input, OutputInterface $output, SymfonyStyle $io): void
167
    {
168
        if (version_compare($this->installed, '2.0.0', '>=')) {
169
            return;
170
        }
171
        $count = $this->migrationHelper->countUnMigratedUsers();
172
        if ($count > 0) {
173
            if ($input->isInteractive()) {
174
                $io->text($this->translator->trans('Beginning user migration...'));
175
            }
176
            $userMigrationMaxuid = (int)$this->migrationHelper->getMaxUnMigratedUid();
177
            if ($input->isInteractive()) {
178
                $progressBar = new ProgressBar($output, (int) ceil($count / MigrationHelper::BATCH_LIMIT));
179
                $progressBar->start();
180
            }
181
            $lastUid = 0;
182
            do {
183
                $result = $this->migrationHelper->migrateUsers($lastUid);
184
                $lastUid = $result['lastUid'];
185
                if ($input->isInteractive()) {
186
                    $progressBar->advance();
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $progressBar does not seem to be defined for all execution paths leading up to this point.
Loading history...
187
                }
188
            } while ($lastUid < $userMigrationMaxuid);
189
            if ($input->isInteractive()) {
190
                $progressBar->finish();
191
                $io->success($this->translator->trans('User migration complete!'));
192
            }
193
        } else {
194
            if ($input->isInteractive()) {
195
                $io->text($this->translator->trans('There was no need to migrate any users.'));
196
            }
197
        }
198
    }
199
200
    private function doAdminLogin(InputInterface $input, OutputInterface $output, StyleInterface $io): array
201
    {
202
        if ($input->isInteractive()) {
203
            $io->newLine();
204
            $io->section($this->translator->trans('Admin Login'));
205
        }
206
        $data = $this->getHelper('form')->interactUsingForm(LoginType::class, $input, $output);
207
        foreach ($data as $k => $v) {
208
            $data[$k] = base64_encode($v); // encode so values are 'safe' for json
209
        }
210
211
        return $data;
212
    }
213
}
214