GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — integration (#2599)
by
unknown
04:54
created

Installer::__checkConfiguration()   F

Complexity

Conditions 17
Paths 3456

Size

Total Lines 126
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
cc 17
eloc 72
c 6
b 1
f 1
nc 3456
nop 0
dl 0
loc 126
rs 2

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
    require_once CORE . "/class.administration.php";
4
5
    class Installer extends Administration
6
    {
7
        /**
8
         * Override the default Symphony constructor to initialise the Log, Config
9
         * and Database objects for installation/update. This allows us to use the
10
         * normal accessors.
11
         */
12
        protected function __construct()
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
__construct uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
__construct uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
13
        {
14
            self::$Profiler = Profiler::instance();
15
            self::$Profiler->sample('Engine Initialisation');
16
17
            if (get_magic_quotes_gpc()) {
18
                General::cleanArray($_SERVER);
19
                General::cleanArray($_COOKIE);
20
                General::cleanArray($_GET);
21
                General::cleanArray($_POST);
22
            }
23
24
            // Include the default Config for installation.
25
            include(INSTALL . '/includes/config_default.php');
26
            static::initialiseConfiguration($settings);
0 ignored issues
show
Bug introduced by
The variable $settings does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
27
28
            // Initialize date/time
29
            define_safe('__SYM_DATE_FORMAT__', self::Configuration()->get('date_format', 'region'));
30
            define_safe('__SYM_TIME_FORMAT__', self::Configuration()->get('time_format', 'region'));
31
            define_safe('__SYM_DATETIME_FORMAT__',
32
                __SYM_DATE_FORMAT__ . self::Configuration()->get('datetime_separator', 'region') . __SYM_TIME_FORMAT__);
33
            DateTimeObj::setSettings(self::Configuration()->get('region'));
34
35
            // Initialize Language, Logs and Database
36
            static::initialiseLang();
37
            static::initialiseLog(INSTALL_LOGS . '/install');
38
            static::initialiseDatabase();
39
40
            // Initialize error handlers
41
            GenericExceptionHandler::initialise(Symphony::Log());
42
            GenericErrorHandler::initialise(Symphony::Log());
43
        }
44
45
        /**
46
         * Initialises the language by looking at the `lang` key,
47
         * passed via GET or POST
48
         */
49
        public static function initialiseLang()
50
        {
51
            $lang = !empty($_REQUEST['lang']) ? preg_replace('/[^a-zA-Z\-]/', null, $_REQUEST['lang']) : 'en';
52
            Lang::initialize();
53
            Lang::set($lang, false);
54
        }
55
56
        /**
57
         * Overrides the default `initialiseLog()` method and writes
58
         * logs to manifest/logs/install
59
         *
60
         * @param null $filename
61
         * @return boolean|void
62
         * @throws Exception
63
         */
64 View Code Duplication
        public static function initialiseLog($filename = null)
65
        {
66
            if (is_dir(INSTALL_LOGS) || General::realiseDirectory(INSTALL_LOGS,
67
                    self::Configuration()->get('write_mode', 'directory'))
68
            ) {
69
                return parent::initialiseLog($filename);
70
            }
71
72
            return;
73
        }
74
75
        /**
76
         * Overrides the default `initialiseDatabase()` method
77
         * This allows us to still use the normal accessor
78
         */
79
        public static function initialiseDatabase()
80
        {
81
            self::setDatabase();
82
        }
83
84
        /**
85
         * This function returns an instance of the Installer
86
         * class. It is the only way to create a new Installer, as
87
         * it implements the Singleton interface
88
         *
89
         * @return Installer
90
         */
91
        public static function instance()
92
        {
93
            if (!(self::$_instance instanceof Installer)) {
94
                self::$_instance = new Installer;
95
            }
96
97
            return self::$_instance;
98
        }
99
100
        public function run()
101
        {
102
            // Make sure a log file is available
103
            if (is_null(Symphony::Log())) {
104
                self::__render(new InstallerPage('missing-log'));
105
            }
106
107
            // Check essential server requirements
108
            $errors = self::__checkRequirements();
109 View Code Duplication
            if (!empty($errors)) {
110
                Symphony::Log()->error('Installer - Missing requirements.');
111
112
                foreach ($errors as $err) {
113
                    Symphony::Log()->error(
114
                        sprintf('Requirement - %s', $err['msg'])
115
                    );
116
                }
117
118
                self::__render(new InstallerPage('requirements', array(
119
                    'errors' => $errors
120
                )));
121
            }
122
123
            // If language is not set and there is language packs available, show language selection pages
124
            if (!isset($_POST['lang']) && count(Lang::getAvailableLanguages(false)) > 1) {
125
                self::__render(new InstallerPage('languages'));
126
            }
127
128
            // Check for configuration errors and, if there are no errors, install Symphony!
129
            if (isset($_POST['fields'])) {
130
                $errors = self::__checkConfiguration();
131 View Code Duplication
                if (!empty($errors)) {
132
                    Symphony::Log()->error('Installer - Wrong configuration.');
133
134
                    foreach ($errors as $err) {
135
                        Symphony::Log()->error(
136
                            sprintf('Configuration - %s', $err['msg'])
137
                        );
138
                    }
139
                } else {
140
                    $disabled_extensions = self::__install();
141
142
                    self::__render(new InstallerPage('success', array(
143
                        'disabled-extensions' => $disabled_extensions
144
                    )));
145
                }
146
            }
147
148
            // Display the Installation page
149
            self::__render(new InstallerPage('configuration', array(
150
                'errors' => $errors,
151
                'default-config' => Symphony::Configuration()->get()
152
            )));
153
        }
154
155
        protected static function __render(InstallerPage $page)
156
        {
157
            $output = $page->generate();
158
159
            header('Content-Type: text/html; charset=utf-8');
160
            echo $output;
161
            exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method __render() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
162
        }
163
164
        /**
165
         * This function checks the server can support a Symphony installation.
166
         * It checks that PHP is 5.2+, MySQL, Zlib, LibXML, XSLT modules are enabled
167
         * and a `install.sql` file exists.
168
         * If any of these requirements fail the installation will not proceed.
169
         *
170
         * @return array
171
         *  An associative array of errors, with `msg` and `details` keys
172
         */
173
        private static function __checkRequirements()
174
        {
175
            $errors = array();
176
177
            // Check for PHP 5.2+
178
            if (version_compare(phpversion(), '5.3', '<=')) {
179
                $errors[] = array(
180
                    'msg' => __('PHP Version is not correct'),
181
                    'details' => __('Symphony requires %1$s or greater to work, however version %2$s was detected.',
182
                        array(
183
                            '<code><abbr title="PHP: Hypertext Pre-processor">PHP</abbr> 5.3</code>',
184
                            '<code>' . phpversion() . '</code>'
185
                        ))
186
                );
187
            }
188
189
            // Make sure the install.sql file exists
190
            if (!file_exists(INSTALL . '/includes/install.sql') || !is_readable(INSTALL . '/includes/install.sql')) {
191
                $errors[] = array(
192
                    'msg' => __('Missing install.sql file'),
193
                    'details' => __('It appears that %s is either missing or not readable. This is required to populate the database and must be uploaded before installation can commence. Ensure that PHP has read permissions.',
194
                        array('<code>install.sql</code>'))
195
                );
196
            }
197
198
            // Is MySQL available?
199 View Code Duplication
            if (!function_exists('mysqli_connect')) {
200
                $errors[] = array(
201
                    'msg' => __('MySQLi extension not present'),
202
                    'details' => __('Symphony requires PHP to be configured with MySQLi to work.')
203
                );
204
            }
205
206
            // Is ZLib available?
207 View Code Duplication
            if (!extension_loaded('zlib')) {
208
                $errors[] = array(
209
                    'msg' => __('ZLib extension not present'),
210
                    'details' => __('Symphony uses the ZLib compression library for log rotation.')
211
                );
212
            }
213
214
            // Is libxml available?
215 View Code Duplication
            if (!extension_loaded('xml') && !extension_loaded('libxml')) {
216
                $errors[] = array(
217
                    'msg' => __('XML extension not present'),
218
                    'details' => __('Symphony needs the XML extension to pass data to the site frontend.')
219
                );
220
            }
221
222
            // Is libxslt available?
223
            if (!extension_loaded('xsl') && !extension_loaded('xslt') && !function_exists('domxml_xslt_stylesheet')) {
224
                $errors[] = array(
225
                    'msg' => __('XSLT extension not present'),
226
                    'details' => __('Symphony needs an XSLT processor such as %s or Sablotron to build pages.',
227
                        array('Lib<abbr title="eXtensible Stylesheet Language Transformation">XSLT</abbr>'))
228
                );
229
            }
230
231
            // Is json_encode available?
232 View Code Duplication
            if (!function_exists('json_decode')) {
233
                $errors[] = array(
234
                    'msg' => __('JSON functionality is not present'),
235
                    'details' => __('Symphony uses JSON functionality throughout the backend for translations and the interface.')
236
                );
237
            }
238
239
            // Cannot write to root folder.
240
            if (!is_writable(DOCROOT)) {
241
                $errors['no-write-permission-root'] = array(
242
                    'msg' => 'Root folder not writable: ' . DOCROOT,
243
                    'details' => __('Symphony does not have write permission to the root directory. Please modify permission settings on %s. This can be reverted once installation is complete.',
244
                        array('<code>' . DOCROOT . '</code>'))
245
                );
246
            }
247
248
            // Cannot write to workspace
249
            if (is_dir(DOCROOT . '/workspace') && !is_writable(DOCROOT . '/workspace')) {
250
                $errors['no-write-permission-workspace'] = array(
251
                    'msg' => 'Workspace folder not writable: ' . DOCROOT . '/workspace',
252
                    'details' => __('Symphony does not have write permission to the existing %1$s directory. Please modify permission settings on this directory and its contents to allow this, such as with a recursive %2$s command.',
253
                        array('<code>/workspace</code>', '<code>chmod -R</code>'))
254
                );
255
            }
256
257
            return $errors;
258
        }
259
260
        /**
261
         * This function checks the current Configuration (which is the values entered
262
         * by the user on the installation form) to ensure that `/symphony` and `/workspace`
263
         * folders exist and are writable and that the Database credentials are correct.
264
         * Once those initial checks pass, the rest of the form values are validated.
265
         *
266
         * @return array An associative array of errors if something went wrong, otherwise an empty array.
267
         */
268
        private static function __checkConfiguration()
0 ignored issues
show
Coding Style introduced by
__checkConfiguration uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
269
        {
270
            $errors = array();
271
            $fields = $_POST['fields'];
272
273
            // Testing the database connection
274
            try {
275
                Symphony::Database()->connect(
276
                    $fields['database']['host'],
277
                    $fields['database']['user'],
278
                    $fields['database']['password'],
279
                    $fields['database']['port'],
280
                    $fields['database']['db']
281
                );
282
            } catch (DatabaseException $e) {
283
                // Invalid credentials
284
                // @link http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
285
                if ($e->getDatabaseErrorCode() === 1044 || $e->getDatabaseErrorCode() === 1045) {
286
                    $errors['database-invalid-credentials'] = array(
287
                        'msg' => 'Database credentials were denied',
288
                        'details' => __('Symphony was unable to access the database with these credentials.')
289
                    );
290
                } // Connection related
291
                else {
292
                    $errors['no-database-connection'] = array(
293
                        'msg' => 'Could not establish database connection.',
294
                        'details' => __('Symphony was unable to establish a valid database connection. You may need to modify host or port settings.')
295
                    );
296
                }
297
            }
298
299
            try {
300
                // Check the database table prefix is legal. #1815
301
                if (!preg_match('/^[0-9a-zA-Z\$_]*$/', $fields['database']['tbl_prefix'])) {
302
                    $errors['database-table-prefix'] = array(
303
                        'msg' => 'Invalid database table prefix: ‘' . $fields['database']['tbl_prefix'] . '’',
304
                        'details' => __('The table prefix %s is invalid. The table prefix must only contain numbers, letters or underscore characters.',
305
                            array('<code>' . $fields['database']['tbl_prefix'] . '</code>'))
306
                    );
307
                } // Check the database credentials
308
                elseif (Symphony::Database()->isConnected()) {
309
                    // Incorrect MySQL version
310
                    $version = Symphony::Database()->fetchVar('version', 0, "SELECT VERSION() AS `version`;");
311
                    if (version_compare($version, '5.5', '<')) {
312
                        $errors['database-incorrect-version'] = array(
313
                            'msg' => 'MySQL Version is not correct. ' . $version . ' detected.',
314
                            'details' => __('Symphony requires %1$s or greater to work, however version %2$s was detected. This requirement must be met before installation can proceed.',
315
                                array('<code>MySQL 5.5</code>', '<code>' . $version . '</code>'))
316
                        );
317
                    } else {
318
                        // Existing table prefix
319
                        if (Symphony::Database()->tableExists($fields['database']['tbl_prefix'] . '%')) {
320
                            $errors['database-table-prefix'] = array(
321
                                'msg' => 'Database table prefix clash with ‘' . $fields['database']['db'] . '’',
322
                                'details' => __('The table prefix %s is already in use. Please choose a different prefix to use with Symphony.',
323
                                    array(
324
325
                                        '<code>' . $fields['database']['tbl_prefix'] . '</code>'
326
                                    ))
327
                            );
328
                        }
329
                    }
330
                }
331
            } catch (DatabaseException $e) {
332
                $errors['unknown-database'] = array(
333
                    'msg' => 'Database ‘' . $fields['database']['db'] . '’ not found.',
334
                    'details' => __('Symphony was unable to connect to the specified database.')
335
                );
336
            }
337
338
            // Website name not entered
339
            if (trim($fields['general']['sitename']) === '') {
340
                $errors['general-no-sitename'] = array(
341
                    'msg' => 'No sitename entered.',
342
                    'details' => __('You must enter a Site name. This will be shown at the top of your backend.')
343
                );
344
            }
345
346
            // Username Not Entered
347
            if (trim($fields['user']['username']) === '') {
348
                $errors['user-no-username'] = array(
349
                    'msg' => 'No username entered.',
350
                    'details' => __('You must enter a Username. This will be your Symphony login information.')
351
                );
352
            }
353
354
            // Password Not Entered
355
            if (trim($fields['user']['password']) === '') {
356
                $errors['user-no-password'] = array(
357
                    'msg' => 'No password entered.',
358
                    'details' => __('You must enter a Password. This will be your Symphony login information.')
359
                );
360
            } // Password mismatch
361
            elseif ($fields['user']['password'] !== $fields['user']['confirm-password']) {
362
                $errors['user-password-mismatch'] = array(
363
                    'msg' => 'Passwords did not match.',
364
                    'details' => __('The password and confirmation did not match. Please retype your password.')
365
                );
366
            }
367
368
            // No Name entered
369
            if (trim($fields['user']['firstname']) === '' || trim($fields['user']['lastname']) === '') {
370
                $errors['user-no-name'] = array(
371
                    'msg' => 'Did not enter First and Last names.',
372
                    'details' => __('You must enter your name.')
373
                );
374
            }
375
376
            // Invalid Email
377
            if (!preg_match('/^\w(?:\.?[\w%+-]+)*@\w(?:[\w-]*\.)+?[a-z]{2,}$/i', $fields['user']['email'])) {
378
                $errors['user-invalid-email'] = array(
379
                    'msg' => 'Invalid email address supplied.',
380
                    'details' => __('This is not a valid email address. You must provide an email address since you will need it if you forget your password.')
381
                );
382
            }
383
384
            // Admin path not entered
385
            if (trim($fields['symphony']['admin-path']) === '') {
386
                $errors['no-symphony-path'] = array(
387
                    'msg' => 'No Symphony path entered.',
388
                    'details' => __('You must enter a path for accessing Symphony, or leave the default. This will be used to access Symphony\'s backend.')
389
                );
390
            }
391
392
            return $errors;
393
        }
394
395
        private static function __install()
0 ignored issues
show
Coding Style introduced by
__install uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
__install uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
396
        {
397
            $fields = $_POST['fields'];
398
            $start = time();
399
400
            Symphony::Log()->info('INSTALLATION PROCESS STARTED (' . DateTimeObj::get('c') . ')');
401
402
            // MySQL: Establishing connection
403
            Symphony::Log()->info('MYSQL: Establishing Connection');
404
405
            try {
406
                Symphony::Database()->connect(
407
                    $fields['database']['host'],
408
                    $fields['database']['user'],
409
                    $fields['database']['password'],
410
                    $fields['database']['port'],
411
                    $fields['database']['db']
412
                );
413
            } catch (DatabaseException $e) {
414
                self::__abort(
415
                    'There was a problem while trying to establish a connection to the MySQL server. Please check your settings.',
416
                    $start);
417
            }
418
419
            // MySQL: Setting prefix & character encoding
420
            Symphony::Database()->setPrefix($fields['database']['tbl_prefix']);
421
422
            // MySQL: Importing schema
423
            Symphony::Log()->info('MYSQL: Importing Table Schema');
424
425
            try {
426
                Symphony::Database()->import(file_get_contents(INSTALL . '/includes/install.sql'));
427
            } catch (DatabaseException $e) {
428
                self::__abort(
429
                    'There was an error while trying to import data to the database. MySQL returned: ' . $e->getDatabaseErrorCode() . ': ' . $e->getDatabaseErrorMessage(),
430
                    $start);
431
            }
432
433
            // MySQL: Creating default author
434
            Symphony::Log()->info('MYSQL: Creating Default Author');
435
436
            try {
437
                Symphony::Database()->insert(array(
438
                    'id' => 1,
439
                    'username' => Symphony::Database()->cleanValue($fields['user']['username']),
440
                    'password' => Cryptography::hash(Symphony::Database()->cleanValue($fields['user']['password'])),
441
                    'first_name' => Symphony::Database()->cleanValue($fields['user']['firstname']),
442
                    'last_name' => Symphony::Database()->cleanValue($fields['user']['lastname']),
443
                    'email' => Symphony::Database()->cleanValue($fields['user']['email']),
444
                    'last_seen' => null,
445
                    'user_type' => 'developer',
446
                    'primary' => 'yes',
447
                    'default_area' => null,
448
                    'auth_token_active' => 'no'
449
                ), 'tbl_authors');
450
            } catch (DatabaseException $e) {
451
                self::__abort(
452
                    'There was an error while trying create the default author. MySQL returned: ' . $e->getDatabaseErrorCode() . ': ' . $e->getDatabaseErrorMessage(),
453
                    $start);
454
            }
455
456
            // Configuration: Populating array
457
            $conf = Symphony::Configuration()->get();
458
459
            foreach ($conf as $group => $settings) {
460
                foreach ($settings as $key => $value) {
461
                    if (isset($fields[$group]) && isset($fields[$group][$key])) {
462
                        $conf[$group][$key] = $fields[$group][$key];
463
                    }
464
                }
465
            }
466
467
            // Create manifest folder structure
468
            Symphony::Log()->info('WRITING: Creating ‘manifest’ folder (/manifest)');
469
            if (!General::realiseDirectory(MANIFEST, $conf['directory']['write_mode'])) {
470
                self::__abort(
471
                    'Could not create ‘manifest’ directory. Check permission on the root folder.',
472
                    $start);
473
            }
474
475
            Symphony::Log()->info('WRITING: Creating ‘logs’ folder (/manifest/logs)');
476
            if (!General::realiseDirectory(LOGS, $conf['directory']['write_mode'])) {
477
                self::__abort(
478
                    'Could not create ‘logs’ directory. Check permission on /manifest.',
479
                    $start);
480
            }
481
482
            Symphony::Log()->info('WRITING: Creating ‘cache’ folder (/manifest/cache)');
483
            if (!General::realiseDirectory(CACHE, $conf['directory']['write_mode'])) {
484
                self::__abort(
485
                    'Could not create ‘cache’ directory. Check permission on /manifest.',
486
                    $start);
487
            }
488
489
            Symphony::Log()->info('WRITING: Creating ‘tmp’ folder (/manifest/tmp)');
490
            if (!General::realiseDirectory(MANIFEST . '/tmp', $conf['directory']['write_mode'])) {
491
                self::__abort(
492
                    'Could not create ‘tmp’ directory. Check permission on /manifest.',
493
                    $start);
494
            }
495
496
            // Writing configuration file
497
            Symphony::Log()->info('WRITING: Configuration File');
498
499
            Symphony::Configuration()->setArray($conf);
500
501 View Code Duplication
            if (!Symphony::Configuration()->write(CONFIG, $conf['file']['write_mode'])) {
502
                self::__abort(
503
                    'Could not create config file ‘' . CONFIG . '’. Check permission on /manifest.',
504
                    $start);
505
            }
506
507
            // Writing htaccess file
508
            Symphony::Log()->info('CONFIGURING: Frontend', E_NOTICE);
0 ignored issues
show
Documentation introduced by
E_NOTICE is of type integer, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
509
510
            $rewrite_base = ltrim(preg_replace('/\/install$/i', null, dirname($_SERVER['PHP_SELF'])), '/');
511
            $htaccess = str_replace(
512
                '<!-- REWRITE_BASE -->', $rewrite_base,
513
                file_get_contents(INSTALL . '/includes/htaccess.txt')
514
            );
515
516
            if (!General::writeFile(DOCROOT . "/.htaccess", $htaccess, $conf['file']['write_mode'], 'a')) {
517
                self::__abort(
518
                    'Could not write ‘.htaccess’ file. Check permission on ' . DOCROOT,
519
                    $start);
520
            }
521
522
            // Writing /workspace folder
523
            if (!is_dir(DOCROOT . '/workspace')) {
524
                // Create workspace folder structure
525
                Symphony::Log()->info('WRITING: Creating ‘workspace’ folder (/workspace)');
526
                if (!General::realiseDirectory(WORKSPACE, $conf['directory']['write_mode'])) {
527
                    self::__abort(
528
                        'Could not create ‘workspace’ directory. Check permission on the root folder.',
529
                        $start);
530
                }
531
532
                Symphony::Log()->info('WRITING: Creating ‘data-sources’ folder (/workspace/data-sources)');
533
                if (!General::realiseDirectory(DATASOURCES, $conf['directory']['write_mode'])) {
534
                    self::__abort(
535
                        'Could not create ‘workspace/data-sources’ directory. Check permission on the root folder.',
536
                        $start);
537
                }
538
539
                Symphony::Log()->info('WRITING: Creating ‘events’ folder (/workspace/events)');
540
                if (!General::realiseDirectory(EVENTS, $conf['directory']['write_mode'])) {
541
                    self::__abort(
542
                        'Could not create ‘workspace/events’ directory. Check permission on the root folder.',
543
                        $start);
544
                }
545
546
                Symphony::Log()->info('WRITING: Creating ‘pages’ folder (/workspace/pages)');
547
                if (!General::realiseDirectory(PAGES, $conf['directory']['write_mode'])) {
548
                    self::__abort(
549
                        'Could not create ‘workspace/pages’ directory. Check permission on the root folder.',
550
                        $start);
551
                }
552
553
                Symphony::Log()->info('WRITING: Creating ‘utilities’ folder (/workspace/utilities)');
554
                if (!General::realiseDirectory(UTILITIES, $conf['directory']['write_mode'])) {
555
                    self::__abort(
556
                        'Could not create ‘workspace/utilities’ directory. Check permission on the root folder.',
557
                        $start);
558
                }
559
            } else {
560
                Symphony::Log()->info('An existing ‘workspace’ directory was found at this location. Symphony will use this workspace.');
561
562
                // MySQL: Importing workspace data
563
                Symphony::Log()->info('MYSQL: Importing Workspace Data...');
564
565
                if (is_file(WORKSPACE . '/install.sql')) {
566
                    try {
567
                        Symphony::Database()->import(file_get_contents(WORKSPACE . '/install.sql'));
568
                    } catch (DatabaseException $e) {
569
                        self::__abort(
570
                            'There was an error while trying to import data to the database. MySQL returned: ' . $e->getDatabaseErrorCode() . ': ' . $e->getDatabaseErrorMessage(),
571
                            $start);
572
                    }
573
                }
574
            }
575
576
            // Write extensions folder
577
            if (!is_dir(EXTENSIONS)) {
578
                // Create extensions folder
579
                Symphony::Log()->info('WRITING: Creating ‘extensions’ folder (/extensions)');
580
                if (!General::realiseDirectory(EXTENSIONS, $conf['directory']['write_mode'])) {
581
                    self::__abort(
582
                        'Could not create ‘extension’ directory. Check permission on the root folder.',
583
                        $start);
584
                }
585
            }
586
587
            // Install existing extensions
588
            Symphony::Log()->info('CONFIGURING: Installing existing extensions');
589
            $disabled_extensions = array();
590
            foreach (new DirectoryIterator(EXTENSIONS) as $e) {
591
                if ($e->isDot() || $e->isFile() || !is_file($e->getRealPath() . '/extension.driver.php')) {
592
                    continue;
593
                }
594
595
                $handle = $e->getBasename();
596
                try {
597
                    if (!ExtensionManager::enable($handle)) {
598
                        $disabled_extensions[] = $handle;
599
                        Symphony::Log()->warning('Could not enable the extension ‘' . $handle . '’.');
600
                    }
601
                } catch (Exception $ex) {
602
                    $disabled_extensions[] = $handle;
603
                    Symphony::Log()->warning('Could not enable the extension ‘' . $handle . '’. ' . $ex->getMessage());
604
                }
605
            }
606
607
            // Loading default language
608
            if (isset($_REQUEST['lang']) && $_REQUEST['lang'] !== 'en') {
609
                Symphony::Log()->info('CONFIGURING: Default language');
610
611
                $language = Lang::Languages();
612
                $language = $language[$_REQUEST['lang']];
613
614
                // Is the language extension enabled?
615
                if (in_array('lang_' . $language['handle'], ExtensionManager::listInstalledHandles())) {
616
                    Symphony::Configuration()->set('lang', $_REQUEST['lang'], 'symphony');
617 View Code Duplication
                    if (!Symphony::Configuration()->write(CONFIG, $conf['file']['write_mode'])) {
618
                        Symphony::Log()->warning('Could not write default language ‘' . $language['name'] . '’ to config file.');
619
                    }
620
                } else {
621
                    Symphony::Log()->warning('Could not enable the desired language ‘' . $language['name'] . '’.');
622
                }
623
            }
624
625
            // Installation completed. Woo-hoo!
626
            Symphony::Log()->info(sprintf('INSTALLATION COMPLETED: Execution Time - %d sec (%s)',
627
                max(1, time() - $start),
628
                date('d.m.y H:i:s')
629
            ));
630
631
            return $disabled_extensions;
632
        }
633
634
        /**
635
         * If something went wrong, the `__abort` function will write an entry to the Log
636
         * file and display the failure page to the user.
637
         *
638
         * @todo: Resume installation after an error has been fixed.
639
         * @param string $message
640
         * @param integer $start
641
         */
642
        protected static function __abort($message, $start)
643
        {
644
            Symphony::Log()->error($message);
645
            Symphony::Log()->error(sprintf('INSTALLATION ABORTED: Execution Time - %d sec (%s)',
646
                max(1, time() - $start),
647
                date('d.m.y H:i:s')
648
            ));
649
650
            self::__render(new InstallerPage('failure'));
651
        }
652
    }
653