LogEnvelope::isSkipException()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php 
2
3
namespace Yaro\LogEnvelope;
4
5
use Exception;
6
use SplFileObject;
7
use Illuminate\Support\Facades\Log;
8
use Illuminate\Support\Facades\Request;
9
use Illuminate\Support\Facades\Session;
10
use Yaro\LogEnvelope\Drivers\DriverFactory;
11
12
class LogEnvelope
13
{
14
    private $config = [];
15
    private $cachedConfig = [];
16
17
    public function __construct()
18
    {
19
        $this->config['censored_fields'] = config('yaro.log-envelope.censored_fields', ['password']);
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

19
        $this->config['censored_fields'] = /** @scrutinizer ignore-call */ config('yaro.log-envelope.censored_fields', ['password']);
Loading history...
20
        $this->config['except'] = config('yaro.log-envelope.except', []);
21
        $this->config['count'] = config('yaro.log-envelope.lines_count', 6);
22
        $this->config['drivers'] = config('yaro.log-envelope.drivers', []);
23
    } // end __construct
24
25
    public function send($exception)
26
    {
27
        $this->onBefore();
28
29
        try {
30
            $data = $this->getExceptionData($exception);
31
32
            if ($this->isSkipException($data['class'])) {
33
                return;
34
            }
35
36
            foreach ($this->config['drivers'] as $driver => $driverConfig) {
37
                DriverFactory::create($driver, $data)->setConfig($driverConfig)->send();
38
            }
39
        } catch (Exception $e) {
40
            Log::error($e);
41
        }
42
        
43
        $this->onAfter();
44
    } // end send
45
    
46
    private function onBefore()
47
    {
48
        $this->cachedConfig = [];
49
        $forcedConfig = config('yaro.log-envelope.force_config', []);
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

49
        $forcedConfig = /** @scrutinizer ignore-call */ config('yaro.log-envelope.force_config', []);
Loading history...
50
        foreach ($forcedConfig as $configKey => $configValue) {
51
            $this->cachedConfig[$configKey] = config($configKey);
52
        }
53
        if ($forcedConfig) {
54
            config($forcedConfig);
55
        }
56
    } // end onBefore
57
    
58
    private function onAfter()
59
    {
60
        if ($this->cachedConfig) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->cachedConfig of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
61
            config($this->cachedConfig);
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

61
            /** @scrutinizer ignore-call */ 
62
            config($this->cachedConfig);
Loading history...
62
        }
63
    } // end onAfter
64
    
65
    public function isSkipException($exceptionClass)
66
    {
67
        return in_array($exceptionClass, $this->config['except']);
68
    } // end isSkipException
69
70
    private function getExceptionData($exception)
71
    {
72
        $data = [];
73
74
        $data['host'] = Request::server('HTTP_HOST');
75
        $data['method'] = Request::method();
76
        $data['fullUrl'] = Request::fullUrl();
77
        if (php_sapi_name() === 'cli') {
78
            $data['host'] = parse_url(config('app.url'), PHP_URL_HOST);
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

78
            $data['host'] = parse_url(/** @scrutinizer ignore-call */ config('app.url'), PHP_URL_HOST);
Loading history...
79
            $data['method'] = 'CLI';
80
        }
81
        $data['exception'] = $exception->getMessage();
82
        $data['error'] = $exception->getTraceAsString();
83
        $data['line'] = $exception->getLine();
84
        $data['file'] = $exception->getFile();
85
        $data['class'] = get_class($exception);
86
        $data['storage'] = array(
87
            'SERVER'  => Request::server(),
88
            'GET'     => Request::query(),
89
            'POST'    => $_POST,
90
            'FILE'    => Request::file(),
91
            'OLD'     => Request::hasSession() ? Request::old() : [],
92
            'COOKIE'  => Request::cookie(),
93
            'SESSION' => Request::hasSession() ? Session::all() : [],
94
            'HEADERS' => Request::header(),
95
        );
96
97
        // Remove empty, false and null values
98
        $data['storage'] = array_filter($data['storage']);
99
100
        // Censor sensitive field values
101
        array_walk_recursive($data['storage'], self::censorSensitiveFields(...));
102
103
        $count = $this->config['count'];
104
        
105
        $data['exegutor']   = [];
106
        $data['file_lines'] = [];
107
        
108
        $file = new SplFileObject($data['file']);
109
        for ($i = -1 * abs($count); $i <= abs($count); $i++) {
110
            list($line, $exegutorLine) = $this->getLineInfo($file, $data['line'], $i);
111
            if (!$line && !$exegutorLine) {
112
                continue;
113
            }
114
            $data['exegutor'][] = $exegutorLine;
115
            $data['file_lines'][$data['line'] + $i] = $line;
116
        }
117
118
        // to make Symfony exception more readable
119
        if ($data['class'] == 'Symfony\Component\Debug\Exception\FatalErrorException') {
120
            preg_match("~^(.+)' in ~", $data['exception'], $matches);
121
            if (isset($matches[1])) {
122
                $data['exception'] = $matches[1];
123
            }
124
        }
125
126
        return $data;
127
    } // end getExceptionData
128
129
    /**
130
     * Set the value of specified fields to *****
131
     *
132
     * @param string $value
133
     * @param string $key
134
     * @return void
135
     */
136
    public function censorSensitiveFields(&$value, $key)
137
    {
138
        if (in_array($key, $this->config['censored_fields'], true)) {
139
            $value = '*****';
140
        }
141
    }
142
143
    /**
144
     * @param SplFileObject $file
145
     */
146
    private function getLineInfo($file, $line, $i)
147
    {
148
        $currentLine = $line + $i;
149
        // cuz array starts with 0, when file lines start count from 1
150
        $index = $currentLine - 1;
151
        if ($index < 0) {
152
            return [false, false];
153
        }
154
        $file->seek($index);
155
        
156
        if ($file->eof()) {
157
            return [false, false];
158
        }
159
160
        return [
161
            $file->current(),
162
            [
163
                'line' => '<span style="color:#aaaaaa;">' . $currentLine . '.</span> ' . SyntaxHighlight::process($file->current()),
164
                'wrap_left' => $i ? '' : '<span style="color: #F5F5F5; background-color: #5A3E3E; width: 100%; display: block;">',
165
                'wrap_right' => $i ? '' : '</span>',
166
            ]
167
        ];
168
    } // end getLineInfo
169
}
170