Completed
Pull Request — master (#4286)
by Craig
10:40 queued 04:59
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 $selectedSettings = [
67
        'username',
68
        'password',
69
        'locale',
70
        'router:request_context:host',
71
        'router:request_context:scheme',
72
        'router:request_context:base_url'
73
    ];
74
75
    public function __construct(
76
        ZikulaHttpKernelInterface $kernel,
77
        PhpHelper $phpHelper,
78
        MigrationHelper $migrationHelper,
79
        LocaleApiInterface $localeApi,
80
        StageHelper $stageHelper,
81
        AjaxUpgraderStage $ajaxUpgraderStage,
82
        TranslatorInterface $translator,
83
        string $installed
84
    ) {
85
        $this->phpHelper = $phpHelper;
86
        $this->migrationHelper = $migrationHelper;
87
        $this->stageHelper = $stageHelper;
88
        $this->ajaxUpgraderStage = $ajaxUpgraderStage;
89
        $this->installed = $installed;
90
        parent::__construct($kernel, $translator, $localeApi);
91
    }
92
93
    protected function configure()
94
    {
95
        $this->setDescription('Upgrade Zikula from the command line.');
96
97
        foreach ($this->settings as $name => $setting) {
98
            if (!in_array($name, $this->selectedSettings, true)) {
99
                // only use selected settings for upgrade
100
                continue;
101
            }
102
            $this->addOption(
103
                $name,
104
                null,
105
                InputOption::VALUE_REQUIRED,
106
                $setting['description'],
107
                $setting['default']
108
            );
109
        }
110
    }
111
112
    protected function execute(InputInterface $input, OutputInterface $output): int
113
    {
114
        if (version_compare($this->installed, UpgraderController::ZIKULACORE_MINIMUM_UPGRADE_VERSION, '<')) {
115
            $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]));
116
117
            return 1;
118
        }
119
120
        $io = new SymfonyStyle($input, $output);
121
        if ($input->isInteractive()) {
122
            $io->title($this->translator->trans('Zikula Upgrader Script'));
123
            $io->section($this->translator->trans('*** UPGRADING TO ZIKULA CORE %version% ***', ['%version%' => ZikulaKernel::VERSION]));
124
            $io->text($this->translator->trans('Upgrading Zikula in %env% environment.', ['%env%' => $this->kernel->getEnvironment()]));
125
        }
126
127
        $iniWarnings = $this->phpHelper->setUp();
128
        if (!empty($iniWarnings)) {
129
            $this->printWarnings($output, $iniWarnings);
130
131
            return 2;
132
        }
133
134
        $yamlManager = new YamlDumper($this->kernel->getProjectDir() . '/config', 'services_custom.yaml');
135
        $yamlManager->setParameter('upgrading', true); // tell the core that we are upgrading
136
137
        $this->migrateUsers($input, $output, $io);
138
139
        // get the settings from user input
140
        $settings = $this->doLocale($input, $output, $io);
141
        $settings = array_merge($settings, $this->doAdminLogin($input, $output, $io));
142
        if (false === $mailSettings = $this->doMailer($input, $output, $io)) {
143
            $io->error($this->translator->trans('Cannot write mailer DSN to %file% file.', ['%file%' => '/.env.local']));
144
        } else {
145
            $settings = array_merge($settings, $mailSettings);
146
        }
147
        $settings = array_merge($settings, $this->doRequestContext($input, $output, $io));
148
149
        if ($input->isInteractive()) {
150
            $this->printSettings($settings, $io);
151
            $io->newLine();
152
        }
153
154
        $params = array_merge($yamlManager->getParameters(), $settings);
155
        $yamlManager->setParameters($params);
156
157
        // upgrade!
158
        $this->stageHelper->handleAjaxStage($this->ajaxUpgraderStage, $io);
159
160
        $io->success($this->translator->trans('UPGRADE SUCCESSFUL!'));
161
162
        return 0;
163
    }
164
165
    private function migrateUsers(InputInterface $input, OutputInterface $output, SymfonyStyle $io): void
166
    {
167
        if (version_compare($this->installed, '2.0.0', '>=')) {
168
            return;
169
        }
170
        $count = $this->migrationHelper->countUnMigratedUsers();
171
        if ($count > 0) {
172
            if ($input->isInteractive()) {
173
                $io->text($this->translator->trans('Beginning user migration...'));
174
            }
175
            $userMigrationMaxuid = (int)$this->migrationHelper->getMaxUnMigratedUid();
176
            if ($input->isInteractive()) {
177
                $progressBar = new ProgressBar($output, (int) ceil($count / MigrationHelper::BATCH_LIMIT));
178
                $progressBar->start();
179
            }
180
            $lastUid = 0;
181
            do {
182
                $result = $this->migrationHelper->migrateUsers($lastUid);
183
                $lastUid = $result['lastUid'];
184
                if ($input->isInteractive()) {
185
                    $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...
186
                }
187
            } while ($lastUid < $userMigrationMaxuid);
188
            if ($input->isInteractive()) {
189
                $progressBar->finish();
190
                $io->success($this->translator->trans('User migration complete!'));
191
            }
192
        } else {
193
            if ($input->isInteractive()) {
194
                $io->text($this->translator->trans('There was no need to migrate any users.'));
195
            }
196
        }
197
    }
198
199
    private function doAdminLogin(InputInterface $input, OutputInterface $output, StyleInterface $io): array
200
    {
201
        if ($input->isInteractive()) {
202
            $io->newLine();
203
            $io->section($this->translator->trans('Admin Login'));
204
        }
205
        $data = $this->getHelper('form')->interactUsingForm(LoginType::class, $input, $output);
206
        foreach ($data as $k => $v) {
207
            $data[$k] = base64_encode($v); // encode so values are 'safe' for json
208
        }
209
210
        return $data;
211
    }
212
}
213