Install   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 177
dl 0
loc 301
rs 10
c 0
b 0
f 0
wmc 23

8 Methods

Rating   Name   Duplication   Size   Complexity  
A doStep1Action() 0 10 3
A getStep() 0 3 1
A doStep2Action() 0 20 5
B createTheSchemasTables() 0 133 2
A doStepAction() 0 10 4
A createTheAdministrator() 0 35 4
A addTheDefaultOptions() 0 20 1
A __invoke() 0 15 3
1
<?php
2
/**
3
 * Install page controller class file
4
 *
5
 * @package    EBloodBank
6
 * @subpackage Controllers
7
 * @since      1.0
8
 */
9
namespace EBloodBank\Controllers;
10
11
use DateTime;
12
use DateTimeZone;
13
use Exception;
14
use InvalidArgumentException;
15
use EBloodBank as EBB;
16
use EBloodBank\Notices;
17
use EBloodBank\Options;
18
use EBloodBank\Models\User;
19
20
/**
21
 * Install page controller class
22
 *
23
 * @since 1.0
24
 */
25
class Install extends Controller
26
{
27
    /**
28
     * @return void
29
     * @since 1.0
30
     */
31
    public function __invoke()
32
    {
33
        $connection = $this->getContainer()->get('db_connection');
34
        if (EBB\getInstallationStatus($connection) !== EBB\DATABASE_INSTALLED || Options::getOption('installing')) {
0 ignored issues
show
Bug introduced by
The function getInstallationStatus was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

34
        if (/** @scrutinizer ignore-call */ EBB\getInstallationStatus($connection) !== EBB\DATABASE_INSTALLED || Options::getOption('installing')) {
Loading history...
35
            $this->doStepAction();
36
            $view = $this->viewFactory->forgeView('install', [
37
                'step' => $this->getStep(),
38
                'status' => 'installing',
39
            ]);
40
        } else {
41
            $view = $this->viewFactory->forgeView('install', [
42
                'status' => 'installed',
43
            ]);
44
        }
45
        $view();
46
    }
47
48
    /**
49
     * @return int
50
     * @since 1.0
51
     */
52
    protected function getStep()
53
    {
54
        return max((int) filter_input(INPUT_GET, 'step'), 1);
55
    }
56
57
    /**
58
     * @return void
59
     * @since 1.0
60
     */
61
    protected function doStepAction()
62
    {
63
        if ('install' === filter_input(INPUT_POST, 'action')) {
64
            switch ($this->getStep()) {
65
                case 1:
66
                    $this->doStep1Action();
67
                    break;
68
                case 2:
69
                    $this->doStep2Action();
70
                    break;
71
            }
72
        }
73
    }
74
75
    /**
76
     * @return void
77
     * @since 1.0
78
     */
79
    protected function doStep1Action()
80
    {
81
        $connection = $this->getContainer()->get('db_connection');
82
        if (EBB\isDatabaseSelected($connection)) {
0 ignored issues
show
Bug introduced by
The function isDatabaseSelected was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

82
        if (/** @scrutinizer ignore-call */ EBB\isDatabaseSelected($connection)) {
Loading history...
83
            EBB\tryDatabaseConnection($connection);
0 ignored issues
show
Bug introduced by
The function tryDatabaseConnection was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

83
            /** @scrutinizer ignore-call */ 
84
            EBB\tryDatabaseConnection($connection);
Loading history...
84
            if (EBB\isDatabaseConnected($connection)) {
0 ignored issues
show
Bug introduced by
The function isDatabaseConnected was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

84
            if (/** @scrutinizer ignore-call */ EBB\isDatabaseConnected($connection)) {
Loading history...
85
                EBB\redirect(
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

85
                /** @scrutinizer ignore-call */ 
86
                EBB\redirect(
Loading history...
86
                    EBB\addQueryArgs(
0 ignored issues
show
Bug introduced by
The function addQueryArgs was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

86
                    /** @scrutinizer ignore-call */ 
87
                    EBB\addQueryArgs(
Loading history...
87
                        EBB\getInstallerURL(),
0 ignored issues
show
Bug introduced by
The function getInstallerURL was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

87
                        /** @scrutinizer ignore-call */ 
88
                        EBB\getInstallerURL(),
Loading history...
88
                        ['step' => 2]
89
                    )
90
                );
91
            }
92
        }
93
    }
94
95
    /**
96
     * @return void
97
     * @since 1.3
98
     */
99
    protected function createTheSchemasTables()
100
    {
101
        $stmts = [];
102
        $connection = $this->getContainer()->get('db_connection');
103
104
        /*** Users Table **************************************************/
105
106
        $stmts[] = <<<'SQL'
107
CREATE TABLE IF NOT EXISTS `user` (
108
  `user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
109
  `user_name` VARCHAR(255) NOT NULL,
110
  `user_email` VARCHAR(100) NOT NULL,
111
  `user_pass` VARCHAR(128) NOT NULL,
112
  `user_role` VARCHAR(45) NOT NULL,
113
  `user_created_at` DATETIME NOT NULL,
114
  `user_status` VARCHAR(45) NOT NULL,
115
  `user_meta` JSON NULL,
116
  PRIMARY KEY (`user_id`))
117
ENGINE = InnoDB
118
SQL;
119
120
        $stmts[] = <<<'SQL'
121
CREATE UNIQUE INDEX `user_email_UNIQUE` ON `user` (`user_email` ASC)
122
SQL;
123
124
        /*** Cities Table *************************************************/
125
126
        $stmts[] = <<<'SQL'
127
CREATE TABLE IF NOT EXISTS `city` (
128
  `city_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
129
  `city_name` VARCHAR(255) NOT NULL,
130
  `city_created_at` DATETIME NOT NULL,
131
  `city_created_by` INT UNSIGNED NULL,
132
  PRIMARY KEY (`city_id`),
133
  CONSTRAINT `city_created_by`
134
    FOREIGN KEY (`city_created_by`)
135
    REFERENCES `user` (`user_id`)
136
    ON DELETE SET NULL
137
    ON UPDATE CASCADE)
138
ENGINE = InnoDB
139
SQL;
140
141
        $stmts[] = <<<'SQL'
142
CREATE INDEX `city_created_by_idx` ON `city` (`city_created_by` ASC)
143
SQL;
144
145
        $stmts[] = <<<'SQL'
146
CREATE UNIQUE INDEX `city_name_UNIQUE` ON `city` (`city_name` ASC)
147
SQL;
148
149
        /*** Districts Table **********************************************/
150
151
        $stmts[] = <<<'SQL'
152
CREATE TABLE IF NOT EXISTS `district` (
153
  `district_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
154
  `district_name` VARCHAR(255) NOT NULL,
155
  `district_city_id` INT UNSIGNED NOT NULL,
156
  `district_created_at` DATETIME NOT NULL,
157
  `district_created_by` INT UNSIGNED NULL,
158
  PRIMARY KEY (`district_id`),
159
  CONSTRAINT `district_city_id`
160
    FOREIGN KEY (`district_city_id`)
161
    REFERENCES `city` (`city_id`)
162
    ON DELETE NO ACTION
163
    ON UPDATE NO ACTION,
164
  CONSTRAINT `district_created_by`
165
    FOREIGN KEY (`district_created_by`)
166
    REFERENCES `user` (`user_id`)
167
    ON DELETE SET NULL
168
    ON UPDATE CASCADE)
169
ENGINE = InnoDB
170
SQL;
171
172
        $stmts[] = <<<'SQL'
173
CREATE INDEX `district_city_id_idx` ON `district` (`district_city_id` ASC)
174
SQL;
175
176
        $stmts[] = <<<'SQL'
177
CREATE INDEX `district_created_by_idx` ON `district` (`district_created_by` ASC)
178
SQL;
179
180
        $stmts[] = <<<'SQL'
181
CREATE UNIQUE INDEX `district_name_UNIQUE` ON `district` (`district_name` ASC, `district_city_id` ASC)
182
SQL;
183
184
        /*** Donors Table *************************************************/
185
186
        $stmts[] = <<<'SQL'
187
CREATE TABLE IF NOT EXISTS `donor` (
188
  `donor_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
189
  `donor_name` VARCHAR(255) NOT NULL,
190
  `donor_gender` VARCHAR(45) NOT NULL,
191
  `donor_birthdate` DATE NOT NULL,
192
  `donor_blood_group` VARCHAR(45) NOT NULL,
193
  `donor_district_id` INT UNSIGNED NOT NULL,
194
  `donor_created_at` DATETIME NOT NULL,
195
  `donor_created_by` INT UNSIGNED NULL,
196
  `donor_status` VARCHAR(45) NOT NULL,
197
  `donor_meta` JSON NULL,
198
  PRIMARY KEY (`donor_id`),
199
  CONSTRAINT `donor_district_id`
200
    FOREIGN KEY (`donor_district_id`)
201
    REFERENCES `district` (`district_id`)
202
    ON DELETE NO ACTION
203
    ON UPDATE NO ACTION,
204
  CONSTRAINT `donor_created_by`
205
    FOREIGN KEY (`donor_created_by`)
206
    REFERENCES `user` (`user_id`)
207
    ON DELETE SET NULL
208
    ON UPDATE CASCADE)
209
ENGINE = InnoDB
210
SQL;
211
212
        $stmts[] = <<<'SQL'
213
CREATE INDEX `donor_district_id_idx` ON `donor` (`donor_district_id` ASC)
214
SQL;
215
216
        $stmts[] = <<<'SQL'
217
CREATE INDEX `donor_created_by_idx` ON `donor` (`donor_created_by` ASC)
218
SQL;
219
220
        /*** Variables Table **********************************************/
221
222
        $stmts[] = <<<'SQL'
223
CREATE TABLE IF NOT EXISTS `variable` (
224
  `variable_name` VARCHAR(45) NOT NULL,
225
  `variable_value` LONGTEXT NULL,
226
  PRIMARY KEY (`variable_name`))
227
ENGINE = InnoDB
228
SQL;
229
230
        foreach ($stmts as $stmt) {
231
            $connection->exec($stmt);
232
        }
233
    }
234
235
    /**
236
     * @return void
237
     * @since 1.3
238
     */
239
    protected function addTheDefaultOptions()
240
    {
241
        /* Reading Options */
242
        Options::addOption('entities_per_page', 10);
243
        Options::addOption('site_publication', 'on');
244
245
        /* Users Options */
246
        Options::addOption('self_registration', 'on');
247
        Options::addOption('new_user_status', 'pending');
248
        Options::addOption('new_user_role', 'contributor');
249
250
        /* Donors Options */
251
        Options::addOption('default_donor_phone_visibility', 'staff');
252
        Options::addOption('default_donor_email_visibility', 'members');
253
254
        /* General Options */
255
        Options::addOption('site_url', EBB\getHomeURL());
0 ignored issues
show
Bug introduced by
The function getHomeURL was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

255
        Options::addOption('site_url', /** @scrutinizer ignore-call */ EBB\getHomeURL());
Loading history...
256
        Options::addOption('site_theme', EBB_DEFAULT_THEME, true);
257
        Options::addOption('site_name', filter_input(INPUT_POST, 'site_name'), true);
258
        Options::addOption('site_email', filter_input(INPUT_POST, 'site_email'), true);
259
    }
260
261
    /**
262
     * @return void
263
     * @since 1.3
264
     */
265
    protected function createTheAdministrator()
266
    {
267
        $user = new User();
268
269
        // Set the user name.
270
        $user->set('name', filter_input(INPUT_POST, 'user_name'));
271
272
        // Set the user name.
273
        $user->set('email', filter_input(INPUT_POST, 'user_email'));
274
275
        $userPass1 = filter_input(INPUT_POST, 'user_pass_1', FILTER_UNSAFE_RAW);
276
        $userPass2 = filter_input(INPUT_POST, 'user_pass_2', FILTER_UNSAFE_RAW);
277
278
        if (empty($userPass1)) {
279
            throw new InvalidArgumentException(__('Please enter your password.'));
280
        }
281
282
        if (empty($userPass2)) {
283
            throw new InvalidArgumentException(__('Please confirm your password.'));
284
        }
285
286
        if ($userPass1 !== $userPass2) {
287
            throw new InvalidArgumentException(__('Please enter the same password.'));
288
        }
289
290
        // Set the user password.
291
        $user->set('pass', password_hash($userPass1, PASSWORD_BCRYPT), false);
292
293
        // Set the user role.
294
        $user->set('role', 'administrator');
295
        $user->set('created_at', new DateTime('now', new DateTimeZone('UTC')));
296
        $user->set('status', 'activated');
297
298
        $this->getEntityManager()->persist($user);
299
        $this->getEntityManager()->flush();
300
    }
301
302
    /**
303
     * @return void
304
     * @since 1.0
305
     */
306
    protected function doStep2Action()
307
    {
308
        try {
309
            $connection = $this->getContainer()->get('db_connection');
310
311
            if (EBB\getInstallationStatus($connection) === EBB\DATABASE_TABLE_NOT_EXIST) {
0 ignored issues
show
Bug introduced by
The function getInstallationStatus was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

311
            if (/** @scrutinizer ignore-call */ EBB\getInstallationStatus($connection) === EBB\DATABASE_TABLE_NOT_EXIST) {
Loading history...
312
                $this->createTheSchemasTables();
313
            }
314
315
            if (EBB\getInstallationStatus($connection, true) === EBB\DATABASE_INSTALLED) {
316
                Options::addOption('installing', true);
317
                $this->addTheDefaultOptions();
318
                $this->createTheAdministrator();
319
                Options::deleteOption('installing');
320
                EBB\redirect(EBB\getLoginURL());
0 ignored issues
show
Bug introduced by
The function redirect was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

320
                /** @scrutinizer ignore-call */ 
321
                EBB\redirect(EBB\getLoginURL());
Loading history...
Bug introduced by
The function getLoginURL was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

320
                EBB\redirect(/** @scrutinizer ignore-call */ EBB\getLoginURL());
Loading history...
321
            }
322
        } catch (InvalidArgumentException $ex) {
323
            Notices::addNotice('installing_failed', $ex->getMessage());
324
        } catch (Exception $ex) {
325
            Notices::addNotice('installing_failed', __('An unexpected error occurred while installing eBloodBank.'));
326
        }
327
    }
328
}
329