Passed
Push — master ( ed9e0d...77c88c )
by Georgi
02:57
created

SystemInstallWizard   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 395
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 284
c 4
b 0
f 0
dl 0
loc 395
rs 10
wmc 15

11 Methods

Rating   Name   Duplication   Size   Complexity  
A stepEnvironment() 0 9 1
B getDisplayLanguages() 0 186 1
A init() 0 5 1
A stepWelcome() 0 35 2
A stepDatabase() 0 43 4
A performInstallationSteps() 0 17 1
A stepUser() 0 31 1
A stepLicense() 0 26 1
A addRequiredNote() 0 5 1
A setForm() 0 3 1
A stepInstallationCompleted() 0 3 1
1
<?php
2
3
namespace Epesi\Core\System;
4
5
use Epesi\Core\System\Seeds\Form;
6
use atk4\ui\jsExpression;
7
use atk4\ui\Wizard;
8
use Illuminate\Support\Facades\Artisan;
9
use Epesi\Core\System\Integration\Modules\Concerns\HasAdminMode;
10
use Illuminate\Support\Facades\App;
11
use Epesi\Core\System\Integration\Modules\ModuleManager;
12
use Epesi\Base\User\Database\Models\User;
0 ignored issues
show
Bug introduced by
The type Epesi\Base\User\Database\Models\User 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...
13
use Illuminate\Support\Facades\Hash;
14
15
class SystemInstallWizard extends Wizard
16
{
17
	use HasAdminMode;
18
	
19
	public function init()
20
	{
21
		parent::init();
22
23
		$this->setAdminMode()->performInstallationSteps();
24
	}
25
	
26
	public function performInstallationSteps()
27
	{
28
		$this->addStep(__('Welcome'), [__CLASS__, 'stepWelcome']);
29
		
30
		$this->addStep([__('License'), 'icon'=>'id card', 'description'=>__('Accept license conditions')], [__CLASS__, 'stepLicense']);
31
			
32
		$this->addStep([__('Database'), 'icon'=>'database', 'description'=>__('Database connection settings')], [__CLASS__, 'stepDatabase']);
33
		
34
		$this->addStep([__('Environment'), 'icon'=>'configure', 'description'=>__('Check environment')], [__CLASS__, 'stepEnvironment']);
35
		
36
		$this->addStep([__('Super Admin'), 'icon'=>'user', 'description'=>__('Create first user')], [__CLASS__, 'stepUser']);
37
		
38
		$this->addStep([__('Complete'), 'icon'=>'check', 'description'=>__('Complete installation')], [__CLASS__, 'stepInstallationCompleted']);
39
		
40
		// below step is skipped because of redirecting to 'login' path once system installed
41
		// see Epesi\Core\Controllers\SystemController::install
42
		$this->addFinish([__CLASS__, 'stepInstallationCompleted']);
43
	}
44
	
45
	public function addRequiredNote()
46
	{
47
		$this->add(['View', __('denotes required field'), 'class' => ['required-note']])->setStyle(['float' => 'right']);
48
		
49
		eval_css('
50
			.required-note::before {
51
				margin: 0 .2em 0 0;
52
				content: \'*\';
53
				color: #db2828;
54
			}
55
		');
56
	}
57
	
58
	public function setForm($form)
59
	{
60
		$this->buttonNext->on('click', $form->js()->submit());
61
	}
62
	
63
	public static function stepWelcome($wizard)
64
	{
65
		$columns = $wizard->add('Columns');
66
		
67
		$column = $columns->addColumn();
68
		$column->add(['Message', __('Thank you for downloading EPESI!')])->text
69
		->addParagraph(__('This wizard will guide you though the process of setting up your new CRM / ERP installation'))
70
		->addParagraph(__('Select the installation language and click NEXT button to proceed to next step'));
71
		
72
		$column = $columns->addColumn();
73
74
		if (! function_exists('locale_get_display_language')) {
75
			$column->addClass('middle aligned');
76
			$column->add(['Label', __('Install php-intl extension to enable language selection!'), 'class' => ['red']]);
77
			
78
			return;
79
		}
80
81
		$systemLanguages = app()->make(\JoeDixon\Translation\Drivers\Translation::class)->allLanguages()->toArray();
82
83
		$values = array_intersect_key(self::getDisplayLanguages(), $systemLanguages);
84
		
85
		$form = $column->add(new Form());
86
		
87
		$form->addField('language', ['DropDown', 'values' => $values, 'caption' => __('Select Language'), 'iconLeft' => 'globe'], ['required'=>true])->set($wizard->recall('language', 'en'));
88
		
89
		$form->onSubmit(function ($form) use ($wizard) {
90
			$wizard->memorize('language', $form->model['language']);
91
			
92
			App::setLocale($form->model['language']);
93
			
94
			return $wizard->jsNext();
95
		});
96
97
		$wizard->setForm($form);
98
	}
99
	
100
	public static function stepLicense($wizard)
101
	{
102
		$columns = $wizard->add('Columns');
103
		$column = $columns->addColumn();
104
		
105
		$license = $column->add(['View', 'defaultTemplate' => 'license.html'])->setStyle(['max-height' => '500px', 'overflow' => 'auto', 'padding' => '5px']);
106
		
107
		$license->js(true)->niceScroll();
108
		
109
		$license->template->setHTML('epesi', config('epesi.app.title'));
110
		
111
		$license->template->setHTML('copyright', config('epesi.app.copyright'));
112
		
113
		$column = $columns->addColumn();
114
		
115
		$form = $column->add(new Form());
116
		$form->addField('copyright', ['Checkbox', 'caption' => __('I will not remove the Copyright notice as required by the MIT license.')], ['required'=>true]);
117
		$form->addField('logo', ['Checkbox', 'caption' => __('I will not remove ":epesi powered" logo and the link from the application login screen or the toolbar.', ['epesi' => config('epesi.app.title')])], ['required'=>true]);
118
		$form->addField('support', ['Checkbox', 'caption' => __('I will not remove "Support -> About" credit page from the application menu.')], ['required'=>true]);
119
		$form->addField('store', ['Checkbox', 'caption' => __('I will not remove or rename ":epesi Store" links from the application.', ['epesi' => config('epesi.app.title')])], ['required'=>true]);
120
		
121
		$form->onSubmit(function ($form) use ($wizard) {
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

121
		$form->onSubmit(function (/** @scrutinizer ignore-unused */ $form) use ($wizard) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
122
			return $wizard->jsNext();
123
		});
124
			
125
		$wizard->setForm($form);
126
	}
127
	
128
	public static function stepDatabase($wizard)
129
	{
130
		$wizard->addRequiredNote();
131
		
132
		$form = $wizard->add('Form');
133
		
134
		$form->addField('host', __('Database Host'), ['required'=>true])->placeholder = __('e.g. localhost');
135
		$form->addField('port', __('Database Port'));
136
		
137
		$form->addField('driver', ['DropDown', 'values' => [
138
				'mysql' => 'MySQL',
139
				'postgre' => 'PostgeSQL',
140
		], 'caption' => __('Database Engine')], ['required'=>true]);
141
		
142
		$form->addField('database', __('Database Name'));
143
		$form->addField('username', __('Database Server User'), ['required'=>true]);
144
		$form->addField('password', ['Password', 'caption' => __('Database Server Password')], ['required'=>true]);
145
		
146
		$form->addField('create', ['Checkbox', 'caption' => __('Create New Database')])->on('change', new jsExpression('if ($(event.target).is(":checked")) alert([])', [__('WARNING: Make sure you have CREATE access level to do this!')]));
147
148
		foreach ($wizard->recall('connection', []) as $name => $value) {
149
			if (! $field = $form->fields[$name]?? null) continue;
150
			
151
			$field->set($value);
152
		}
153
154
		$form->onSubmit(function ($form) use ($wizard) {
155
			$connection = $form->model->get();
156
157
			$wizard->memorize('connection', $connection);
158
159
			Artisan::call('epesi:database-connection', ['--connection' => $connection]);
160
		
161
			if ($connection['create']) {
162
				Artisan::call('epesi:database-create', ['name' => $connection['database'], '--connection' => $connection]);
163
			}
164
			
165
			ModuleManager::clearCache();
166
			
167
			Artisan::call('config:clear');
168
			Artisan::call('cache:clear');
169
170
			return $wizard->jsNext();
171
		});
172
	}
173
	
174
	public static function stepEnvironment($wizard)
175
	{
176
		Artisan::call('migrate');
177
		
178
		ob_start();
179
		ModuleManager::install('system');
180
		ob_end_clean();
181
		
182
		$wizard->add(new SystemEnvironmentOverview());
183
	}
184
	
185
	public static function stepUser($wizard)
186
	{
187
		$wizard->addRequiredNote();
188
		
189
		$form = $wizard->add([new Form, 'buttonSave' => 'Button']);
190
		
191
		$form->addField('name', __('Name'), ['required'=>true])->placeholder = __('e.g. John Doe');
192
		$form->addField('email', __('Email'), ['required'=>true])->placeholder = __('e.g. [email protected]');
193
		$form->addField('password', ['Password', 'caption' => __('Password')], ['required'=>true]);
194
		$form->addField('password_verify', ['Password', 'caption' => __('Verify Password')], ['required'=>true]);
195
		
196
		$form->addFieldRules('email', [[
197
				'type'   => 'email',
198
				'prompt' => __('Invalid email address')
199
		]]);
200
		
201
		$form->addFieldRules('password_verify', [[
202
				'type'   => 'match[password]',
203
				'prompt' => __('Password mismatch')
204
		]]);
205
		
206
		$form->validate(function ($form) use ($wizard) {
207
			$user = $form->model->get();
208
			
209
			User::create([
210
					'name' => $user['name'],
211
					'email' => $user['email'],
212
					'password' => Hash::make($user['password']),
213
			])->assignRole('Super Admin');
214
			
215
			return $wizard->jsNext();
216
		});
217
	}
218
	
219
	public static function stepInstallationCompleted($wizard)
220
	{
221
		$wizard->add(['Header', __(':epesi was successfully installed!', ['epesi' => config('epesi.app.title')]), 'huge centered']);
222
	}
223
224
	public static function getDisplayLanguages() {
225
		return [
226
				'aa' => __('Afar'),
227
				'ab' => __('Abkhazian'),
228
				'ae' => __('Avestan'),
229
				'af' => __('Afrikaans'),
230
				'ak' => __('Akan'),
231
				'am' => __('Amharic'),
232
				'an' => __('Aragonese'),
233
				'ar' => __('Arabic'),
234
				'as' => __('Assamese'),
235
				'av' => __('Avaric'),
236
				'ay' => __('Aymara'),
237
				'az' => __('Azerbaijani'),
238
				'ba' => __('Bashkir'),
239
				'be' => __('Belarusian'),
240
				'bg' => __('Bulgarian'),
241
				'bh' => __('Bihari'),
242
				'bi' => __('Bislama'),
243
				'bm' => __('Bambara'),
244
				'bn' => __('Bengali'),
245
				'bo' => __('Tibetan'),
246
				'br' => __('Breton'),
247
				'bs' => __('Bosnian'),
248
				'ca' => __('Catalan'),
249
				'ce' => __('Chechen'),
250
				'ch' => __('Chamorro'),
251
				'co' => __('Corsican'),
252
				'cr' => __('Cree'),
253
				'cs' => __('Czech'),
254
				'cu' => __('Church Slavic'),
255
				'cv' => __('Chuvash'),
256
				'cy' => __('Welsh'),
257
				'da' => __('Danish'),
258
				'de' => __('German'),
259
				'dv' => __('Divehi'),
260
				'dz' => __('Dzongkha'),
261
				'ee' => __('Ewe'),
262
				'el' => __('Greek'),
263
				'en' => __('English'),
264
				'eo' => __('Esperanto'),
265
				'es' => __('Spanish'),
266
				'et' => __('Estonian'),
267
				'eu' => __('Basque'),
268
				'fa' => __('Persian'),
269
				'ff' => __('Fulah'),
270
				'fi' => __('Finnish'),
271
				'fj' => __('Fijian'),
272
				'fo' => __('Faroese'),
273
				'fr' => __('French'),
274
				'fy' => __('Western Frisian'),
275
				'ga' => __('Irish'),
276
				'gd' => __('Scottish Gaelic'),
277
				'gl' => __('Galician'),
278
				'gn' => __('Guarani'),
279
				'gu' => __('Gujarati'),
280
				'gv' => __('Manx'),
281
				'ha' => __('Hausa'),
282
				'he' => __('Hebrew'),
283
				'hi' => __('Hindi'),
284
				'ho' => __('Hiri Motu'),
285
				'hr' => __('Croatian'),
286
				'ht' => __('Haitian'),
287
				'hu' => __('Hungarian'),
288
				'hy' => __('Armenian'),
289
				'hz' => __('Herero'),
290
				'ia' => __('Interlingua (International Auxiliary Language Association)'),
291
				'id' => __('Indonesian'),
292
				'ie' => __('Interlingue'),
293
				'ig' => __('Igbo'),
294
				'ii' => __('Sichuan Yi'),
295
				'ik' => __('Inupiaq'),
296
				'io' => __('Ido'),
297
				'is' => __('Icelandic'),
298
				'it' => __('Italian'),
299
				'iu' => __('Inuktitut'),
300
				'ja' => __('Japanese'),
301
				'jv' => __('Javanese'),
302
				'ka' => __('Georgian'),
303
				'kg' => __('Kongo'),
304
				'ki' => __('Kikuyu'),
305
				'kj' => __('Kwanyama'),
306
				'kk' => __('Kazakh'),
307
				'kl' => __('Kalaallisut'),
308
				'km' => __('Khmer'),
309
				'kn' => __('Kannada'),
310
				'ko' => __('Korean'),
311
				'kr' => __('Kanuri'),
312
				'ks' => __('Kashmiri'),
313
				'ku' => __('Kurdish'),
314
				'kv' => __('Komi'),
315
				'kw' => __('Cornish'),
316
				'ky' => __('Kirghiz'),
317
				'la' => __('Latin'),
318
				'lb' => __('Luxembourgish'),
319
				'lg' => __('Ganda'),
320
				'li' => __('Limburgish'),
321
				'ln' => __('Lingala'),
322
				'lo' => __('Lao'),
323
				'lt' => __('Lithuanian'),
324
				'lu' => __('Luba-Katanga'),
325
				'lv' => __('Latvian'),
326
				'mg' => __('Malagasy'),
327
				'mh' => __('Marshallese'),
328
				'mi' => __('Maori'),
329
				'mk' => __('Macedonian'),
330
				'ml' => __('Malayalam'),
331
				'mn' => __('Mongolian'),
332
				'mr' => __('Marathi'),
333
				'ms' => __('Malay'),
334
				'mt' => __('Maltese'),
335
				'my' => __('Burmese'),
336
				'na' => __('Nauru'),
337
				'nb' => __('Norwegian Bokmal'),
338
				'nd' => __('North Ndebele'),
339
				'ne' => __('Nepali'),
340
				'ng' => __('Ndonga'),
341
				'nl' => __('Dutch'),
342
				'nn' => __('Norwegian Nynorsk'),
343
				'no' => __('Norwegian'),
344
				'nr' => __('South Ndebele'),
345
				'nv' => __('Navajo'),
346
				'ny' => __('Chichewa'),
347
				'oc' => __('Occitan'),
348
				'oj' => __('Ojibwa'),
349
				'om' => __('Oromo'),
350
				'or' => __('Oriya'),
351
				'os' => __('Ossetian'),
352
				'pa' => __('Panjabi'),
353
				'pi' => __('Pali'),
354
				'pl' => __('Polish'),
355
				'ps' => __('Pashto'),
356
				'pt' => __('Portuguese'),
357
				'qu' => __('Quechua'),
358
				'rm' => __('Raeto-Romance'),
359
				'rn' => __('Kirundi'),
360
				'ro' => __('Romanian'),
361
				'ru' => __('Russian'),
362
				'rw' => __('Kinyarwanda'),
363
				'sa' => __('Sanskrit'),
364
				'sc' => __('Sardinian'),
365
				'sd' => __('Sindhi'),
366
				'se' => __('Northern Sami'),
367
				'sg' => __('Sango'),
368
				'si' => __('Sinhala'),
369
				'sk' => __('Slovak'),
370
				'sl' => __('Slovenian'),
371
				'sm' => __('Samoan'),
372
				'sn' => __('Shona'),
373
				'so' => __('Somali'),
374
				'sq' => __('Albanian'),
375
				'sr' => __('Serbian'),
376
				'ss' => __('Swati'),
377
				'st' => __('Southern Sotho'),
378
				'su' => __('Sundanese'),
379
				'sv' => __('Swedish'),
380
				'sw' => __('Swahili'),
381
				'ta' => __('Tamil'),
382
				'te' => __('Telugu'),
383
				'tg' => __('Tajik'),
384
				'th' => __('Thai'),
385
				'ti' => __('Tigrinya'),
386
				'tk' => __('Turkmen'),
387
				'tl' => __('Tagalog'),
388
				'tn' => __('Tswana'),
389
				'to' => __('Tonga'),
390
				'tr' => __('Turkish'),
391
				'ts' => __('Tsonga'),
392
				'tt' => __('Tatar'),
393
				'tw' => __('Twi'),
394
				'ty' => __('Tahitian'),
395
				'ug' => __('Uighur'),
396
				'uk' => __('Ukrainian'),
397
				'ur' => __('Urdu'),
398
				'uz' => __('Uzbek'),
399
				've' => __('Venda'),
400
				'vi' => __('Vietnamese'),
401
				'vo' => __('Volapuk'),
402
				'wa' => __('Walloon'),
403
				'wo' => __('Wolof'),
404
				'xh' => __('Xhosa'),
405
				'yi' => __('Yiddish'),
406
				'yo' => __('Yoruba'),
407
				'za' => __('Zhuang'),
408
				'zh' => __('Chinese'),
409
				'zu' => __('Zulu')
410
		];
411
	}
412
}
413