Completed
Push — master ( e2a767...40afc9 )
by Henry
16:31 queued 08:12
created

Installer::_rawExecute()   B

Complexity

Conditions 6
Paths 11

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 31
ccs 0
cts 0
cp 0
rs 8.8017
c 0
b 0
f 0
cc 6
nc 11
nop 3
crap 42
1
<?php
2
namespace Redaxscript;
3
4
use PDOException;
5
use function explode;
6
use function file_get_contents;
7
use function method_exists;
8
use function str_replace;
9
use function ucfirst;
10
use function version_compare;
11
12
/**
13
 * parent class to install the database
14
 *
15
 * @since 2.4.0
16
 *
17
 * @category Installer
18
 * @package Redaxscript
19
 * @author Henry Ruhs
20
 */
21
22
class Installer
23
{
24
	/**
25
	 * instance of the registry class
26
	 *
27
	 * @var Registry
28
	 */
29
30
	protected $_registry;
31
32
	/**
33
	 * instance of the request class
34
	 *
35
	 * @var Request
36
	 */
37
38
	protected $_request;
39
40
	/**
41
	 * instance of the language class
42
	 *
43
	 * @var Language
44
	 */
45
46
	protected $_language;
47
48
	/**
49
	 * instance of the config class
50
	 *
51
	 * @var Config
52
	 */
53
54
	protected $_config;
55
56
	/**
57
	 * name of the directory
58
	 *
59
	 * @var string
60
	 */
61
62
	protected $_directory;
63
64
	/**
65
	 * placeholder for the prefix
66
	 *
67
	 * @var string
68
	 */
69
70
	protected $_prefixPlaceholder = '/* %PREFIX% */';
71
72
	/**
73
	 * constructor of the class
74
	 *
75
	 * @since 3.0.0
76
	 *
77
	 * @param Registry $registry instance of the registry class
78
	 * @param Request $request instance of the request class
79
	 * @param Language $language instance of the language class
80 3
	 * @param Config $config instance of the config class
81
	 */
82 3
83 3
	public function __construct(Registry $registry, Request $request, Language $language, Config $config)
84 3
	{
85 3
		$this->_registry = $registry;
86 3
		$this->_request = $request;
87
		$this->_language = $language;
88
		$this->_config = $config;
89
	}
90
91
	/**
92
	 * init the class
93
	 *
94
	 * @since 2.6.0
95
	 *
96 3
	 * @param string $directory name of the directory
97
	 */
98 3
99 3
	public function init(string $directory = 'database') : void
100
	{
101
		$this->_directory = $directory;
102
	}
103
104
	/**
105
	 * create from sql
106
	 *
107 1
	 * @since 2.4.0
108
	 *
109 1
	 * @return bool
110 1
	 */
111
112
	public function rawCreate() : bool
113
	{
114
		return $this->_rawExecute($this->_config->get('dbType'), 'create');
115
	}
116
117
	/**
118 1
	 * drop from sql
119
	 *
120 1
	 * @since 2.4.0
121 1
	 *
122
	 * @return bool
123
	 */
124
125
	public function rawDrop() : bool
126
	{
127
		return $this->_rawExecute($this->_config->get('dbType'), 'drop');
128
	}
129
130
	/**
131 1
	 * migrate from sql
132
	 *
133 1
	 * @since 4.4.0
134 1
	 *
135 1
	 * @param string $version version to migrate
136 1
	 *
137 1
	 * @return bool
138 1
	 */
139 1
140 1
	public function rawMigrate(string $version = null) : bool
141 1
	{
142
		return $this->_rawExecute($this->_config->get('dbType'), 'migrate', $version);
143
	}
144
145
	/**
146
	 * insert the data
147
	 *
148
	 * @since 3.1.0
149
	 *
150
	 * @param array $optionArray options of the installation
151 1
	 */
152
153 1
	public function insertData(array $optionArray = []) : void
154 1
	{
155 1
		$this->insertCategories($optionArray);
156 1
		$this->insertArticles($optionArray);
157
		$this->insertExtras($optionArray);
158 1
		$this->insertComments($optionArray);
159 1
		$this->insertGroups();
160 1
		$this->insertUsers($optionArray);
161 1
		$this->insertModules();
162 1
		$this->insertSettings($optionArray);
163
	}
164 1
165 1
	/**
166
	 * insert the categories
167
	 *
168
	 * @since 3.1.0
169
	 *
170
	 * @param array $optionArray options of the installation
171
	 */
172
173
	public function insertCategories(array $optionArray = []) : void
174
	{
175 1
		$now = $this->_registry->get('now');
176
		Db::forTablePrefix('categories')
177 1
			->create()
178 1
			->set(
179 1
			[
180 1
				'title' => 'Home',
181
				'alias' => 'home',
182 1
				'author' => $optionArray['adminUser'],
183 1
				'rank' => 1,
184 1
				'date' => $now
185 1
			])
186 1
			->save();
187 1
	}
188 1
189 1
	/**
190
	 * insert the articles
191 1
	 *
192 1
	 * @since 3.1.0
193
	 *
194
	 * @param array $optionArray options of the installation
195
	 */
196
197
	public function insertArticles(array $optionArray = []) : void
198
	{
199
		$now = $this->_registry->get('now');
200
		Db::forTablePrefix('articles')
201
			->create()
202 1
			->set(
203
			[
204 1
				'title' => 'Welcome',
205
				'alias' => 'welcome',
206
				'author' => $optionArray['adminUser'],
207 1
				'text' => file_get_contents('database' . DIRECTORY_SEPARATOR . 'html' . DIRECTORY_SEPARATOR . 'articles' . DIRECTORY_SEPARATOR . 'welcome.phtml'),
208
				'category' => 1,
209
				'comments' => 1,
210
				'rank' => 1,
211
				'date' => $now
212
			])
213
			->save();
214
	}
215
216
	/**
217
	 * insert the extras
218
	 *
219
	 * @since 3.1.0
220
	 *
221
	 * @param array $optionArray options of the installation
222
	 */
223
224
	public function insertExtras(array $optionArray = []) : void
225
	{
226
		$now = $this->_registry->get('now');
227
		$extrasArray =
228
		[
229
			'categories' =>
230
			[
231
				'category' => null,
232
				'headline' => 1,
233
				'status' => 1
234
			],
235
			'articles' =>
236
			[
237
				'category' => null,
238
				'headline' => 1,
239
				'status' => 1
240
			],
241
			'comments' =>
242
			[
243
				'category' => null,
244 1
				'headline' => 1,
245
				'status' => 1
246
			],
247
			'languages' =>
248 1
			[
249
				'category' => null,
250 1
				'headline' => 1,
251 1
				'status' => 0
252 1
			],
253
			'templates' =>
254 1
			[
255 1
				'category' => null,
256 1
				'headline' => 1,
257 1
				'status' => 0
258 1
			],
259 1
			'teaser' =>
260 1
			[
261 1
				'category' => 1,
262 1
				'headline' => 0,
263
				'status' => 0
264 1
			]
265
		];
266 1
		$extrasRank = 0;
267
268
		/* process extras */
269
270
		foreach ($extrasArray as $key => $value)
271
		{
272
			Db::forTablePrefix('extras')
273
				->create()
274
				->set(
275
				[
276 1
					'title' => ucfirst($key),
277
					'alias' => $key,
278 1
					'author' => $optionArray['adminUser'],
279 1
					'text' => file_get_contents('database' . DIRECTORY_SEPARATOR . 'html' . DIRECTORY_SEPARATOR . 'extras' . DIRECTORY_SEPARATOR . $key . '.phtml'),
280 1
					'category' => $value['category'],
281 1
					'headline' => $value['headline'],
282
					'status' => $value['status'],
283 1
					'rank' => ++$extrasRank,
284 1
					'date' => $now
285 1
				])
286 1
				->save();
287 1
		}
288 1
	}
289
290 1
	/**
291 1
	 * insert the comments
292
	 *
293
	 * @since 3.1.0
294
	 *
295
	 * @param array $optionArray options of the installation
296
	 */
297
298
	public function insertComments(array $optionArray = []) : void
299 1
	{
300
		$now = $this->_registry->get('now');
301 1
		Db::forTablePrefix('comments')
302 1
			->create()
303 1
			->set(
304
			[
305 1
				'author' => $optionArray['adminUser'],
306
				'email' => $optionArray['adminEmail'],
307
				'text' => file_get_contents('database' . DIRECTORY_SEPARATOR . 'html' . DIRECTORY_SEPARATOR . 'comments' . DIRECTORY_SEPARATOR . 'hello.phtml'),
308
				'article' => 1,
309
				'rank' => 1,
310
				'date' => $now
311
			])
312
			->save();
313
	}
314
315
	/**
316
	 * insert the groups
317
	 *
318 1
	 * @since 3.1.0
319 1
	 */
320 1
321 1
	public function insertGroups() : void
322
	{
323 1
		Db::forTablePrefix('groups')
324
			->create()
325
			->set(
326
			[
327 1
				'name' => 'Administrators',
328 1
				'alias' => 'administrators',
329
				'description' => 'Unlimited access',
330
				'categories' => '[1, 2, 3]',
331
				'articles' => '[1, 2, 3]',
332
				'extras' => '[1, 2, 3]',
333
				'comments' => '[1, 2, 3]',
334
				'groups' => '[1, 2, 3]',
335
				'users' => '[1, 2, 3]',
336
				'modules' => '[1, 2, 3]',
337
				'settings' => 1,
338 1
				'filter' => 0
339
			])
340 1
			->save();
341 1
		Db::forTablePrefix('groups')
342 1
			->create()
343 1
			->set(
344 1
			[
345
				'name' => 'Members',
346 1
				'alias' => 'members',
347 1
				'description' => 'Default members group'
348 1
			])
349 1
			->save();
350 1
	}
351 1
352
	/**
353 1
	 * insert the users
354 1
	 *
355
	 * @since 3.1.0
356
	 *
357
	 * @param array $optionArray options of the installation
358
	 */
359
360
	public function insertUsers(array $optionArray = []) : void
361
	{
362 1
		$passwordHash = new Hash();
363
		$passwordHash->init($optionArray['adminPassword']);
364
		Db::forTablePrefix('users')
365
			->create()
366 1
			->set(
367
			[
368
				'name' => $optionArray['adminName'],
369
				'user' => $optionArray['adminUser'],
370
				'password' => $passwordHash->getHash(),
371
				'email' => $optionArray['adminEmail'],
372
				'description' => 'God admin',
373
				'groups' => '[1]'
374
			])
375
			->save();
376
	}
377
378 1
	/**
379
	 * insert the modules
380 1
	 *
381
	 * @since 3.1.0
382
	 */
383
384 1
	public function insertModules() : void
385
	{
386 1
		$moduleArray =
387 1
		[
388
			'AliasGenerator',
389
			'CallHome',
390 1
			'ConfirmAction',
391
			'FormValidator',
392
			'RankSorter',
393
			'TextareaResizer',
394
			'UnmaskPassword',
395
			'VisualEditor'
396
		];
397
398
		/* process modules */
399
400 1
		foreach ($moduleArray as $alias)
401
		{
402
			$moduleClass = 'Redaxscript\Modules\\' . $alias . '\\' . $alias;
403
404 1
			/* install */
405
406 1
			if (method_exists($moduleClass, 'install'))
407 1
			{
408
				$module = new $moduleClass($this->_registry, $this->_request, $this->_language, $this->_config);
409 1
				$module->install();
410
			}
411 1
		}
412 1
	}
413 1
414 1
	/**
415 1
	 * insert the settings
416 1
	 *
417 1
	 * @since 3.1.0
418 1
	 *
419 1
	 * @param array $optionArray options of the installation
420 1
	 */
421 1
422 1
	public function insertSettings(array $optionArray = []) : void
423 1
	{
424 1
		$settingArray =
425 1
		[
426 1
			'language' => null,
427 1
			'template' => null,
428 1
			'title' => $this->_language->get('_package')['name'],
429 1
			'author' => $optionArray['adminName'],
430
			'copyright' => null,
431
			'description' => $this->_language->get('_package')['description'],
432
			'keywords' => null,
433
			'robots' => 1,
434 1
			'email' => $optionArray['adminEmail'],
435
			'smtp' => null,
436 1
			'subject' => $this->_language->get('_package')['name'],
437 1
			'notification' => 0,
438 1
			'charset' => 'UTF-8',
439
			'locale' => 'en_US',
440 1
			'divider' => ' - ',
441 1
			'zone' => 'Europe/Berlin',
442
			'time' => 'H:i',
443 1
			'date' => 'd.m.Y',
444
			'homepage' => 0,
445 1
			'limit' => 10,
446
			'order' => 'asc',
447
			'pagination' => 1,
448
			'registration' => 0,
449
			'verification' => 0,
450
			'recovery' => 1,
451
			'moderation' => 0,
452
			'captcha' => 0,
453
			'version' => $this->_language->get('_package')['version']
454
		];
455
456 2
		/* process settings */
457
458 2
		foreach ($settingArray as $name => $value)
459 2
		{
460 2
			Db::forTablePrefix('settings')
461
				->create()
462
				->set(
463
				[
464 2
					'name' => $name,
465
					'value' => $value
466 2
				])
467 2
				->save();
468
		}
469 2
	}
470
471 2
	/**
472
	 * execute from sql
473 2
	 *
474
	 * @since 4.5.0
475
	 *
476 2
	 * @param string $type type of the database
477
	 * @param string $action action to process
478
	 * @param string $version version to process
479
	 *
480
	 * @return bool
481
	 */
482
483
	protected function _rawExecute(string $type = null, string $action = null, string $version = null) : bool
484
	{
485
		$actionFilesystem = new Filesystem\File();
486
		$actionFilesystem->init($this->_directory . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . $action);
487
		$actionFilesystemArray = $actionFilesystem->getSortArray();
488
		$dbPrefix = $this->_config->get('dbPrefix');
489
		$status = true;
490
491
		/* process filesystem */
492
493
		foreach ($actionFilesystemArray as $file)
494
		{
495
			$query = $this->_validateFileByVersion($file, $version) ? $actionFilesystem->readFile($file) : null;
496
			if ($query)
0 ignored issues
show
Bug Best Practice introduced by
The expression $query of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
497
			{
498
				if ($dbPrefix)
0 ignored issues
show
Bug Best Practice introduced by
The expression $dbPrefix of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
499
				{
500
					$query = str_replace($this->_prefixPlaceholder, $dbPrefix, $query);
501
				}
502
				try
503
				{
504
					Db::rawExecute($query);
505
				}
506
				catch (PDOException $exception)
507
				{
508
					$status = false;
509
				}
510
			}
511
		}
512
		return $status;
513
	}
514
515
	/**
516
	 * validate file by version
517
	 *
518
	 * @since 4.5.0
519
	 *
520
	 * @param string $file name of the file
521
	 * @param string $version version to process
522
	 *
523
	 * @return bool
524
	 */
525
526
	protected function _validateFileByVersion(string $file = null, string $version = null) : bool
527
	{
528
		$fileArray = explode('_', $file);
529
		return version_compare($version, $fileArray[0], '<');
530
	}
531
}
532