Completed
Push — master ( 4b7f62...6a99e5 )
by Nazar
04:14
created

functions.php ➔ install_form()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 100
Code Lines 63

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
eloc 63
nc 1
nop 0
dl 0
loc 100
rs 8.2857

How to fix   Long Method   

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