Failed Conditions
Push — master ( 5f5e96...daf37e )
by Adrien
03:02
created

RecordCompleter::getEnvData()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 28
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4.054

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 20
dl 0
loc 28
rs 9.6
c 1
b 0
f 0
ccs 17
cts 20
cp 0.85
cc 4
nc 3
nop 0
crap 4.054
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ecodev\Felix\Log;
6
7
use Ecodev\Felix\Model\CurrentUser;
8
use Monolog\LogRecord;
9
use Monolog\Processor\ProcessorInterface;
10
11
class RecordCompleter implements ProcessorInterface
12
{
13 5
    public function __construct(private readonly string $baseUrl)
14
    {
15 5
    }
16
17
    /**
18
     * Complete a log record with extra data, including any global stuff relevant to the app.
19
     */
20 4
    public function __invoke(LogRecord $record): LogRecord
21
    {
22 4
        $extra = array_merge($record->extra, $this->getEnvData());
23
24 4
        return $record->with(
25 4
            context: $this->redactSensitiveData($record->context),
26 4
            extra: $this->redactSensitiveData($extra),
27 4
        );
28
    }
29
30
    /**
31
     * Retrieve dynamic information from environment to be logged.
32
     */
33 4
    private function getEnvData(): array
34
    {
35 4
        $user = CurrentUser::get();
36
37 4
        if (PHP_SAPI === 'cli') {
38
            global $argv;
39 4
            $ip = !empty(getenv('REMOTE_ADDR')) ? getenv('REMOTE_ADDR') : 'script';
40 4
            $url = implode(' ', $argv);
41 4
            $referer = '';
42
        } else {
43
            $ip = $_SERVER['REMOTE_ADDR'] ?? '';
44
            $url = $this->baseUrl . $_SERVER['REQUEST_URI'];
45
            $referer = $_SERVER['HTTP_REFERER'] ?? '';
46
        }
47
48 4
        $request = $_REQUEST;
49 4
        $request = $this->redactSensitiveData($request);
50
51 4
        $envData = [
52 4
            'creator_id' => $user?->getId(),
53 4
            'login' => $user?->getLogin() ?: '<anonymous>',
54 4
            'url' => $url,
55 4
            'referer' => $referer,
56 4
            'request' => json_encode($request, JSON_PRETTY_PRINT),
57 4
            'ip' => $ip,
58 4
        ];
59
60 4
        return $envData;
61
    }
62
63
    /**
64
     * Redact sensitive values from the entire data structure.
65
     */
66 4
    private function redactSensitiveData(array $request): array
67
    {
68 4
        foreach ($request as $key => &$value) {
69 4
            if (in_array($key, [
70 4
                'password',
71 4
                'passwordConfirmation',
72 4
            ], true)) {
73 1
                $value = '***REDACTED***';
74 4
            } elseif (is_array($value)) {
75 2
                $value = $this->redactSensitiveData($value);
76
            }
77
        }
78
79 4
        return $request;
80
    }
81
}
82