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

RecordCompleter   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Test Coverage

Coverage 92.11%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 34
dl 0
loc 69
rs 10
c 1
b 0
f 0
ccs 35
cts 38
cp 0.9211

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __invoke() 0 7 1
A redactSensitiveData() 0 14 4
A __construct() 0 2 1
A getEnvData() 0 28 4
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