Completed
Push — master ( 77bd5e...c97259 )
by Nazar
04:13
created

functions.php ➔ install_process()   F

Complexity

Conditions 25
Paths 745

Size

Total Lines 300
Code Lines 180

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 25
eloc 180
nc 745
nop 2
dl 0
loc 300
rs 2.2307

How to fix   Long Method    Complexity   

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
 * @package    CleverStyle CMS
4
 * @subpackage Installer
5
 * @author     Nazar Mokrynskyi <[email protected]>
6
 * @copyright  Copyright (c) 2011-2016, Nazar Mokrynskyi
7
 * @license    MIT License, see license.txt
8
 */
9
function install_form () {
10
	$timezones = get_timezones_list();
11
	return h::{'form[method=post]'}(
12
		h::nav(
13
			h::{'radio[name=mode]'}(
14
				[
15
					'value'   => ['1', '0'],
16
					'in'      => [h::span('Regular user'), h::span('Expert')],
17
					'onclick' =>
18
						"var items = document.getElementsByClassName('expert');"
19
						."for (var i = 0; i < items.length; i++) {"
20
						."items.item(i).style.display = this.value == '0' ? 'table-row' : '';"
21
						."}"
22
				]
23
			)
24
		).
25
		h::table(
26
			h::{'tr td'}(
27
				'Site name:',
28
				h::{'input[name=site_name]'}()
29
			).
30
			h::{'tr.expert td'}(
31
				'Database engine:',
32
				h::{'select[name=db_engine][size=3][selected=MySQLi]'}(
33
					file_get_json(DIR.'/db_engines.json')
34
				)
35
			).
36
			h::{'tr.expert td'}(
37
				'Database host:',
38
				h::{'input[name=db_host][value=localhost]'}(
39
					[
40
						'placeholder' => 'Relative or absolute path to DB for SQLite'
41
					]
42
				)
43
			).
44
			h::{'tr td'}(
45
				'Database name:',
46
				h::{'input[name=db_name]'}()
47
			).
48
			h::{'tr td'}(
49
				'Database user:',
50
				h::{'input[name=db_user]'}()
51
			).
52
			h::{'tr td'}(
53
				'Database user password:',
54
				h::{'input[type=password][name=db_password]'}()
55
			).
56
			h::{'tr.expert td'}(
57
				'Database tables prefix:',
58
				h::{'input[name=db_prefix]'}(
59
					[
60
						'value' => substr(md5(random_bytes(1000)), 0, 5).'_'
61
					]
62
				)
63
			).
64
			h::{'tr.expert td'}(
65
				'Database charset:',
66
				h::{'input[name=db_charset][value=utf8mb4]'}()
67
			).
68
			h::{'tr td'}(
69
				'Timezone:',
70
				h::{'select[name=timezone][size=7][selected=UTC]'}(
71
					[
72
						'in'    => array_keys($timezones),
73
						'value' => array_values($timezones)
74
					]
75
				)
76
			).
77
			h::{'tr td'}(
78
				'Language:',
79
				h::{'select[name=language][size=3][selected=English]'}(
80
					file_get_json(DIR.'/languages.json')
81
				)
82
			).
83
			h::{'tr td'}(
84
				'Email of administrator:',
85
				h::{'input[type=email][name=admin_email]'}()
86
			).
87
			h::{'tr td'}(
88
				'Administrator password:',
89
				h::{'input[type=password][name=admin_password]'}()
90
			)
91
		).
92
		h::{'button.readme'}(
93
			'Readme',
94
			[
95
				'onclick' => "window.open('readme.html', 'readme', 'location=no')"
96
			]
97
		).
98
		h::{'button.license'}(
99
			'License',
100
			[
101
				'onclick' => "window.open('license.txt', 'license', 'location=no')"
102
			]
103
		).
104
		h::{'button[type=submit]'}(
105
			'Install'
106
		)
107
	);
108
}
109
110
/**
111
 * @param array[]    $fs
112
 * @param array|null $argv
113
 *
114
 * @return string
115
 */
116
function install_process ($fs, $argv = null) {
117
	/**
118
	 * Connecting to the DataBase
119
	 */
120
	define('DEBUG', false);
121
	/**
122
	 * DataBase structure import
123
	 */
124
	if (!file_exists(DIR."/install/DB/$_POST[db_engine].sql")) {
125
		return "Can't find system tables structure for selected database engine! Installation aborted.";
126
	}
127
	$Request = \cs\Request::instance();
128
	/**
129
	 * General system configuration
130
	 */
131
	if (isset($_POST['site_url'])) {
132
		$url = $_POST['site_url'];
133
	} else {
134
		$Request->init_server($_SERVER);
135
		$url = "$Request->scheme://$Request->host$Request->path";
136
		$url = implode('/', array_slice(explode('/', $url), 0, -2)); //Remove 2 last items
137
	}
138
	preg_match('#//([^/]+)#', $url, $domain);
139
	$domain = explode(':', $domain[1])[0];
140
	$config = [
141
		'name'                              => $_POST['site_name'],
142
		'url'                               => [$url],
143
		'admin_email'                       => $_POST['admin_email'],
144
		'closed_title'                      => 'Site closed',
145
		'closed_text'                       => '<p>Site closed for maintenance</p>',
146
		'site_mode'                         => 1,
147
		'title_delimiter'                   => ' | ',
148
		'title_reverse'                     => 0,
149
		'cache_compress_js_css'             => 1,
150
		'vulcanization'                     => 1,
151
		'put_js_after_body'                 => 1,
152
		'theme'                             => 'CleverStyle',
153
		'language'                          => $_POST['language'],
154
		'active_languages'                  => [$_POST['language']],
155
		'multilingual'                      => 0,
156
		'db_balance'                        => 0,
157
		'db_mirror_mode'                    => \cs\DB::MIRROR_MODE_MASTER_MASTER,
158
		'cookie_prefix'                     => '',
159
		'cookie_domain'                     => [$domain],
160
		'inserts_limit'                     => 1000,
161
		'key_expire'                        => 120,
162
		'gravatar_support'                  => 0,
163
		'session_expire'                    => 2592000,
164
		'update_ratio'                      => 75,
165
		'sign_in_attempts_block_count'      => 0,
166
		'sign_in_attempts_block_time'       => 5,
167
		'timezone'                          => $_POST['timezone'],
168
		'password_min_length'               => 4,
169
		'password_min_strength'             => 3,
170
		'smtp'                              => 0,
171
		'smtp_host'                         => '',
172
		'smtp_port'                         => '',
173
		'smtp_secure'                       => '',
174
		'smtp_auth'                         => 0,
175
		'smtp_user'                         => '',
176
		'smtp_password'                     => '',
177
		'mail_from'                         => $_POST['admin_email'],
178
		'mail_from_name'                    => "Administrator of $_POST[site_name]",
179
		'allow_user_registration'           => 1,
180
		'require_registration_confirmation' => 1,
181
		'auto_sign_in_after_registration'   => 1,
182
		'registration_confirmation_time'    => 1,
183
		'mail_signature'                    => '',
184
		'remember_user_ip'                  => 0,
185
		'simple_admin_mode'                 => !isset($_POST['mode']) || $_POST['mode'] ? 1 : 0,
186
		'default_module'                    => 'System'
187
	];
188
	/**
189
	 * Extracting of engine's files
190
	 */
191
	$extracted = array_filter(
192
		array_map(
193
			function ($index, $file) {
194
				if (
195
					!file_exists(dirname(ROOT."/$file")) &&
196
					!mkdir(dirname(ROOT."/$file"), 0770, true)
197
				) {
198
					return false;
199
				}
200
				/**
201
				 * TODO: copy() + file_exists() is a hack for HHVM, when bug fixed upstream (copying of empty files) this should be simplified
202
				 */
203
				copy(DIR."/fs/$index", ROOT."/$file");
204
				return file_exists(ROOT."/$file");
205
			},
206
			$fs,
207
			array_keys($fs)
208
		)
209
	);
210
	if (
211
		count($extracted) !== count($fs) ||
212
		!(file_exists(ROOT.'/storage') || mkdir(ROOT.'/storage', 0770)) ||
213
		!file_put_contents(ROOT.'/storage/.htaccess', "Deny from all\nRewriteEngine Off\n<Files *>\n\tSetHandler default-handler\n</Files>")
214
	) {
215
		return "Can't extract system files from the archive! Installation aborted.";
216
	}
217
	/**
218
	 * Basic system configuration
219
	 */
220
	$public_key  = hash('sha512', random_bytes(1000));
221
	$main_config = is_dir(ROOT.'/config') && file_put_contents(
222
			ROOT.'/config/main.json',
223
			str_replace(
224
				[
225
					'@domain',
226
					'@timezone',
227
					'@db_host',
228
					'@db_type',
229
					'@db_name',
230
					'@db_user',
231
					'@db_password',
232
					'@db_prefix',
233
					'@db_charset',
234
					'@language',
235
					'@public_key'
236
				],
237
				[
238
					$config['cookie_domain'][0],
239
					$_POST['timezone'],
240
					$_POST['db_host'],
241
					$_POST['db_engine'],
242
					$_POST['db_name'],
243
					$_POST['db_user'],
244
					str_replace('"', '\\"', $_POST['db_password']),
245
					$_POST['db_prefix'],
246
					$_POST['db_charset'],
247
					$_POST['language'],
248
					$public_key
249
				],
250
				'{
251
//Domain of main mirror
252
	"domain"			: "@domain",
253
//Base timezone
254
	"timezone"			: "@timezone",
255
//Settings of main DB
256
	"db_host"			: "@db_host",
257
	"db_type"			: "@db_type",
258
	"db_name"			: "@db_name",
259
	"db_user"			: "@db_user",
260
	"db_password"		: "@db_password",
261
	"db_prefix"			: "@db_prefix",
262
	"db_charset"		: "@db_charset",
263
//Settings of main Storage
264
	"storage_type"		: "Local",
265
	"storage_url"		: "",
266
	"storage_host"		: "localhost",
267
	"storage_user"		: "",
268
	"storage_password"	: "",
269
//Base language
270
	"language"			: "@language",
271
//Cache engine
272
	"cache_engine"		: "FileSystem",
273
//Settings of Memcached cache engine
274
	"memcache_host"		: "127.0.0.1",
275
	"memcache_port"		: "11211",
276
//Any length
277
	"public_key"		: "@public_key"
278
}'
279
			)
280
		);
281
	extension_loaded('apc') && apc_clear_cache('user');
282
	if (!$main_config) {
283
		return "Can't write base system configuration! Installation aborted.";
284
	}
285
	chmod(ROOT.'/config/main.json', 0600);
286
	/**
287
	 * @var \cs\DB\_Abstract $cdb
288
	 */
289
	$cdb = "cs\\DB\\$_POST[db_engine]";
290
	$cdb = new $cdb(
291
		$_POST['db_name'],
292
		$_POST['db_user'],
293
		$_POST['db_password'],
294
		$_POST['db_host'],
295
		$_POST['db_charset'],
296
		$_POST['db_prefix']
297
	);
298
	if (!is_object($cdb) || !$cdb->connected()) {
299
		return 'Database connection failed! Installation aborted.';
300
	}
301
	if (!$cdb->q(
302
		array_filter(
303
			explode(';', file_get_contents(DIR."/install/DB/$_POST[db_engine].sql")),
304
			'_trim'
305
		)
306
	)
307
	) {
308
		return "Can't import system tables structure for selected database engine! Installation aborted.";
309
	}
310
	/**
311
	 * General configuration import
312
	 */
313
	$modules = [
314
		'System' => [
315
			'active' => 1,
316
			'db'     => [
317
				'keys'  => '0',
318
				'users' => '0',
319
				'texts' => '0'
320
			]
321
		]
322
	];
323
	if (file_exists(DIR.'/modules.json')) {
324
		foreach (file_get_json(DIR.'/modules.json') as $module) {
325
			$modules[$module] = [
326
				'active'  => -1,
327
				'db'      => [],
328
				'storage' => []
329
			];
330
		}
331
		unset($module);
332
	}
333
	if (!$cdb->q(
334
		"INSERT INTO `[prefix]config` (
335
			`domain`, `core`, `db`, `storage`, `components`
336
		) VALUES (
337
			'%s', '%s', '[]', '[]', '%s'
338
		)",
339
		$config['cookie_domain'][0],
340
		_json_encode($config),
341
		'{"modules":'._json_encode($modules).',"plugins":[],"blocks":[]}'
342
	)
343
	) {
344
		return "Can't import system configuration into database! Installation aborted.";
345
	}
346
	unset($modules);
347
	/**
348
	 * Administrator registration
349
	 */
350
	$admin_login = strstr($_POST['admin_email'], '@', true);
351
	if (!$cdb->q(
352
		"INSERT INTO `[prefix]users` (
353
			`login`, `login_hash`, `password_hash`, `email`, `email_hash`, `reg_date`, `reg_ip`, `status`
354
		) VALUES (
355
			'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'
356
		)",
357
		$admin_login,
358
		hash('sha224', $admin_login),
359
		password_hash(hash('sha512', hash('sha512', $_POST['admin_password']).$public_key), PASSWORD_DEFAULT),
360
		$_POST['admin_email'],
361
		hash('sha224', $_POST['admin_email']),
362
		time(),
363
		ip2hex($Request->remote_addr),
364
		1
365
	)
366
	) {
367
		return "Can't register administrator user! Installation aborted.";
368
	}
369
	/**
370
	 * Disconnecting from the DataBase, removing of installer file
371
	 */
372
	$cdb->__destruct();
373
	$warning   = false;
374
	$cli       = PHP_SAPI == 'cli';
375
	$installer = $cli ? ROOT."/$argv[0]" : ROOT.'/'.pathinfo(DIR, PATHINFO_BASENAME);
376
	if (!is_writable($installer) || !unlink($installer)) {
377
		$warning = "Please, remove installer file $installer for security!\n";
378
	}
379
	if ($cli) {
380
		return "Congratulations! CleverStyle CMS has been installed successfully!\n$warning\nLogin: $admin_login\nPassword: $_POST[admin_password]";
381
	} else {
382
		return
383
			h::h3(
384
				'Congratulations! CleverStyle CMS has been installed successfully!'
385
			).
386
			h::{'table tr| td'}(
387
				[
388
					'Your sign in information:',
389
					[
390
						'colspan' => 2
391
					]
392
				],
393
				[
394
					'Login:',
395
					$admin_login
396
				],
397
				[
398
					'Password:',
399
					$_POST['admin_password']
400
				]
401
			).
402
			h::p(
403
				$warning,
404
				[
405
					'style' => 'color: red;'
406
				]
407
			).
408
			h::button(
409
				'Go to website',
410
				[
411
					'onclick' => "location.href = '/';"
412
				]
413
			);
414
	}
415
}
416