Passed
Push — 2.x ( fea0f7...4a4959 )
by Terry
01:54
created

BaseController::saveCofigCheckDataDriverFile()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 8
nop 1
dl 0
loc 29
rs 9.7
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Shieldon\Firewall\Panel;
14
15
use Psr\Http\Message\ResponseInterface;
16
use Shieldon\Firewall\Firewall;
17
use Shieldon\Firewall\FirewallTrait;
18
use Shieldon\Firewall\Panel\DemoTrait;
19
use Shieldon\Firewall\Utils\Container;
20
use Shieldon\Firewall\Log\ActionLogParser;
21
use function Shieldon\Firewall\__;
22
use function Shieldon\Firewall\get_request;
23
use function Shieldon\Firewall\get_response;
24
use function Shieldon\Firewall\get_session;
25
26
use PDO;
27
use PDOException;
28
use Redis;
29
use RedisException;
30
use RuntimeException;
31
use function array_push;
32
use function class_exists;
33
use function define;
34
use function defined;
35
use function extract;
36
use function file_exists;
37
use function file_put_contents;
38
use function is_array;
39
use function is_numeric;
40
use function is_string;
41
use function is_writable;
42
use function json_encode;
43
use function mkdir;
44
use function ob_end_clean;
45
use function ob_get_contents;
46
use function ob_start;
47
use function password_hash;
48
use function preg_split;
49
use function rtrim;
50
use function str_replace;
51
use function trim;
52
use function umask;
53
54
/**
55
 * User
56
 */
57
class BaseController
58
{
59
    use FirewallTrait;
60
    use DemoTrait;
61
62
    /**
63
     * LogPaeser instance.
64
     *
65
     * @var object
66
     */
67
    protected $parser;
68
69
    /**
70
     * Messages.
71
     *
72
     * @var array
73
     */
74
    protected $messages = [];
75
76
    /**
77
     * Check page availability.
78
     *
79
     * @var array
80
     */
81
    protected $pageAvailability = [
82
83
        // Need to implement Action Logger to make it true.
84
        'logs' => false,
85
    ];
86
87
    /**
88
     * see $this->csrf()
89
     *
90
     * @var array
91
     */
92
    protected $csrfField = [];
93
94
    /**
95
     * Language code.
96
     *
97
     * @var string
98
     */
99
    protected $locate = 'en';
100
101
    /**
102
     * Captcha modules.
103
     *
104
     * @var Interface
0 ignored issues
show
Bug introduced by
The type Shieldon\Firewall\Panel\Interface 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...
105
     */
106
    protected $captcha = [];
107
108
    /**
109
     * The base URL of the firewall panel.
110
     *
111
     * @var string
112
     */
113
    public $base = '';
114
115
    /**
116
     * Firewall panel base controller.                  
117
     */
118
    public function __construct() 
119
    {
120
        $firewall = Container::get('firewall');
121
122
        if (!($firewall instanceof Firewall)) {
123
            throw new RuntimeException(
124
                'The Firewall instance should be initialized first.'
125
            );
126
        }
127
128
        $this->mode          = 'managed';
129
        $this->kernel        = $firewall->getKernel();
130
        $this->configuration = $firewall->getConfiguration();
131
        $this->directory     = $firewall->getDirectory();
132
        $this->filename      = $firewall->getFilename();
133
        $this->base          = SHIELDON_PANEL_BASE;
134
135
        if (!empty($this->kernel->logger)) {
136
137
            // We need to know where the logs stored in.
138
            $logDirectory = $this->kernel->logger->getDirectory();
139
140
            // Load ActionLogParser for parsing log files.
141
            $this->parser = new ActionLogParser($logDirectory);
142
143
            $this->pageAvailability['logs'] = true;
144
        }
145
146
        $flashMessage = get_session()->get('flash_messages');
147
148
        // Flash message, use it when redirecting page.
149
        if (!empty($flashMessage)) {
150
            $this->messages = $flashMessage;
0 ignored issues
show
Documentation Bug introduced by
It seems like $flashMessage can also be of type string. However, the property $messages is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
151
            get_session()->remove('flash_messages');
152
        }
153
154
        $this->locate = 'en';
155
156
        $sessionLang = get_session()->get('shieldon_panel_lang');
157
158
        if (!empty($sessionLang)) {
159
            $this->locate = $sessionLang;
160
        }
161
    }
162
163
    /**
164
     * Load view file.
165
     *
166
     * @param string $page The page type. (filename)
167
     * @param array  $data The variables passed to that page.
168
     *
169
     * @return string
170
     */
171
    protected function loadView(string $page, array $data = []): string
172
    {
173
        if (!defined('SHIELDON_VIEW')) {
174
            define('SHIELDON_VIEW', true);
175
        }
176
177
        $viewFilePath =  __DIR__ . '/../../../templates/' . $page . '.php';
178
    
179
        if (!empty($data)) {
180
            extract($data);
181
        }
182
183
        $output = '';
184
    
185
        if (file_exists($viewFilePath)) {
186
            ob_start();
187
            require $viewFilePath;
188
            $output = ob_get_contents();
189
            ob_end_clean();
190
        }
191
192
        return $output;
193
    }
194
195
    /**
196
     * Render the web page with full layout.
197
     *
198
     * @param string $page The page type. (filename)
199
     * @param array  $data The variables passed to that page.
200
     *
201
     * @return ResponseInterface
202
     */
203
    protected function renderPage(string $page, array $data): ResponseInterface
204
    {
205
        $channelName = $this->kernel->driver->getChannel();
206
207
        if (empty($channelName)) {
208
            $channelName = 'default';
209
        }
210
211
        $body['channel_name'] = $channelName;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$body was never initialized. Although not strictly required by PHP, it is generally a good practice to add $body = array(); before regardless.
Loading history...
212
        $body['mode_name'] = $this->mode;
213
        $body['page_url'] = $this->url();
214
        $body['content'] = $this->loadView($page, $data);
215
        $body['title'] = $data['title'] ?? '';
216
217
        $body['title'] .= ' - ' . __('panel', 'title_site_wide', 'Shieldon Firewall');
218
        $body['title'] .= ' v' . SHIELDON_FIREWALL_VERSION;
219
220
        $page = $this->loadView('panel/template', $body);
221
222
        return $this->respond($page);
223
    }
224
225
    /**
226
     * Return the response instance.
227
     *
228
     * @param string $body The content body.
229
     *
230
     * @return ResponseInterface
231
     */
232
    protected function respond(string $body): ResponseInterface
233
    {
234
        $response = get_response();
235
        $stream = $response->getBody();
236
        $stream->write($body);
237
        $stream->rewind();
238
239
        return $response->withBody($stream);
240
    }
241
242
    /**
243
     * Include a view file.
244
     *
245
     * @param string $page The page type. (filename)
246
     * @param array  $data The variables passed to that page.
247
     *
248
     * @return void
249
     */
250
    protected function _include(string $page, array $data = []): void
251
    {
252
        if (!defined('SHIELDON_VIEW')) {
253
            define('SHIELDON_VIEW', true);
254
        }
255
256
        foreach ($data as $k => $v) {
257
            ${$k} = $v;
258
        }
259
260
        require __DIR__ . '/../../../templates/' . $page . '.php';
261
    }
262
263
    /**
264
     * Response message to front.
265
     *
266
     * @param string $type The message status type. error|success
267
     * @param string $text The message body.
268
     *
269
     * @return void
270
     */
271
    protected function pushMessage(string $type, string $text): void
272
    {
273
        $class = $type;
274
275
        if ($type == 'error') {
276
            $class = 'danger';
277
        }
278
279
        array_push($this->messages, [
280
            'type' => $type,
281
            'text' => $text,
282
            'class' => $class,
283
        ]);
284
    }
285
286
    /**
287
     * Return the relative URL.
288
     *
289
     * @param string $path The page's path.
290
     * @param string $tab  Tab.
291
     *
292
     * @return string
293
     */
294
    protected function url(string $path = '', string $tab = ''): string
295
    {
296
        $query = !empty($tab) ? '?tab=' . $tab : '';
297
298
        return '/' . trim($this->base, '/') . '/' . $path . '/' . $query;
299
    }
300
301
    /**
302
     * Output HTML input element with CSRF token.
303
     *
304
     * @return void
305
     */
306
    public function _csrf(): void
307
    {
308
        if (!empty($this->csrfField)) {
309
            foreach ($this->csrfField as $value) {
310
                echo '<input type="hidden" name="' . $value['name'] . '" value="' . $value['value'] . '" id="csrf-field">';
311
            }
312
        }
313
    }
314
315
    /**
316
     * Save the configuration settings to the JSON file.
317
     *
318
     * @return void
319
     */
320
    protected function saveConfig(): void
321
    {
322
        $postParams = get_request()->getParsedBody();
323
324
        $configFilePath = $this->directory . '/' . $this->filename;
325
326
        foreach ($this->csrfField as $csrfInfo) {
327
            if (!empty($csrfInfo['name'])) {
328
                unset_superglobal($csrfInfo['name'], 'post');
0 ignored issues
show
Bug introduced by
The function unset_superglobal 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

328
                /** @scrutinizer ignore-call */ 
329
                unset_superglobal($csrfInfo['name'], 'post');
Loading history...
329
            }
330
        }
331
332
        if (empty($postParams) || !is_array($postParams) || 'managed' !== $this->mode) {
333
            return;
334
        }
335
336
        $this->saveConfigPrepareSettings($postParams);
337
338
        //  Start checking the availibility of the data driver settings.
339
        $result = true;
340
        $result = $this->saveConfigCheckDataDriver($result);
341
        $result = $this->saveConfigCheckActionLogger($result);
342
        $result = $this->saveConfigCheckIptables($result);
343
344
        // Only update settings while data driver is correctly connected.
345
        if ($result) {
346
            file_put_contents($configFilePath, json_encode($this->configuration));
347
348
            $this->pushMessage('success',
349
                __(
350
                    'panel',
351
                    'success_settings_saved',
352
                    'Settings saved.'
353
                )
354
            );
355
        }
356
    }
357
358
    /**
359
     * Echo the setting string to the template.
360
     *
361
     * @param string $field   Field.
362
     * @param mixed  $defailt Default value.
363
     *
364
     * @return void
365
     */
366
    protected function _(string $field, $default = ''): void
367
    {
368
        if (is_string($this->getConfig($field)) || is_numeric($this->getConfig($field))) {
369
370
            if ('demo' === $this->mode) {
371
372
                // Hide sensitive data because of security concerns.
373
                $hiddenForDemo = [
374
                    'drivers.redis.auth',
375
                    'drivers.file.directory_path',
376
                    'drivers.sqlite.directory_path',
377
                    'drivers.mysql.dbname',
378
                    'drivers.mysql.user',
379
                    'drivers.mysql.pass',
380
                    'captcha_modules.recaptcha.config.site_key',
381
                    'captcha_modules.recaptcha.config.secret_key',
382
                    'loggers.action.config.directory_path',
383
                    'admin.user',
384
                    'admin.pass',
385
                    'admin.last_modified',
386
                    'messengers.telegram.config.api_key',
387
                    'messengers.telegram.config.channel',
388
                    'messengers.sendgrid.config.api_key',
389
                    'messengers.sendgrid.config.sender',
390
                    'messengers.sendgrid.config.recipients',
391
                    'messengers.line_notify.config.access_token',
392
                    'iptables.config.watching_folder',
393
                    'ip6tables.config.watching_folder',
394
                ];
395
396
                if (in_array($field, $hiddenForDemo)) {
397
                    echo __('panel', 'field_not_visible', 'Cannot view this field in demo mode.');
398
                } else {
399
                    echo (!empty($this->getConfig($field))) ? $this->getConfig($field) : $default;
400
                }
401
402
            } else {
403
                echo (!empty($this->getConfig($field))) ? $this->getConfig($field) : $default;
404
            }
405
        } elseif (is_array($this->getConfig($field))) {
406
407
            if ('demo' === $this->mode) {
408
                $hiddenForDemo = [
409
                    'messengers.sendgrid.config.recipients'
410
                ];
411
412
                if (in_array($field, $hiddenForDemo)) {
413
                    echo __('panel', 'field_not_visible', 'Cannot view this field in demo mode.');
414
                } else {
415
                    echo implode("\n", $this->getConfig($field));
0 ignored issues
show
Bug introduced by
It seems like $this->getConfig($field) can also be of type string; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

415
                    echo implode("\n", /** @scrutinizer ignore-type */ $this->getConfig($field));
Loading history...
416
                }
417
418
            } else {
419
                echo implode("\n", $this->getConfig($field));
420
            }
421
        }
422
    }
423
424
    /**
425
     * Use on HTML checkbox and radio elements.
426
     *
427
     * @param string $value
428
     * @param mixed  $valueChecked
429
     * @param bool   $isConfig
430
     *
431
     * @return void
432
     */
433
    protected function checked(string $value, $valueChecked, bool $isConfig = true): void
434
    {
435
        if ($isConfig) {
436
            if ($this->getConfig($value) === $valueChecked) {
437
                echo 'checked';
438
            } else {
439
                echo '';
440
            }
441
        } else {
442
            if ($value === $valueChecked) {
443
                echo 'checked';
444
            } else {
445
                echo '';
446
            }
447
        }
448
    }
449
450
    /**
451
     * Echo correspondence string on Messenger setting page.
452
     *
453
     * @param string $moduleName
454
     * @param string $echoType
455
     *
456
     * @return void
457
     */
458
    protected function _m(string $moduleName, string $echoType = 'css'): void
459
    {
460
        if ('css' === $echoType) {
461
            echo $this->getConfig('messengers.' . $moduleName . '.confirm_test') ? 'success' : '';
462
        }
463
464
        if ('icon' === $echoType) {
465
            echo $this->getConfig('messengers.' . $moduleName . '.confirm_test') ? '<i class="fas fa-check"></i>' : '<i class="fas fa-exclamation"></i>';
466
        }
467
    }
468
469
    /**
470
     * Use on HTML select elemets.
471
     *
472
     * @param string $value
473
     * @param mixed  $valueChecked
474
     *
475
     * @return void
476
     */
477
    protected function selected(string $value, $valueChecked): void
478
    {
479
        if ($this->getConfig($value) === $valueChecked) {
480
            echo 'selected';
481
        } else {
482
            echo '';
483
        }
484
    }
485
486
    /**
487
     * Parse the POST fields and set them into configuration data structure.
488
     * Used for saveConfig method only.
489
     *
490
     * @param array $postParams
491
     *
492
     * @return void
493
     */
494
    private function saveConfigPrepareSettings(array $postParams): void
495
    {
496
        foreach ($postParams as $postKey => $postData) {
497
            if (is_string($postData)) {
498
                if ($postData === 'on') {
499
                    $this->setConfig(str_replace('__', '.', $postKey), true);
500
501
                } elseif ($postData === 'off') {
502
                    $this->setConfig(str_replace('__', '.', $postKey), false);
503
504
                } else {
505
                    if ($postKey === 'ip_variable_source') {
506
                        $this->setConfig('ip_variable_source.REMOTE_ADDR', false);
507
                        $this->setConfig('ip_variable_source.HTTP_CF_CONNECTING_IP', false);
508
                        $this->setConfig('ip_variable_source.HTTP_X_FORWARDED_FOR', false);
509
                        $this->setConfig('ip_variable_source.HTTP_X_FORWARDED_HOST', false);
510
                        $this->setConfig('ip_variable_source.' . $postData, true);
511
512
                    } elseif ($postKey === 'dialog_ui__shadow_opacity') {
513
                        $this->setConfig('dialog_ui.shadow_opacity', (string) $postData);
514
515
                    } elseif ($postKey === 'admin__pass') {
516
                        if (strlen($postParams['admin__pass']) < 58) {
517
                            $this->setConfig('admin.pass', password_hash($postData, PASSWORD_BCRYPT));
518
                        }
519
                    } else if ($postKey === 'messengers__sendgrid__config__recipients') {
520
                        $this->setConfig(
521
                            'messengers.sendgrid.config.recipients',
522
                            preg_split('/\r\n|[\r\n]/',
523
                            $postData)
524
                        );
525
                    } else {
526
                        if (is_numeric($postData)) {
527
                            $this->setConfig(str_replace('__', '.', $postKey), (int) $postData);
528
                        } else  {
529
                            $this->setConfig(str_replace('__', '.', $postKey), $postData);
530
                        }
531
                    }
532
                }
533
            }
534
        }
535
    }
536
537
    /**
538
     * Check the settings of Action Logger.
539
     *
540
     * @return bool
541
     */
542
    private function saveConfigCheckActionLogger(bool $result): bool
543
    {
544
        if (!$result) {
545
            return false;
546
        }
547
548
        // Check Action Logger settings.
549
        $enableActionLogger = $this->getConfig('loggers.action.enable');
550
        $actionLogDir = rtrim($this->getConfig('loggers.action.config.directory_path'), '\\/ ');
551
552
        $result = true;
553
554
        if ($enableActionLogger) {
555
            if (empty($actionLogDir)) {
556
                $actionLogDir = $this->directory . '/action_logs';
557
            }
558
559
            $this->setConfig('loggers.action.config.directory_path', $actionLogDir);
560
561
            if (!is_dir($actionLogDir)) {
562
                $originalUmask = umask(0);
563
                mkdir($actionLogDir, 0777, true);
564
                umask($originalUmask);
565
            }
566
567
            if (!is_writable($actionLogDir)) {
568
                $result = false;
569
                $this->pushMessage('error',
570
                    __(
571
                        'panel',
572
                        'error_logger_directory_not_writable',
573
                        'Action Logger requires the storage directory writable.'
574
                    )
575
                );
576
            }
577
        }
578
579
        return $result;
580
    }
581
582
    /**
583
     * Check the settings of Iptables.
584
     * 
585
     * @param bool $result The result passed from previous check.
586
     *
587
     * @return bool
588
     */
589
    private function saveConfigCheckIptables(bool $result): bool
590
    {
591
        if (!$result) {
592
            return false;
593
        }
594
595
        // System firewall.
596
        $enableIptables = $this->getConfig('iptables.enable');
597
        $iptablesWatchingFolder = rtrim($this->getConfig('iptables.config.watching_folder'), '\\/ ');
598
599
        $result = true;
600
601
        if ($enableIptables) {
602
            if (empty($iptablesWatchingFolder)) {
603
                $iptablesWatchingFolder = $this->directory . '/iptables';
604
            }
605
606
            $this->setConfig('iptables.config.watching_folder', $iptablesWatchingFolder);
607
608
            if (!is_dir($iptablesWatchingFolder)) {
609
                $originalUmask = umask(0);
610
                mkdir($iptablesWatchingFolder, 0777, true);
611
                umask($originalUmask);
612
613
                // Create default log files.
614
                if (is_writable($iptablesWatchingFolder)) {
615
                    fopen($iptablesWatchingFolder . '/iptables_queue.log', 'w+');
616
                    fopen($iptablesWatchingFolder . '/ipv4_status.log',    'w+');
617
                    fopen($iptablesWatchingFolder . '/ipv6_status.log',    'w+');
618
                    fopen($iptablesWatchingFolder . '/ipv4_command.log',   'w+');
619
                    fopen($iptablesWatchingFolder . '/ipv6_command.log',   'w+');
620
                }
621
            }
622
    
623
            if (!is_writable($iptablesWatchingFolder)) {
624
                $result = false;
625
                $this->pushMessage('error',
626
                    __(
627
                        'panel',
628
                        'error_ip6tables_directory_not_writable',
629
                        'iptables watching folder requires the storage directory writable.'
630
                    )
631
                );
632
            }
633
        }
634
635
        return $result;
636
    }
637
638
    /**
639
     * Check the settings of Data drivers.
640
     *
641
     * @param bool $result The result passed from previous check.
642
     *
643
     * @return bool
644
     */
645
    private function saveConfigCheckDataDriver(bool $result): bool
646
    {
647
        if (!$result) {
648
            return false;
649
        }
650
651
        switch ($this->configuration['driver_type']) {
652
            case 'mysql':
653
                $result = $this->saveCofigChecDataDriverkMySql($result);
0 ignored issues
show
Bug introduced by
The method saveCofigChecDataDriverkMySql() does not exist on Shieldon\Firewall\Panel\BaseController. Did you maybe mean saveCofigCheckDataDriverMySql()? ( Ignorable by Annotation )

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

653
                /** @scrutinizer ignore-call */ 
654
                $result = $this->saveCofigChecDataDriverkMySql($result);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
654
                break;
655
656
            case 'sqlite':
657
                $result = $this->saveCofigCheckDataDriverSqlLite($result);
658
                break;
659
660
            case 'redis':
661
                $result = $this->saveCofigCheckDataDriverRedis($result);
662
                break;
663
664
            case 'file':
665
            default:
666
                $result = $this->saveCofigCheckDataDriverFile($result);
667
            // endswitch
668
        }
669
670
        return $result;
671
    }
672
673
    /**
674
     * Check the settings of Data drivers.
675
     *
676
     * @param bool $result The result passed from previous check.
677
     *
678
     * @return bool
679
     */
680
    private function saveCofigCheckDataDriverMySql(bool $result): bool
0 ignored issues
show
Unused Code introduced by
The method saveCofigCheckDataDriverMySql() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
681
    {
682
        if (class_exists('PDO')) {
683
            $db = [
684
                'host'    => $this->getConfig('drivers.mysql.host'),
685
                'dbname'  => $this->getConfig('drivers.mysql.dbname'),
686
                'user'    => $this->getConfig('drivers.mysql.user'),
687
                'pass'    => $this->getConfig('drivers.mysql.pass'),
688
                'charset' => $this->getConfig('drivers.mysql.charset'),
689
            ];
690
691
            try {
692
                $pdo = new PDO(
0 ignored issues
show
Unused Code introduced by
The assignment to $pdo is dead and can be removed.
Loading history...
693
                    'mysql:host=' . $db['host'] . ';dbname=' . $db['dbname'] . ';charset=' . $db['charset'],
694
                    (string) $db['user'],
695
                    (string) $db['pass']
696
                );
697
            } catch(PDOException $e) {
698
                $result = false;
699
                $this->pushMessage('error', 
700
                    __(
701
                        'panel',
702
                        'error_mysql_connection',
703
                        'Cannot access to your MySQL database, please check your settings.'
704
                    )
705
                );
706
            }
707
        } else {
708
            $result = false;
709
            $this->pushMessage('error',
710
                __(
711
                    'panel',
712
                    'error_mysql_driver_not_supported',
713
                    'Your system doesn’t support MySQL driver.'
714
                )
715
            );
716
        }
717
718
        return $result;
719
    }
720
721
    /**
722
     * Check the settings of Data drivers.
723
     *
724
     * @param bool $result The result passed from previous check.
725
     *
726
     * @return bool
727
     */
728
    private function saveCofigCheckDataDriverSqlLite(bool $result): bool
729
    {
730
        $sqliteDir = rtrim($this->getConfig('drivers.sqlite.directory_path'), '\\/ ');
731
732
        if (empty($sqliteDir)) {
733
            $sqliteDir = $this->directory . '/data_driver_sqlite';
734
        }
735
736
        $sqliteFilePath = $sqliteDir . '/shieldon.sqlite3';
737
        $this->setConfig('drivers.sqlite.directory_path', $sqliteDir);
738
        
739
        if (!file_exists($sqliteFilePath)) {
740
            if (!is_dir($sqliteDir)) {
741
                $originalUmask = umask(0);
742
                mkdir($sqliteDir, 0777, true);
743
                umask($originalUmask);
744
            }
745
        }
746
747
        if (class_exists('PDO')) {
748
            try {
749
                $pdo = new PDO('sqlite:' . $sqliteFilePath);
0 ignored issues
show
Unused Code introduced by
The assignment to $pdo is dead and can be removed.
Loading history...
750
            } catch(PDOException $e) {
751
                $result = false;
752
                $this->pushMessage('error', $e->getMessage());
753
            }
754
        } else {
755
            $result = false;
756
            $this->pushMessage('error',
757
                __(
758
                    'panel',
759
                    'error_sqlite_driver_not_supported',
760
                    'Your system doesn’t support SQLite driver.'
761
                )
762
            );
763
        }
764
765
        if (!is_writable($sqliteFilePath)) {
766
            $result = false;
767
            $this->pushMessage('error',
768
                __(
769
                    'panel',
770
                    'error_sqlite_directory_not_writable',
771
                    'SQLite data driver requires the storage directory writable.'
772
                )
773
            );
774
        }
775
776
        return $result;
777
    }
778
779
    /**
780
     * Check the settings of Data drivers.
781
     *
782
     * @param bool $result The result passed from previous check.
783
     *
784
     * @return bool
785
     */
786
    private function saveCofigCheckDataDriverRedis(bool $result): bool
0 ignored issues
show
Unused Code introduced by
The parameter $result 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

786
    private function saveCofigCheckDataDriverRedis(/** @scrutinizer ignore-unused */ bool $result): bool

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...
787
    {
788
        if (class_exists('Redis')) {
789
            try {
790
                $redis = new Redis();
791
                $redis->connect(
792
                    (string) $this->getConfig('drivers.redis.host'), 
793
                    (int)    $this->getConfig('drivers.redis.port')
794
                );
795
            } catch(RedisException $e) {
796
                $result = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
797
                $this->pushMessage('error', $e->getMessage());
798
            }
799
        } else {
800
            $result = false;
801
            $this->pushMessage('error',
802
                __(
803
                    'panel',
804
                    'error_redis_driver_not_supported',
805
                    'Your system doesn’t support Redis driver.'
806
                )
807
            );
808
        }
809
810
        return $redis;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $redis does not seem to be defined for all execution paths leading up to this point.
Loading history...
811
    }
812
813
    /**
814
     * Check the settings of Data drivers.
815
     *
816
     * @param bool $result The result passed from previous check.
817
     *
818
     * @return bool
819
     */
820
    private function saveCofigCheckDataDriverFile(bool $result): bool
821
    {
822
        $fileDir = rtrim($this->getConfig('drivers.file.directory_path'), '\\/ ');
823
824
        if (empty($fileDir)) {
825
            $fileDir = $this->directory . '/data_driver_file';
826
            $this->setConfig('drivers.file.directory_path', $fileDir);
827
        }
828
829
        $this->setConfig('drivers.file.directory_path', $fileDir);
830
831
        if (!is_dir($fileDir)) {
832
            $originalUmask = umask(0);
833
            mkdir($fileDir, 0777, true);
834
            umask($originalUmask);
835
        }
836
837
        if (!is_writable($fileDir)) {
838
            $result = false;
839
            $this->pushMessage('error',
840
                __(
841
                    'panel',
842
                    'error_file_directory_not_writable',
843
                    'File data driver requires the storage directory writable.'
844
                )
845
            );
846
        }
847
848
        return $result;
849
    }
850
}
851
852