Completed
Push — master ( 527ecb...217492 )
by René
04:32
created

Version0010Date20191227063812::migrateEvents()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 43
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 37
nc 2
nop 0
dl 0
loc 43
ccs 0
cts 40
cp 0
crap 6
rs 9.328
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 René Gieling <[email protected]>
4
 *
5
 * @author René Gieling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 *  This program is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU Affero General Public License as
11
 *  published by the Free Software Foundation, either version 3 of the
12
 *  License, or (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU Affero General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU Affero General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Polls\Migration;
25
26
// use Doctrine\DBAL\Exception\TableNotFoundException;
27
// use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
28
use Doctrine\DBAL\Types\Type;
0 ignored issues
show
Bug introduced by
The type Doctrine\DBAL\Types\Type was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use OCP\DB\ISchemaWrapper;
30
use OCP\DB\QueryBuilder\IQueryBuilder;
31
use OCP\IConfig;
32
use OCP\IDBConnection;
33
use OCP\Migration\SimpleMigrationStep;
34
use OCP\Migration\IOutput;
35
use OCP\Security\ISecureRandom;
36
37
/**
38
 * Installation class for the polls app.
39
 * Initial db creation
40
 */
41
class Version0010Date20191227063812 extends SimpleMigrationStep {
42
43
	/** @var IDBConnection */
44
	protected $connection;
45
46
	/** @var IConfig */
47
	protected $config;
48
49
	/**
50
	 * @param IDBConnection $connection
51
	 * @param IConfig $config
52
	 */
53
	public function __construct(IDBConnection $connection, IConfig $config) {
54
		$this->connection = $connection;
55
		$this->config = $config;
56
	}
57
58
	/**
59
	 * @param IOutput $output
60
	 * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
61
	 * @param array $options
62
	 * @return null|ISchemaWrapper
63
	 * @since 13.0.0
64
	 */
65
	public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
66
		/** @var ISchemaWrapper $schema */
67
		$schema = $schemaClosure();
68
69
		if ($schema->hasTable('polls_comments')) {
70
			$table = $schema->getTable('polls_comments');
71
			if (!$table->hasColumn('timestamp')) {
72
				$table->addColumn('timestamp', Type::INTEGER, [
73
					'length' => 11,
74
					'notnull' => true,
75
					'default' => 0
76
				]);
77
			}
78
		}
79
80
		if (!$schema->hasTable('polls_polls')) {
81
			$table = $schema->createTable('polls_polls');
82
			$table->addColumn('id', Type::INTEGER, [
83
				'autoincrement' => true,
84
				'length' => 11,
85
				'notnull' => true
86
			]);
87
			$table->addColumn('type', Type::STRING, [
88
				'length' => 64,
89
				'notnull' => true,
90
				'default' => 'datePoll'
91
			]);
92
			$table->addColumn('title', Type::STRING, [
93
				'length' => 128,
94
				'notnull' => true
95
			]);
96
			$table->addColumn('description', Type::STRING, [
97
				'length' => 1024,
98
				'notnull' => true
99
			]);
100
			$table->addColumn('owner', Type::STRING, [
101
				'length' => 64,
102
				'notnull' => true
103
			]);
104
			$table->addColumn('created', Type::INTEGER, [
105
				'length' => 11,
106
				'notnull' => true,
107
				'default' => 0
108
			]);
109
			$table->addColumn('expire', Type::INTEGER, [
110
				'length' => 11,
111
				'notnull' => true,
112
				'default' => 0
113
			]);
114
			$table->addColumn('deleted', Type::INTEGER, [
115
				'length' => 11,
116
				'notnull' => true,
117
				'default' => 0
118
			]);
119
			$table->addColumn('access', Type::STRING, [
120
				'notnull' => true,
121
				'length' => 1024,
122
				'default' => 'hidden'
123
			]);
124
			$table->addColumn('anonymous', Type::INTEGER, [
125
				'length' => 8,
126
				'notnull' => true,
127
				'default' => 0
128
			]);
129
			$table->addColumn('full_anonymous', Type::INTEGER, [
130
				'notnull' => true,
131
				'default' => 0,
132
			]);
133
			$table->addColumn('allow_maybe', Type::INTEGER, [
134
				'notnull' => true,
135
				'default' => 1
136
			]);
137
			$table->addColumn('options', Type::TEXT, [
138
				'notnull' => true,
139
				'default' => ''
140
			]);
141
			$table->addColumn('settings', Type::TEXT, [
142
				'notnull' => true,
143
				'default' => ''
144
			]);
145
			$table->addColumn('vote_limit', Type::INTEGER, [
146
				'length' => 11,
147
				'notnull' => true,
148
				'default' => 0
149
			]);
150
			$table->addColumn('show_results', Type::STRING, [
151
				'length' => 64,
152
				'notnull' => true,
153
				'default' => 'always'
154
			]);
155
			$table->addColumn('admin_access', Type::INTEGER, [
156
				'length' => 8,
157
				'notnull' => true,
158
				'default' => 0
159
			]);
160
161
			$table->setPrimaryKey(['id']);
162
		}
163
164
		if (!$schema->hasTable('polls_share')) {
165
			$table = $schema->createTable('polls_share');
166
			$table->addColumn('id', Type::INTEGER, [
167
				'autoincrement' => true,
168
				'notnull' => true,
169
			]);
170
			$table->addColumn('token', Type::STRING, [
171
				'notnull' => true,
172
				'length' => 64,
173
			]);
174
			$table->addColumn('type', Type::STRING, [
175
				'notnull' => true,
176
				'length' => 64
177
			]);
178
			$table->addColumn('poll_id', Type::INTEGER, [
179
				'notnull' => true
180
			]);
181
			$table->addColumn('user_id', Type::STRING, [
182
				'notnull' => false,
183
				'length' => 64
184
			]);
185
			$table->addColumn('user_email', Type::STRING, [
186
				'notnull' => false,
187
				'length' => 254
188
			]);
189
			$table->addColumn('user', Type::TEXT, [
190
				'notnull' => true,
191
				'default' => ''
192
			]);
193
			$table->setPrimaryKey(['id']);
194
		}
195
196
		if (!$schema->hasTable('polls_log')) {
197
			$table = $schema->createTable('polls_log');
198
			$table->addColumn('id', Type::INTEGER, [
199
				'autoincrement' => true,
200
				'notnull' => true
201
			]);
202
			$table->addColumn('created', Type::INTEGER, [
203
				'notnull' => true,
204
				'length' => 11,
205
				'default' => 0
206
			]);
207
			$table->addColumn('processed', Type::INTEGER, [
208
				'notnull' => true,
209
				'length' => 11,
210
				'default' => 0
211
			]);
212
			$table->addColumn('poll_id', Type::INTEGER, [
213
				'notnull' => true
214
			]);
215
			$table->addColumn('user_id', Type::STRING, [
216
				'notnull' => false,
217
				'length' => 1024
218
			]);
219
			$table->addColumn('display_name', Type::STRING, [
220
				'notnull' => false,
221
				'length' => 64
222
			]);
223
			$table->addColumn('message_id', Type::STRING, [
224
				'notnull' => false,
225
				'length' => 64
226
			]);
227
			$table->addColumn('message', Type::STRING, [
228
				'notnull' => false,
229
				'length' => 1024
230
			]);
231
			$table->setPrimaryKey(['id']);
232
		}
233
234
		return $schema;
235
	}
236
237
	/**
238
	 * @param IOutput $output
239
	 * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
240
	 * @param array $options
241
	 * @since 13.0.0
242
	 */
243
	public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
244
		/** @var ISchemaWrapper $schema */
245
		$schema = $schemaClosure();
246
247
		if ($schema->hasTable('polls_polls')) {
248
			$this->migrateEvents();
249
		}
250
251
		if ($schema->hasTable('polls_share')) {
252
			$this->copyTokens();
253
		}
254
	}
255
256
257
	private function resolveAccess($access) {
258
		if ($access === 'public') {
259
			return 'public';
260
		} else {
261
			return 'hidden';
262
		}
263
	}
264
265
	private function resolveOptions($maybe) {
266
		if ($maybe) {
267
			return json_encode(['yes', 'no', 'maybe']);
268
		} else {
269
			return json_encode(['yes', 'no']);
270
		}
271
	}
272
273
	private function resolveType($type) {
274
		if ($type) {
275
			return 'textPoll';
276
		} else {
277
			return 'datePoll';
278
		}
279
	}
280
281
	/**
282
	* Copy public tokens
283
	*/
284
	protected function migrateEvents() {
285
		$insert = $this->connection->getQueryBuilder();
286
		$insert
287
			->insert('polls_polls')
288
			->values([
289
				'id' => $insert->createParameter('id'),
290
				'type' => $insert->createParameter('type'),
291
				'title' => $insert->createParameter('title'),
292
				'description' => $insert->createParameter('description'),
293
				'owner' => $insert->createParameter('owner'),
294
				'created' => $insert->createParameter('created'),
295
				'expire' => $insert->createParameter('expire'),
296
				'deleted' => $insert->createParameter('deleted'),
297
				'access' => $insert->createParameter('access'),
298
				'anonymous' => $insert->createParameter('anonymous'),
299
				'full_anonymous' => $insert->createParameter('full_anonymous'),
300
				'allow_maybe' => $insert->createParameter('allow_maybe'),
301
				'options' => $insert->createParameter('options'),
302
			]);
303
		$query = $this->connection->getQueryBuilder();
304
		$query->select('*')->from('polls_events');
305
		$result = $query->execute();
306
307
		while ($row = $result->fetch()) {
308
			$insert
309
			->setParameter('id', $row['id'])
310
			->setParameter('type', $this->resolveType($row['type']))
311
			->setParameter('title', $row['title'])
312
			->setParameter('description', $row['description'])
313
			->setParameter('owner', $row['owner'])
314
			->setParameter('created', intval(strtotime($row['created'])))
315
			->setParameter('expire', intval(strtotime($row['expire'])))
316
			->setParameter('deleted', intval(strtotime($row['deleted'])))
317
			->setParameter('access', $this->resolveAccess($row['access']))
318
			->setParameter('anonymous', intval( $row['full_anonymous'] ) * 2 + intval($row['is_anonymous']))
319
			->setParameter('full_anonymous', $row['full_anonymous'])
320
			->setParameter('allow_maybe', $row['allow_maybe'])
321
			->setParameter('options', $this->resolveOptions($row['allow_maybe']));
322
			$insert->execute();
323
324
		}
325
326
		$result->closeCursor();
327
	}
328
329
	/**
330
	 * Copy public tokens
331
	 */
332
	protected function copyTokens() {
333
		$insert = $this->connection->getQueryBuilder();
334
		$insert->insert('polls_share')
335
			->values([
336
				'token' => $insert->createParameter('token'),
337
				'type' => $insert->createParameter('type'),
338
				'poll_id' => $insert->createParameter('poll_id'),
339
				'user_id' => $insert->createParameter('user_id'),
340
				'user_email' => $insert->createParameter('user_email')
341
			]);
342
		$query = $this->connection->getQueryBuilder();
343
		$query->select('*')
344
			->from('polls_events');
345
		$result = $query->execute();
346
347
		while ($row = $result->fetch()) {
348
			if ($row['access'] == 'public') {
349
				// copy the hash to a public share
350
				$insert
351
				->setParameter('token', $row['hash'])
352
				->setParameter('type', 'public')
353
				->setParameter('poll_id', $row['id'])
354
				->setParameter('user_id', null)
355
				->setParameter('user_email', null);
356
				$insert->execute();
357
			} elseif ($row['access'] == 'hidden') {
358
				// copy the hash to a public share
359
				// poll stays hidden for registered users
360
				$insert
361
				->setParameter('token', $row['hash'])
362
				->setParameter('type', 'public')
363
				->setParameter('poll_id', $row['id'])
364
				->setParameter('user_id', null)
365
				->setParameter('user_email', null);
366
				$insert->execute();
367
			} elseif ($row['access'] == 'registered') {
368
				// copy the hash to a public share
369
				// to keep the hash
370
				$insert
371
				->setParameter('token', $row['hash'])
372
				->setParameter('type', 'public')
373
				->setParameter('poll_id', $row['id'])
374
				->setParameter('user_id', null)
375
				->setParameter('user_email', null);
376
			} else {
377
				// create a personal share for invitated users
378
379
				// explode the access entry to single access strings
380
				$users = explode(';', $row['access']);
381
				foreach ($users as $value) {
382
					// separate 'user' and 'group' from user names and create
383
					// a share for every entry
384
					$parts = explode('_', $value);
385
					$insert
386
					->setParameter('token', \OC::$server->getSecureRandom()->generate(
387
						16,
388
						ISecureRandom::CHAR_DIGITS .
389
						ISecureRandom::CHAR_LOWER .
390
						ISecureRandom::CHAR_UPPER
391
					))
392
					->setParameter('type', $parts[0])
393
					->setParameter('poll_id', $row['id'])
394
					->setParameter('user_id', $parts[1])
395
					->setParameter('user_email', null);
396
					$insert->execute();
397
				}
398
			}
399
		}
400
		$result->closeCursor();
401
	}
402
403
}
404