Passed
Push — master ( 8a455a...42a228 )
by Craig
07:01
created

UpgradeCommand   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 88
dl 0
loc 169
rs 10
c 1
b 1
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 1
B execute() 0 87 8
A configure() 0 17 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - 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\SymfonyStyle;
21
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
22
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
23
use Zikula\Bundle\CoreBundle\YamlDumper;
24
use Zikula\Bundle\CoreInstallerBundle\Controller\UpgraderController;
25
use Zikula\Bundle\CoreInstallerBundle\Form\Type\LocaleType;
26
use Zikula\Bundle\CoreInstallerBundle\Form\Type\LoginType;
27
use Zikula\Bundle\CoreInstallerBundle\Form\Type\RequestContextType;
28
use Zikula\Bundle\CoreInstallerBundle\Helper\ControllerHelper;
29
use Zikula\Bundle\CoreInstallerBundle\Helper\MigrationHelper;
30
use Zikula\Bundle\CoreInstallerBundle\Helper\StageHelper;
31
use Zikula\Bundle\CoreInstallerBundle\Stage\Upgrade\AjaxUpgraderStage;
32
use Zikula\Common\Translator\TranslatorInterface;
33
use Zikula\SettingsModule\Api\ApiInterface\LocaleApiInterface;
34
35
class UpgradeCommand extends AbstractCoreInstallerCommand
36
{
37
    /**
38
     * @var string
39
     */
40
    private $currentInstalledVersion;
41
42
    /**
43
     * @var ZikulaHttpKernelInterface
44
     */
45
    private $kernel;
46
47
    /**
48
     * @var ControllerHelper
49
     */
50
    private $controllerHelper;
51
52
    /**
53
     * @var MigrationHelper
54
     */
55
    private $migrationHelper;
56
57
    /**
58
     * @var LocaleApiInterface
59
     */
60
    private $localeApi;
61
62
    /**
63
     * @var StageHelper
64
     */
65
    private $stageHelper;
66
67
    /**
68
     * @var array
69
     */
70
    private $selectedSettings = [
71
        'username',
72
        'password',
73
        'router:request_context:host',
74
        'router:request_context:scheme',
75
        'router:request_context:base_url'
76
    ];
77
78
    public function __construct(
79
        string $currentInstalledVersion,
80
        ZikulaHttpKernelInterface $kernel,
81
        ControllerHelper $controllerHelper,
82
        MigrationHelper $migrationHelper,
83
        LocaleApiInterface $localeApi,
84
        StageHelper $stageHelper,
85
        TranslatorInterface $translator
86
    ) {
87
        $this->currentInstalledVersion = $currentInstalledVersion;
88
        $this->kernel = $kernel;
89
        $this->controllerHelper = $controllerHelper;
90
        $this->migrationHelper = $migrationHelper;
91
        $this->localeApi = $localeApi;
92
        $this->stageHelper = $stageHelper;
93
        parent::__construct($translator);
94
    }
95
96
    protected function configure()
97
    {
98
        $this
99
            ->setDescription('Upgrade Zikula from the command line.')
100
            ->setName('zikula:upgrade')
101
        ;
102
        foreach ($this->settings as $name => $setting) {
103
            if (!in_array($name, $this->selectedSettings, true)) {
104
                // only use selected settings for upgrade
105
                continue;
106
            }
107
            $this->addOption(
108
                $name,
109
                null,
110
                InputOption::VALUE_REQUIRED,
111
                $setting['description'],
112
                $setting['default']
113
            );
114
        }
115
    }
116
117
    protected function execute(InputInterface $input, OutputInterface $output)
118
    {
119
        if (version_compare($this->currentInstalledVersion, UpgraderController::ZIKULACORE_MINIMUM_UPGRADE_VERSION, '<')) {
120
            $output->writeln($this->translator->__f('The current installed version of Zikula is reporting (%1$s). You must upgrade to version (%2$s) before you can use this upgrade.', ['%1$s' => $this->currentInstalledVersion, '%2$s' => UpgraderController::ZIKULACORE_MINIMUM_UPGRADE_VERSION]));
121
122
            return false;
123
        }
124
125
        $io = new SymfonyStyle($input, $output);
126
        $io->title($this->translator->__('Zikula Upgrader Script'));
127
        $io->section($this->translator->__f('*** UPGRADING TO ZIKULA CORE %version% ***', ['%version%' => ZikulaKernel::VERSION]));
128
        $io->text($this->translator->__f('Upgrading Zikula in %env% environment.', ['%env%' => $this->kernel->getEnvironment()]));
129
130
        $warnings = $this->controllerHelper->initPhp();
131
        if (!empty($warnings)) {
132
            $this->printWarnings($output, $warnings);
133
134
            return false;
135
        }
136
        $checks = $this->controllerHelper->requirementsMet();
137
        if (true !== $checks) {
0 ignored issues
show
introduced by
The condition true !== $checks is always true.
Loading history...
138
            $this->printRequirementsWarnings($output, $checks);
139
140
            return false;
141
        }
142
143
        $count = $this->migrationHelper->countUnMigratedUsers();
144
        if ($count > 0) {
145
            $io->text($this->translator->__('Beginning user migration...'));
146
            $userMigrationMaxuid = (int)$this->migrationHelper->getMaxUnMigratedUid();
147
            $progressBar = new ProgressBar($output, (int)ceil($count / MigrationHelper::BATCH_LIMIT));
148
            $progressBar->start();
149
            $lastUid = 0;
150
            do {
151
                $result = $this->migrationHelper->migrateUsers($lastUid);
152
                $lastUid = $result['lastUid'];
153
                $progressBar->advance();
154
            } while ($lastUid < $userMigrationMaxuid);
155
            $progressBar->finish();
156
            $io->success($this->translator->__('User migration complete!'));
157
        } else {
158
            $io->text($this->translator->__('There was no need to migrate any users.'));
159
        }
160
161
        // avoid warning in PHP 7.2 based on ini_set() usage which is caused by any access to the
162
        // session before regeneration happens (e.g. by an event listener executed before a login)
163
        // see issue #3898 for the details
164
        $reportingLevel = error_reporting();
165
        error_reporting($reportingLevel & ~E_WARNING);
166
167
        // get the settings from user input
168
        $settings = $this->getHelper('form')->interactUsingForm(LocaleType::class, $input, $output, [
169
            'choices' => $this->localeApi->getSupportedLocaleNames()
170
        ]);
171
172
        $data = $this->getHelper('form')->interactUsingForm(LoginType::class, $input, $output);
173
        foreach ($data as $k => $v) {
174
            $data[$k] = base64_encode($v); // encode so values are 'safe' for json
175
        }
176
        $settings = array_merge($settings, $data);
177
178
        $data = $this->getHelper('form')->interactUsingForm(RequestContextType::class, $input, $output);
179
        foreach ($data as $k => $v) {
0 ignored issues
show
Comprehensibility Bug introduced by
$k is overwriting a variable from outer foreach loop.
Loading history...
Comprehensibility Bug introduced by
$v is overwriting a variable from outer foreach loop.
Loading history...
180
            $newKey = str_replace(':', '.', $k);
181
            $data[$newKey] = $v;
182
            unset($data[$k]);
183
        }
184
        $settings = array_merge($settings, $data);
185
186
        $this->printSettings($settings, $io);
187
        $io->newLine();
188
189
        // write the parameters to custom_parameters.yml
190
        $yamlManager = new YamlDumper($this->kernel->getProjectDir() . '/app/config', 'custom_parameters.yml');
191
        $params = array_merge($yamlManager->getParameters(), $settings);
192
        unset($params['upgrading']);
193
        $yamlManager->setParameters($params);
194
195
        // upgrade!
196
        $ajaxStage = new AjaxUpgraderStage($this->translator, $this->currentInstalledVersion);
197
        $this->stageHelper->handleAjaxStage($ajaxStage, $io);
198
199
        error_reporting($reportingLevel);
200
201
        $io->success($this->translator->__('UPGRADE COMPLETE!'));
202
203
        return true;
204
    }
205
}
206