Flare::anonymizeIp()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Facade\FlareClient;
4
5
use Exception;
6
use Facade\FlareClient\Concerns\HasContext;
7
use Facade\FlareClient\Context\ContextContextDetector;
8
use Facade\FlareClient\Context\ContextDetectorInterface;
9
use Facade\FlareClient\Enums\MessageLevels;
10
use Facade\FlareClient\Glows\Glow;
11
use Facade\FlareClient\Glows\Recorder;
12
use Facade\FlareClient\Http\Client;
13
use Facade\FlareClient\Middleware\AddGlows;
14
use Facade\FlareClient\Middleware\AnonymizeIp;
15
use Illuminate\Contracts\Container\Container;
16
use Illuminate\Pipeline\Pipeline;
17
use Throwable;
18
19
class Flare
20
{
21
    use HasContext;
22
23
    /** @var \Facade\FlareClient\Http\Client */
24
    private $client;
25
26
    /** @var \Facade\FlareClient\Api */
27
    private $api;
28
29
    /** @var array */
30
    private $middleware = [];
31
32
    /** @var \Facade\FlareClient\Glows\Recorder */
33
    private $recorder;
34
35
    /** @var string */
36
    private $applicationPath;
37
38
    /** @var \Illuminate\Contracts\Container\Container|null */
39
    private $container;
40
41
    /** @var ContextDetectorInterface */
42
    private $contextDetector;
43
44
    /** @var callable|null */
45
    private $previousExceptionHandler;
46
47
    /** @var callable|null */
48
    private $previousErrorHandler;
49
50
    public static function register(string $apiKey, string $apiSecret = null, ContextDetectorInterface $contextDetector = null, Container $container = null)
51
    {
52
        $client = new Client($apiKey, $apiSecret);
53
54
        return new static($client, $contextDetector, $container);
55
    }
56
57
    public function __construct(Client $client, ContextDetectorInterface $contextDetector = null, Container $container = null, array $middleware = [])
58
    {
59
        $this->client = $client;
60
        $this->recorder = new Recorder();
61
        $this->contextDetector = $contextDetector ?? new ContextContextDetector();
62
        $this->container = $container;
63
        $this->middleware = $middleware;
64
        $this->api = new Api($this->client);
65
66
        $this->registerDefaultMiddleware();
67
    }
68
69
    public function getMiddleware(): array
70
    {
71
        return $this->middleware;
72
    }
73
74
    public function registerFlareHandlers()
75
    {
76
        $this->registerExceptionHandler();
77
        $this->registerErrorHandler();
78
79
        return $this;
80
    }
81
82
    public function registerExceptionHandler()
83
    {
84
        $this->previousExceptionHandler = set_exception_handler([$this, 'handleException']);
85
86
        return $this;
87
    }
88
89
    public function registerErrorHandler()
90
    {
91
        $this->previousErrorHandler = set_error_handler([$this, 'handleError']);
92
93
        return $this;
94
    }
95
96
    private function registerDefaultMiddleware()
97
    {
98
        return $this->registerMiddleware(new AddGlows($this->recorder));
99
    }
100
101
    public function registerMiddleware($callable)
102
    {
103
        $this->middleware[] = $callable;
104
105
        return $this;
106
    }
107
108
    public function getMiddlewares(): array
109
    {
110
        return $this->middleware;
111
    }
112
113
    public function glow(
114
        string $name,
115
        string $messageLevel = MessageLevels::INFO,
116
        array $metaData = []
117
    ) {
118
        $this->recorder->record(new Glow($name, $messageLevel, $metaData));
119
    }
120
121
    public function handleException(Throwable $throwable)
122
    {
123
        $this->report($throwable);
124
125
        if ($this->previousExceptionHandler) {
126
            call_user_func($this->previousExceptionHandler, $throwable);
127
        }
128
    }
129
130
    public function handleError($code, $message, $file = '', $line = 0)
131
    {
132
        $exception = new \ErrorException($message, 0, $code, $file, $line);
133
134
        $this->report($exception);
135
136
        if ($this->previousErrorHandler) {
137
            return call_user_func(
138
                $this->previousErrorHandler,
139
                $message,
140
                $code,
141
                $file,
142
                $line
143
            );
144
        }
145
    }
146
147
    public function applicationPath(string $applicationPath)
148
    {
149
        $this->applicationPath = $applicationPath;
150
151
        return $this;
152
    }
153
154
    public function report(Throwable $throwable, callable $callback = null)
155
    {
156
        $report = $this->createReport($throwable);
157
158
        if (! is_null($callback)) {
159
            call_user_func($callback, $report);
160
        }
161
162
        $this->sendReportToApi($report);
163
    }
164
165
    public function reportMessage(string $message, string $logLevel, callable $callback = null)
166
    {
167
        $report = $this->createReportFromMessage($message, $logLevel);
168
169
        if (! is_null($callback)) {
170
            call_user_func($callback, $report);
171
        }
172
173
        $this->sendReportToApi($report);
174
    }
175
176
    public function sendTestReport(Throwable $throwable)
177
    {
178
        $this->api->sendTestReport($this->createReport($throwable));
179
    }
180
181
    private function sendReportToApi(Report $report)
182
    {
183
        try {
184
            $this->api->report($report);
185
        } catch (Exception $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
186
        }
187
    }
188
189
    public function reset()
190
    {
191
        $this->api->sendQueuedReports();
192
193
        $this->userProvidedContext = [];
194
        $this->recorder->reset();
195
    }
196
197
    private function applyAdditionalParameters(Report $report)
198
    {
199
        $report
200
            ->stage($this->stage)
201
            ->messageLevel($this->messageLevel)
202
            ->setApplicationPath($this->applicationPath)
203
            ->userProvidedContext($this->userProvidedContext);
204
    }
205
206
    public function anonymizeIp()
207
    {
208
        $this->registerMiddleware(new AnonymizeIp);
209
210
        return $this;
211
    }
212
213
    public function createReport(Throwable $throwable): Report
214
    {
215
        $report = Report::createForThrowable(
216
            $throwable,
217
            $this->contextDetector->detectCurrentContext(),
218
            $this->applicationPath
219
        );
220
221
        return $this->applyMiddlewareToReport($report);
222
    }
223
224
    public function createReportFromMessage(string $message, string $logLevel): Report
225
    {
226
        $report = Report::createForMessage(
227
            $message,
228
            $logLevel,
229
            $this->contextDetector->detectCurrentContext(),
230
            $this->applicationPath
231
        );
232
233
        $report->groupByException();
234
235
        return $this->applyMiddlewareToReport($report);
236
    }
237
238
    protected function applyMiddlewareToReport(Report $report): Report
239
    {
240
        $this->applyAdditionalParameters($report);
241
242
        $report = (new Pipeline($this->container))
243
            ->send($report)
244
            ->through($this->middleware)
245
            ->then(function ($report) {
246
                return $report;
247
            });
248
249
        return $report;
250
    }
251
}
252