|
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 2018 |
|
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); |
|
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())) { |
|
|
|
|
|
|
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 (version_compare($this->dbVersion, '4.10.0', '>=') |
|
109
|
|
|
&& version_compare($this->dbVersion, '5.0.0', '<')) { |
|
110
|
|
|
$this->migrations->markMigrated('20180620081553'); |
|
111
|
|
|
$this->logCurrentState('Marked version 4.10.0 migrated.'); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
$this->migrations->migrate(); |
|
115
|
|
|
(new DbVersion($this->Settings))->set($this->saitoVersion); |
|
116
|
|
|
$this->logCurrentState('Post upgrade state.'); |
|
117
|
|
|
} catch (\Throwable $e) { |
|
118
|
|
|
$this->logCurrentState('Migration failed: ' . $e->getMessage()); |
|
119
|
|
|
|
|
120
|
|
|
return $this->redirect('/'); |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
$token->delete(); |
|
124
|
|
|
$this->viewBuilder()->setTemplate('success'); |
|
125
|
|
|
|
|
126
|
|
|
$this->logCurrentState('Update successfull.'); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* Render the update error template |
|
131
|
|
|
* |
|
132
|
|
|
* @param string $message message for failure |
|
133
|
|
|
* @param int $code failure-code |
|
134
|
|
|
* @return void |
|
135
|
|
|
*/ |
|
136
|
|
|
private function renderFailure(string $message, int $code) |
|
137
|
|
|
{ |
|
138
|
|
|
$this->viewBuilder()->setTemplate('failure'); |
|
139
|
|
|
$this->set('code', $code); |
|
140
|
|
|
$this->set('incident', $message); |
|
141
|
|
|
} |
|
142
|
|
|
|
|
143
|
|
|
/** |
|
144
|
|
|
* Log current strate |
|
145
|
|
|
* |
|
146
|
|
|
* @param string $message message for log |
|
147
|
|
|
* @return void |
|
148
|
|
|
*/ |
|
149
|
|
|
private function logCurrentState(string $message) |
|
150
|
|
|
{ |
|
151
|
|
|
$this->log($message, LogLevel::INFO, ['saito.install']); |
|
152
|
|
|
$content = [ |
|
153
|
|
|
'date' => date('c'), |
|
154
|
|
|
'dbVersion' => $this->dbVersion, |
|
155
|
|
|
'saitoVersion' => $this->saitoVersion, |
|
156
|
|
|
'status' => $this->migrations->status(), |
|
157
|
|
|
]; |
|
158
|
|
|
$this->log(print_r($content, true), LogLevel::INFO, ['saito.install']); |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.