UpdaterController::start()   B
last analyzed

Complexity

Conditions 9
Paths 16

Size

Total Lines 70
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 9
eloc 41
nc 16
nop 0
dl 0
loc 70
rs 7.7084
c 1
b 0
f 1

How to fix   Long Method   

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
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace Installer\Controller;
14
15
use Cake\Core\Configure;
16
use Cake\Event\Event;
17
use Cake\Filesystem\File;
18
use Cake\I18n\I18n;
19
use Cake\ORM\Table;
20
use Cake\ORM\TableRegistry;
21
use Installer\Form\UpdaterStartForm;
22
use Installer\Lib\DbVersion;
23
use Psr\Log\LogLevel;
24
25
/**
26
 * Updater Controller
27
 */
28
class UpdaterController extends AppController
29
{
30
    /** @var string */
31
    private $dbVersion;
32
33
    /** @var string */
34
    private $saitoVersion;
35
36
    /**
37
     * {@inheritDoc}
38
     */
39
    public function initialize()
40
    {
41
        parent::initialize();
42
        $this->dbVersion = Configure::read('Saito.Settings.db_version');
43
        $this->saitoVersion = Configure::read('Saito.v');
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49
    public function beforeRender(\Cake\Event\Event $event)
50
    {
51
        $this->set('titleForLayout', __d('installer', 'update.title'));
52
    }
53
54
    /**
55
     * Index method
56
     *
57
     * @return \Cake\Http\Response|void
58
     */
59
    public function start()
60
    {
61
        $token = new File(CONFIG . 'updater');
62
63
        if ($token->exists()) {
64
            $this->renderFailure(__d('installer', 'update.failure.explanation'), 1529737182);
0 ignored issues
show
Bug introduced by
It seems like __d('installer', 'update.failure.explanation') can also be of type null; however, parameter $message of Installer\Controller\Upd...roller::renderFailure() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
            $this->renderFailure(/** @scrutinizer ignore-type */ __d('installer', 'update.failure.explanation'), 1529737182);
Loading history...
65
66
            return;
67
        }
68
69
        $this->set('dbVersion', $this->dbVersion);
70
        $this->set('saitoVersion', $this->saitoVersion);
71
72
        if (empty($this->dbVersion)) {
73
            $msg = __d('installer', 'update.failure.nodbversion');
74
            $this->renderFailure($msg, 1529737397);
75
            $this->log($msg, LogLevel::ERROR, ['saito.install']);
76
77
            return;
78
        }
79
80
        if (version_compare($this->dbVersion, '4.10.0', '<')) {
81
            $msg = __d('installer', 'update.failure.wrongdbversion', ['v' => $this->dbVersion]);
82
            $this->renderFailure($msg, 1529737648);
83
            $this->log($msg, LogLevel::ERROR, ['saito.install']);
84
85
            return;
86
        }
87
88
        $startForm = new UpdaterStartForm();
89
        $this->set('startForm', $startForm);
90
91
        if (!$this->getRequest()->is('post')) {
92
            return;
93
        }
94
95
        if (!$startForm->execute($this->request->getData())) {
0 ignored issues
show
Bug introduced by
It seems like $this->request->getData() can also be of type null; however, parameter $data of Cake\Form\Form::execute() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

95
        if (!$startForm->execute(/** @scrutinizer ignore-type */ $this->request->getData())) {
Loading history...
96
            // don't emit errors in frontend in case form is accidental on live-installation
97
            $startForm->setErrors([]);
98
            $this->set('startAuthError', true);
99
100
            return;
101
        }
102
103
        $this->logCurrentState('Pre-update state.');
104
105
        $token->write('');
106
107
        try {
108
            if (
109
                version_compare($this->dbVersion, '4.10.0', '>=')
110
                && version_compare($this->dbVersion, '5.0.0', '<')
111
            ) {
112
                $this->migrations->markMigrated('20180620081553');
0 ignored issues
show
Bug introduced by
'20180620081553' of type string is incompatible with the type integer expected by parameter $version of Migrations\Migrations::markMigrated(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
                $this->migrations->markMigrated(/** @scrutinizer ignore-type */ '20180620081553');
Loading history...
113
                $this->logCurrentState('Marked version 4.10.0 migrated.');
114
            }
115
116
            $this->migrations->migrate();
117
            (new DbVersion($this->Settings))->set($this->saitoVersion);
118
            $this->logCurrentState('Post upgrade state.');
119
        } catch (\Throwable $e) {
120
            $this->logCurrentState('Migration failed: ' . $e->getMessage());
121
122
            return $this->redirect('/');
123
        }
124
125
        $token->delete();
126
        $this->viewBuilder()->setTemplate('success');
127
128
        $this->logCurrentState('Update successfull.');
129
    }
130
131
    /**
132
     * Render the update error template
133
     *
134
     * @param string $message message for failure
135
     * @param int $code failure-code
136
     * @return void
137
     */
138
    private function renderFailure(string $message, int $code)
139
    {
140
        $this->viewBuilder()->setTemplate('failure');
141
        $this->set('code', $code);
142
        $this->set('incident', $message);
143
    }
144
145
    /**
146
     * Log current strate
147
     *
148
     * @param string $message message for log
149
     * @return void
150
     */
151
    private function logCurrentState(string $message)
152
    {
153
        $this->log($message, LogLevel::INFO, ['saito.install']);
154
        $content = [
155
            'date' => date('c'),
156
            'dbVersion' => $this->dbVersion,
157
            'saitoVersion' => $this->saitoVersion,
158
            'status' => $this->migrations->status(),
159
        ];
160
        $this->log(print_r($content, true), LogLevel::INFO, ['saito.install']);
161
    }
162
}
163