Passed
Push — dev ( 896d5d...6a73c6 )
by Janko
07:03
created

ErrorHandler   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 12.31%

Importance

Changes 0
Metric Value
eloc 54
dl 0
loc 116
c 0
b 0
f 0
ccs 8
cts 65
cp 0.1231
rs 10
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A transactionHandler() 0 13 2
A outputHandler() 0 27 5
A registerHandlers() 0 9 1
A register() 0 6 2
A isAdminUser() 0 18 3
A logfileHandler() 0 11 1
A setErrorReporting() 0 9 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Config;
6
7
use Doctrine\DBAL\Connection;
8
use Stu\Component\Logging\GameRequest\GameRequestSaverInterface;
9
use Stu\Lib\Session\SessionInterface;
10
use Stu\Module\Config\StuConfigInterface;
11
use Stu\Module\Control\GameControllerInterface;
0 ignored issues
show
Bug introduced by
The type Stu\Module\Control\GameControllerInterface 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...
12
use Stu\Module\Logging\LogTypeEnum;
13
use Stu\Module\Logging\StuLogger;
14
use Throwable;
15
use Whoops\Handler\PlainTextHandler;
16
use Whoops\Handler\PrettyPageHandler;
17
use Whoops\Run;
18
use Whoops\Util\Misc;
19
20
/**
21
 * Registers the main error handler
22
 */
23
final class ErrorHandler
24
{
25 2
    public function __construct(private Connection $database, private GameRequestSaverInterface $gameRequestSaver, private GameControllerInterface $game, private StuConfigInterface $stuConfig, private SessionInterface $session) {}
26
27 1
    public function register(bool $registerErrorHandlers): void
28
    {
29 1
        $this->setErrorReporting();
30
31 1
        if ($registerErrorHandlers) {
32
            $this->registerHandlers();
33
        }
34
    }
35
36
    private function registerHandlers(): void
37
    {
38
        $whoops = new Run();
39
40
        $whoops->appendHandler($this->outputHandler());
41
        $whoops->prependHandler($this->transactionHandler());
42
        $whoops->prependHandler($this->logfileHandler());
43
44
        $whoops->register();
45
    }
46
47
    private function outputHandler(): mixed
48
    {
49
50
        if (
51
            $this->stuConfig->getDebugSettings()->isDebugMode()
52
            || $this->isAdminUser()
53
        ) {
54
            if (Misc::isCommandLine()) {
55
                $handler = new PlainTextHandler();
56
            } else {
57
                $handler = new PrettyPageHandler();
58
                $handler->setPageTitle('Error - Star Trek Universe');
59
            }
60
        } elseif (Misc::isCommandLine()) {
61
            $handler = new PlainTextHandler();
62
        } else {
63
            $handler = function (): void {
64
65
                echo str_replace(
66
                    '$REQUESTID',
67
                    $this->game->getGameRequestId(),
68
                    (string) file_get_contents(__DIR__ . '/../html/error.html')
69
                );
70
            };
71
        }
72
73
        return $handler;
74
    }
75
76
    private function transactionHandler(): callable
77
    {
78
        return function (): void {
79
80
            // end transaction if still active
81
            if ($this->database->isTransactionActive()) {
82
                $this->database->rollBack();
83
            }
84
85
            // save the game request
86
            $this->gameRequestSaver->save(
87
                $this->game->getGameRequest(),
88
                true
89
            );
90
        };
91
    }
92
93
    private function logfileHandler(): callable
94
    {
95
        $logger = StuLogger::getLogger(LogTypeEnum::DEFAULT);
96
97
        return function (Throwable $e) use ($logger): void {
98
            $logger->error(
99
                $e->getMessage(),
100
                [
101
                    'file' => $e->getFile(),
102
                    'line' => $e->getLine(),
103
                    'trace' => $e->getTrace()
104
                ]
105
            );
106
        };
107
    }
108
109 1
    private function setErrorReporting(): void
110
    {
111
        if (
112 1
            $this->stuConfig->getDebugSettings()->isDebugMode()
113 1
            || $this->isAdminUser()
114
        ) {
115 1
            error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
116
        } else {
117
            error_reporting(E_ERROR | E_WARNING | E_PARSE);
118
        }
119
    }
120
121
    private function isAdminUser(): bool
122
    {
123
        $isAdminUser = false;
124
125
        // load the session handler only if a session has been started
126
        if (session_id() !== '') {
127
128
            $user = $this->session->getUser();
129
130
            $isAdminUser = $user !== null
131
                && in_array(
132
                    $user->getId(),
133
                    $this->stuConfig->getGameSettings()->getAdminIds(),
134
                    true
135
                );
136
        }
137
138
        return $isAdminUser;
139
    }
140
}
141