Completed
Push — master ( 3ff92e...9fb27f )
by Adrien
08:52
created

DbWriter::completeEvent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0078

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 14
ccs 7
cts 8
cp 0.875
crap 2.0078
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Log;
6
7
use Application\Model\User;
8
use Application\Repository\LogRepository;
9
use Zend\Log\Writer\AbstractWriter;
10
11
class DbWriter extends AbstractWriter
12
{
13
    /**
14
     * @var LogRepository
15
     */
16
    private $logRepository;
17
18
    /**
19
     * @var string
20
     */
21
    private $baseUrl;
22
23 1
    public function __construct(LogRepository $logRepository, string $baseUrl, $options = null)
24
    {
25 1
        parent::__construct($options);
26 1
        $this->logRepository = $logRepository;
27 1
        $this->baseUrl = $baseUrl;
28 1
    }
29
30
    /**
31
     * Write a message to the log
32
     *
33
     * @param array $event log data event
34
     */
35 5
    protected function doWrite(array $event): void
36
    {
37 5
        $completedEvent = $this->completeEvent($event);
38 5
        $this->logRepository->log($completedEvent);
39 5
    }
40
41 5
    private function completeEvent(array $event): array
42
    {
43 5
        $envData = $this->getEnvData();
44 5
        $event = array_merge($event, $envData);
45
46
        // If we are logging PHP errors, then we include all known information in message
47 5
        if ($event['extra']['errno'] ?? false) {
48
            $event['message'] .= "\nStacktrace:\n" . $this->getStacktrace();
49
        }
50
51 5
        $event['creation_date'] = $event['timestamp'];
52 5
        unset($event['timestamp'], $event['priorityName']);
53
54 5
        return $event;
55
    }
56
57
    /**
58
     * Retrieve dynamic information from environment to be logged.
59
     *
60
     * @return array
61
     */
62 5
    private function getEnvData(): array
63
    {
64 5
        $user = User::getCurrent();
65
66 5
        if (PHP_SAPI === 'cli') {
67 5
            global $argv;
68 5
            $request = $argv;
69 5
            $ip = 'script';
70 5
            $url = implode(' ', $argv);
71 5
            $referer = '';
72
        } else {
73
            $request = $_REQUEST;
74
            $ip = $_SERVER['REMOTE_ADDR'] ?? '';
75
            $url = $this->baseUrl . $_SERVER['REQUEST_URI'];
76
            $referer = $_SERVER['HTTP_REFERER'] ?? '';
77
        }
78
79
        $envData = [
80 5
            'creator_id' => $user ? $user->getId() : null,
81 5
            'url' => $url,
82 5
            'referer' => $referer,
83 5
            'request' => json_encode($request, JSON_PRETTY_PRINT),
84 5
            'ip' => $ip,
85
        ];
86
87 5
        return $envData;
88
    }
89
90
    /**
91
     * Returns the backtrace excluding the most recent calls to this function so we only get the interesting parts
92
     *
93
     * @return string
94
     */
95
    private function getStacktrace(): string
96
    {
97
        ob_start();
98
        @debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition for debug_print_backtrace(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

98
        /** @scrutinizer ignore-unhandled */ @debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
Are you sure the usage of debug_print_backtrace(Ap..._BACKTRACE_IGNORE_ARGS) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
99
        $trace = ob_get_contents();
100
        ob_end_clean();
101
102
        // Remove first items from backtrace as it's this function and previous logging functions which is not interesting
103
        $trace = preg_replace('/^#[0-4]\s+[^\n]*\n/m', '', $trace);
104
105
        // Renumber backtrace items.
106
        $trace = preg_replace_callback('/^#(\d+)/m', function ($matches) {
107
            return '#' . ($matches[1] - 5);
108
        }, $trace);
109
110
        return $trace;
111
    }
112
}
113