-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathWurrdInstaller.php
More file actions
executable file
·338 lines (293 loc) · 10.2 KB
/
WurrdInstaller.php
File metadata and controls
executable file
·338 lines (293 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
<?php
/*
* This file is a part of Wurrd AuthAPI plugin.
*
* Copyright 2005-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Wurrd\Mibew\Plugin\AuthAPI;
use Mibew\Database;
use Mibew\Mail\Utils as MailUtils;
use Mibew\Maintenance\Installer;
use Symfony\Component\Yaml\Parser as YamlParser;
use Wurrd\Mibew\Plugin\AuthAPI\Constants;
/**
* Encapsulates installation process.
*/
class WurrdInstaller extends Installer
{
/**
* Class constructor.
*
* @param array $system_configs Associative array of system configs.
*/
public function __construct($system_configs)
{
parent::__construct($system_configs);
}
/**
* Create tables.
*
* One can get all logged messages of this step using
* {@link Installer::getLog()} method. Also the list of all errors can be
* got using {@link Installer::getErrors()}.
*
* @return boolean True if all tables are created and false otherwise.
*/
public function createTables()
{
if ($this->tablesExist() && $this->tablesNeedUpdate()) {
// Tables already exists but they should be updated
$this->errors[] = getlocal('The tables are alredy in place but outdated. Run the updater to fix it.');
return false;
}
if ($this->tablesExist()) {
$this->log[] = getlocal('Tables structure is up to date.');
return true;
}
// There are no tables in the database. We need to create them.
if (!$this->doCreateTables()) {
return false;
}
$this->log[] = getlocal('Tables are created.');
if (!$this->prepopulateDatabase()) {
return false;
}
$this->log[] = getlocal('Tables are pre popluated with necessary info.');
return true;
}
/**
* Drop tables.
*
* One can get all logged messages of this step using
* {@link Installer::getLog()} method. Also the list of all errors can be
* got using {@link Installer::getErrors()}.
*
* @return boolean True if all tables are dropped and false otherwise.
*/
public function dropTables()
{
// Drop the tables.
if (!$this->doDropTables()) {
return false;
}
$this->log[] = getlocal('Tables are removed.');
// Remove version info from config
if (!$this->removeVersionInfo()) {
return false;
}
$this->log[] = getlocal('Plugin version removed from database.');
return true;
}
/**
* Performs all database updates needed for 0.1.3.
*
* @return boolean True if the updates have been applied successfully and
* false otherwise.
*/
public function update00103()
{
$db = $this->getDatabase();
if (!$db) {
return false;
}
$db->query('START TRANSACTION');
try {
// Alter device table.
$db->query('ALTER TABLE {waa_device} ADD COLUMN dtmcreated int NOT NULL DEFAULT 0');
$db->query('ALTER TABLE {waa_device} ADD COLUMN dtmmodified int NOT NULL DEFAULT 0');
$db->query('ALTER TABLE {waa_device} ADD INDEX idx_device (deviceuuid, platform)');
// Alter authorization table.
$db->query('ALTER TABLE {waa_authorization} ADD COLUMN dtmcreated int NOT NULL DEFAULT 0 AFTER clientid');
$db->query('ALTER TABLE {waa_authorization} ADD COLUMN dtmmodified int NOT NULL DEFAULT 0 AFTER dtmcreated');
$db->query('ALTER TABLE {waa_authorization} ADD INDEX idx_accesstoken (accesstoken)');
$db->query('ALTER TABLE {waa_authorization} ADD INDEX idx_refreshtoken (refreshtoken)');
$db->query('ALTER TABLE {waa_authorization} ADD INDEX idx_deviceid (deviceid)');
$db->query('ALTER TABLE {waa_authorization} ADD INDEX idx_previousaccesstoken (previousaccesstoken)');
} catch (\Exception $e) {
// Something went wrong. We actually cannot update the database.
$this->errors[] = getlocal('Cannot update content: {0}', $e->getMessage());
// The database changes should be discarded.
$db->query('ROLLBACK');
return false;
}
// All needed data has been updated.
$db->query('COMMIT');
return true;
}
/**
* Loads database schema.
*
* @return array Associative array of database schema. Each key of the array
* is a table name and each value is its description. Table array itself
* is an associative array with the following keys:
* - fields: An associative array, which keys are MySQL columns names
* and values are columns definitions.
* - unique_keys: An associative array. Each its value is a name of a
* table's unique key. Each value is an array with names of the
* columns the key is based on.
* - indexes: An associative array. Each its value is a name of a
* table's index. Each value is an array with names of the
* columns the index is based on.
*/
protected function getDatabaseSchema()
{
return $this->parser->parse(file_get_contents(__DIR__ . '/database_schema.yml'));
}
/**
* Gets version of existing database structure for the Wurrd:AuthAPI plugin.
*
* If the plugin is not installed yet boolean false will be returned.
*
* @return string|boolean Database structure version or boolean false if the
* version cannot be determined.
*/
protected function getDatabaseVersion()
{
if (!($db = $this->getDatabase())) {
return false;
}
try {
$result = $db->query(
"SELECT vcvalue AS version FROM {config} WHERE vckey = :key LIMIT 1",
array(':key' => 'waa_version'),
array('return_rows' => Database::RETURN_ONE_ROW)
);
} catch (\Exception $e) {
return false;
}
if (!$result) {
// It seems that database structure version isn't stored in the
// database.
return false;
}
return $result['version'];
}
/**
* Checks if the database structure must be updated.
*
* @return boolean
*/
protected function tablesNeedUpdate()
{
return version_compare($this->getDatabaseVersion(), Constants::WAA_VERSION, '<');
}
/**
* Checks if database structure is already created.
*
* @return boolean
*/
protected function tablesExist()
{
return ($this->getDatabaseVersion() !== false);
}
/**
* Drop all tables.
*
* @return boolean Indicates if tables removed or not.
*/
protected function doDropTables()
{
if (!($db = $this->getDatabase())) {
return false;
}
try {
// Drop tables as defined by the schema
$schema = $this->getDatabaseSchema();
// We need to delete backwards such that foreign key constraints are not violated
// ??? or, we can do it from top to bottom with CASCADE ???
$tables = array_keys($schema);
$tableCount = count($tables);
for ($i = $tableCount - 1; $i >= 0; $i--) {
$db->query(sprintf(
'DROP TABLE IF EXISTS {%s}',
$tables[$i]
));
}
} catch (\Exception $e) {
$this->errors[] = getlocal(
'Cannot drop tables. Error: {0}',
array($e->getMessage())
);
return false;
}
return true;
}
/**
* Saves some necessary data in the database.
*
* This method is called just once after tables are created.
*
* @return boolean Indicates if the data are saved to the database or not.
*/
protected function prepopulateDatabase()
{
if (!($db = $this->getDatabase())) {
return false;
}
// Set correct database structure version if needed
try {
list($count) = $db->query(
'SELECT COUNT(*) FROM {config} WHERE vckey = :key',
array(':key' => 'waa_version'),
array(
'return_rows' => Database::RETURN_ONE_ROW,
'fetch_type' => Database::FETCH_NUM
)
);
if ($count == 0) {
$db->query(
'INSERT INTO {config} (vckey, vcvalue) VALUES (:key, :value)',
array(
':key' => 'waa_version',
':value' => Constants::WAA_VERSION,
)
);
}
} catch (\Exception $e) {
$this->errors[] = getlocal(
'Cannot store database structure version. Error {0}',
array($e->getMessage())
);
return false;
}
return true;
}
/**
* Removes this plugin's version info from the database
*
* This method is called just once after tables are dropped.
*
* @return boolean Indicates if the version info is removed or not.
*/
protected function removeVersionInfo()
{
if (!($db = $this->getDatabase())) {
return false;
}
try {
$db->query(
'DELETE FROM {config} WHERE vckey = :key',
array(':key' => 'waa_version')
);
} catch (\Exception $e) {
$this->errors[] = getlocal(
'Cannot remove the plugin database structure version. Error {0}',
array($e->getMessage())
);
return false;
}
return true;
}
}