Completed
Push — master ( c05c28...68f862 )
by Craig
06:13
created

AjaxUpgradeController::finalizeParameters()   D

Complexity

Conditions 11
Paths 768

Size

Total Lines 57
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 32
nc 768
nop 0
dl 0
loc 57
rs 4.2682
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
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 Zikula\Bundle\CoreInstallerBundle\Controller;
13
14
use RandomLib\Factory;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\Yaml\Yaml;
19
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaKernel;
20
use Zikula\Bundle\CoreBundle\YamlDumper;
21
use Zikula\ExtensionsModule\Api\VariableApi;
22
use Zikula\ThemeModule\Entity\Repository\ThemeEntityRepository;
23
24
/**
25
 * Class AjaxUpgradeController
26
 */
27
class AjaxUpgradeController extends AbstractController
28
{
29
    /**
30
     * @var YamlDumper
31
     */
32
    private $yamlManager;
33
34
    /**
35
     * @var string the currently installed core version
36
     */
37
    private $currentVersion;
38
39
    /**
40
     * AjaxUpgradeController constructor.
41
     * @param ContainerInterface $container
42
     */
43
    public function __construct(ContainerInterface $container)
44
    {
45
        parent::__construct($container);
46
        $originalParameters = Yaml::parse(file_get_contents($this->container->get('kernel')->getRootDir() .'/config/parameters.yml'));
47
        $this->yamlManager = new YamlDumper($this->container->get('kernel')->getRootDir() .'/config', 'custom_parameters.yml');
48
        // load and set new default values from the original parameters.yml file into the custom_parameters.yml file.
49
        $this->yamlManager->setParameters(array_merge($originalParameters['parameters'], $this->yamlManager->getParameters()));
50
        $currentVersion = $this->container->getParameter(ZikulaKernel::CORE_INSTALLED_VERSION_PARAM);
51
        $this->currentVersion = (version_compare($currentVersion, '1.4.0', '<')) ? '1.4.0' : $currentVersion;
52
    }
53
54
    public function ajaxAction(Request $request)
55
    {
56
        $stage = $request->request->get('stage');
57
        $this->container->setParameter('upgrading', true);
58
        $status = $this->executeStage($stage);
59
        $response = ['status' => (bool) $status];
60
        if (is_array($status)) {
61
            $response['results'] = $status;
62
        }
63
64
        return new JsonResponse($response);
65
    }
66
67
    public function commandLineAction($stage)
68
    {
69
        $this->container->setParameter('upgrading', true);
70
71
        return $this->executeStage($stage);
72
    }
73
74
    private function executeStage($stageName)
75
    {
76
        switch ($stageName) {
77
            case "loginadmin":
78
                $params = $this->decodeParameters($this->yamlManager->getParameters());
79
80
                return $this->loginAdmin($params);
81
            case "upgrademodules":
82
                $result = $this->upgradeModules();
83
                if (count($result) === 0) {
84
                    return true;
85
                }
86
87
                return $result;
88
            case "installroutes":
89
                if (version_compare(ZikulaKernel::VERSION, '1.4.0', '>') && version_compare($this->currentVersion, '1.4.0', '>=')) {
90
                    // this stage is not necessary to upgrade from 1.4.0 -> 1.4.x
91
                    return true;
92
                }
93
                $this->installModule('ZikulaRoutesModule');
94
                $this->reSyncAndActivateModules();
95
                $this->setModuleCategory('ZikulaRoutesModule', $this->translator->__('System'));
96
97
                return true;
98
            case "regenthemes":
99
                return $this->regenerateThemes();
100
            case "versionupgrade":
101
                return $this->versionUpgrade();
102
            case "finalizeparameters":
103
                return $this->finalizeParameters();
104
            case "clearcaches":
105
                return $this->clearCaches();
106
        }
107
108
        return true;
109
    }
110
111
    /**
112
     * Attempt to upgrade ALL the core modules. Some will need it, some will not.
113
     * Modules that do not need upgrading return TRUE as a result of the upgrade anyway.
114
     * @return array
115
     */
116
    private function upgradeModules()
117
    {
118
        $coreModulesInPriorityUpgradeOrder = [
119
            'ZikulaExtensionsModule',
120
            'ZikulaUsersModule',
121
            'ZikulaZAuthModule',
122
            'ZikulaGroupsModule',
123
            'ZikulaPermissionsModule',
124
            'ZikulaAdminModule',
125
            'ZikulaBlocksModule',
126
            'ZikulaThemeModule',
127
            'ZikulaSettingsModule',
128
            'ZikulaCategoriesModule',
129
            'ZikulaSecurityCenterModule',
130
            'ZikulaRoutesModule',
131
            'ZikulaMailerModule',
132
            'ZikulaSearchModule',
133
            'ZikulaMenuModule',
134
        ];
135
        $result = [];
136
        foreach ($coreModulesInPriorityUpgradeOrder as $moduleName) {
137
            $extensionEntity = $this->container->get('zikula_extensions_module.extension_repository')->get($moduleName);
138
            if (isset($extensionEntity)) {
139
                $result[$moduleName] = $this->container->get('zikula_extensions_module.extension_helper')->upgrade($extensionEntity);
140
            }
141
        }
142
143
        return $result;
144
    }
145
146
    private function regenerateThemes()
147
    {
148
        // regenerate the themes list
149
        $this->container->get('zikula_theme_module.helper.bundle_sync_helper')->regenerate();
150
        // set all themes as active @todo this is probably overkill
151
        $themes = $this->container->get('zikula_theme_module.theme_entity.repository')->findAll();
152
        /** @var \Zikula\ThemeModule\Entity\ThemeEntity $theme */
153
        foreach ($themes as $theme) {
154
            $theme->setState(ThemeEntityRepository::STATE_ACTIVE);
155
        }
156
        $this->container->get('doctrine')->getManager()->flush();
157
158
        return true;
159
    }
160
161
    private function versionUpgrade()
162
    {
163
        /**
164
         * NOTE: There are *intentionally* no `break` statements within each case here so that the process continues
165
         * through each case until the end.
166
         */
167
        switch ($this->currentVersion) {
168
            case '1.4.0':
169
                // perform the following SQL
170
                //ALTER TABLE categories_category ADD CONSTRAINT FK_D0B2B0F88304AF18 FOREIGN KEY (cr_uid) REFERENCES users (uid);
171
                //ALTER TABLE categories_category ADD CONSTRAINT FK_D0B2B0F8C072C1DD FOREIGN KEY (lu_uid) REFERENCES users (uid);
172
                //ALTER TABLE categories_registry ADD CONSTRAINT FK_1B56B4338304AF18 FOREIGN KEY (cr_uid) REFERENCES users (uid);
173
                //ALTER TABLE categories_registry ADD CONSTRAINT FK_1B56B433C072C1DD FOREIGN KEY (lu_uid) REFERENCES users (uid);
174
                //ALTER TABLE sc_intrusion ADD CONSTRAINT FK_8595CE46539B0606 FOREIGN KEY (uid) REFERENCES users (uid);
175
                //DROP INDEX gid_uid ON group_membership;
176
                //ALTER TABLE group_membership DROP PRIMARY KEY;
177
                //ALTER TABLE group_membership ADD CONSTRAINT FK_5132B337539B0606 FOREIGN KEY (uid) REFERENCES users (uid);
178
                //ALTER TABLE group_membership ADD CONSTRAINT FK_5132B3374C397118 FOREIGN KEY (gid) REFERENCES groups (gid);
179
                //CREATE INDEX IDX_5132B337539B0606 ON group_membership (uid);
180
                //CREATE INDEX IDX_5132B3374C397118 ON group_membership (gid);
181
                //ALTER TABLE group_membership ADD PRIMARY KEY (uid, gid);
182
            case '1.4.1':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
183
                $request = $this->container->get('request_stack')->getCurrentRequest();
184
                if (isset($request) && $request->hasSession()) {
185
                    $request->getSession()->remove('interactive_init');
186
                    $request->getSession()->remove('interactive_remove');
187
                    $request->getSession()->remove('interactive_upgrade');
188
                }
189
            case '1.4.2':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
190
                $this->installModule('ZikulaZAuthModule');
191
                $this->reSyncAndActivateModules();
192
                $this->setModuleCategory('ZikulaZAuthModule', $this->translator->__('Users'));
193
            case '1.4.3':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
194
                $this->installModule('ZikulaMenuModule');
195
                $this->reSyncAndActivateModules();
196
                $this->setModuleCategory('ZikulaMenuModule', $this->translator->__('Content'));
197
            case '1.4.4':
198
                // nothing
199
            case '1.4.5':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
200
                // Menu module was introduced in 1.4.4 but not installed on upgrade
201
                $schemaManager = $this->container->get('doctrine')->getConnection()->getSchemaManager();
202
                if (!$schemaManager->tablesExist(['menu_items'])) {
203
                    $this->installModule('ZikulaMenuModule');
204
                    $this->reSyncAndActivateModules();
205
                    $this->setModuleCategory('ZikulaMenuModule', $this->translator->__('Content'));
206
                }
207
            case '1.4.6':
208
                // nothing needed
209
            case '1.4.7':
210
                // nothing needed
211
        }
212
213
        // always do this
214
        $this->reSyncAndActivateModules();
215
216
        return true;
217
    }
218
219
    private function finalizeParameters()
220
    {
221
        $variableApi = $this->container->get('zikula_extensions_module.api.variable');
222
        // Set the System Identifier as a unique string.
223
        if (!$variableApi->get(VariableApi::CONFIG, 'system_identifier')) {
224
            $variableApi->set(VariableApi::CONFIG, 'system_identifier', str_replace('.', '', uniqid(rand(1000000000, 9999999999), true)));
225
        }
226
227
        // add new configuration parameters
228
        $params = $this->yamlManager->getParameters();
229
        unset($params['username'], $params['password']);
230
        $RandomLibFactory = new Factory();
231
        $generator = $RandomLibFactory->getMediumStrengthGenerator();
232
233
        if (!isset($params['secret']) || ($params['secret'] == 'ThisTokenIsNotSoSecretChangeIt')) {
234
            $params['secret'] = $generator->generateString(50);
235
        }
236
        if (!isset($params['url_secret'])) {
237
            $params['url_secret'] = $generator->generateString(10);
238
        }
239
        // Configure the Request Context
240
        // see http://symfony.com/doc/current/cookbook/console/sending_emails.html#configuring-the-request-context-globally
241
        $request = $this->container->get('request_stack')->getMasterRequest();
242
        $hostFromRequest = isset($request) ? $request->getHost() : null;
243
        $basePathFromRequest = isset($request) ? $request->getBasePath() : null;
244
        $params['router.request_context.host'] = isset($params['router.request_context.host']) ? $params['router.request_context.host'] : $hostFromRequest;
245
        $params['router.request_context.scheme'] = isset($params['router.request_context.scheme']) ? $params['router.request_context.scheme'] : 'http';
246
        $params['router.request_context.base_url'] = isset($params['router.request_context.base_url']) ? $params['router.request_context.base_url'] : $basePathFromRequest;
247
248
        // set currently installed version into parameters
249
        $params[ZikulaKernel::CORE_INSTALLED_VERSION_PARAM] = ZikulaKernel::VERSION;
250
251
        // disable asset combination on upgrades
252
        $params['zikula_asset_manager.combine'] = false;
253
254
        // always try to update the database_server_version param
255
        try {
256
            $dbh = new \PDO("$params[database_driver]:host=$params[database_host];dbname=$params[database_name]", $params['database_user'], $params['database_password']);
257
            $params['database_server_version'] = $dbh->getAttribute(\PDO::ATTR_SERVER_VERSION);
258
        } catch (\Exception $e) {
259
            // do nothing on fail
260
        }
261
262
        $this->yamlManager->setParameters($params);
263
264
        // store the recent version in a config var for later usage. This enables us to determine the version we are upgrading from
265
        $variableApi->set(VariableApi::CONFIG, 'Version_Num', ZikulaKernel::VERSION);
266
        $variableApi->set(VariableApi::CONFIG, 'Version_Sub', ZikulaKernel::VERSION_SUB);
267
268
        // set the 'start' page information to empty to avoid missing module errors.
269
        $variableApi->set(VariableApi::CONFIG, 'startpage', '');
270
        $variableApi->set(VariableApi::CONFIG, 'starttype', '');
271
        $variableApi->set(VariableApi::CONFIG, 'startfunc', '');
272
        $variableApi->set(VariableApi::CONFIG, 'startargs', '');
273
274
        return true;
275
    }
276
277
    private function clearCaches()
278
    {
279
        // clear cache with zikula's method
280
        $cacheClearer = $this->container->get('zikula.cache_clearer');
281
        $cacheClearer->clear('symfony');
282
        // use full symfony cache_clearer not zikula's to clear entire cache and set for warmup
283
        // console commands always run in `dev` mode but site should be `prod` mode. clear both for good measure.
284
        $this->container->get('cache_clearer')->clear('dev');
285
        $this->container->get('cache_clearer')->clear('prod');
286
        if (in_array($this->container->getParameter('env'), ['dev', 'prod'])) {
287
            // this is just in case anyone ever creates a mode that isn't dev|prod
288
            $this->container->get('cache_clearer')->clear($this->container->getParameter('env'));
289
        }
290
291
        // finally remove upgrading flag in parameters
292
        $this->yamlManager->delParameter('upgrading');
293
294
        return true;
295
    }
296
}
297