Recorder::record()   B
last analyzed

Complexity

Conditions 8
Paths 33

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 8.0355
c 0
b 0
f 0
ccs 23
cts 23
cp 1
cc 8
nc 33
nop 1
crap 8
1
<?php
2
3
namespace Tylercd100\LERN\Components;
4
5
use Throwable;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Request;
8
use Illuminate\Support\Facades\Cache;
9
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
10
use Tylercd100\LERN\Exceptions\RecorderFailedException;
11
use Tylercd100\LERN\Models\ExceptionModel;
12
use Carbon\Carbon;
13
14
class Recorder extends Component {
15
16
    /**
17
     * @var mixed
18
     */
19
    protected $config = [];
20
21
    /**
22
     * @var array
23
     */
24
    protected $absolutelyDontHandle = [
25
        \Tylercd100\LERN\Exceptions\RecorderFailedException::class,
26
        \Doctrine\DBAL\Driver\PDOException::class,
27
    ];
28
29
    /**
30
     * The constructor
31
     */
32
    public function __construct() {
33 57
        $this->config = config('lern.record');
34 57
    }
35 57
36
    /**
37
     * Records an Exception to the database
38
     * @param  Throwable $e The exception you want to record
39
     * @return false|ExceptionModel
40
     * @throws RecorderFailedException
41
     */
42
    public function record(Throwable $e)
43 18
    {
44
        if ($this->shouldntHandle($e)) {
45 18
            return false;
46 6
        }
47
48
        $opts = [
49
            'class'       => get_class($e),
50 15
            'file'        => $e->getFile(),
51 15
            'line'        => $e->getLine(),
52 15
            'code'        => (is_int($e->getCode()) ? $e->getCode() : 0),
53 15
            'message'     => $e->getMessage(),
54 15
            'trace'       => $e->getTraceAsString(),
55 15
        ];
56
57
        $configDependant = array_keys($this->config['collect']);
58 15
59
        foreach ($configDependant as $key) {
60 15
            if ($this->canCollect($key)) {
61 15
                $value = $this->collect($key, $e);
62 12
                if ($value !== null) {
63 12
                    $opts[$key] = $value;
64 15
                }
65
            }
66
        }
67
68
        $class = config('lern.record.model');
69 15
        $class = !empty($class) ? $class : ExceptionModel::class;
70 15
71
        $model = new $class();
72 15
        foreach($opts as $key => $value) {
73 15
            $model->{$key} = $value;
74 15
        }
75
76
        $model->save();
77 15
78
        Cache::forever($this->getCacheKey($e), Carbon::now());
79 12
80
        return $model;
81 12
    }
82
83
    /**
84
     * Checks the config to see if you can collect certain information
85
     * @param  string $type the config value you want to check
86
     * @return boolean      
87
     */
88
    private function canCollect($type) {
89 15
        if (!empty($this->config) && !empty($this->config['collect']) && !empty($this->config['collect'][$type])) {
90 15
            return $this->config['collect'][$type] === true;
91 12
        }
92
        return false;
93 3
    }
94
95
    /**
96
     * @param string $key
97
     * @param Throwable $e
98
     * @return array|int|null|string
99
     * @throws Throwable
100
     */
101
    protected function collect($key, Throwable $e = null) {
102 12
        switch ($key) {
103
            case 'user_id':
104 12
                return $this->getUserId();
105 12
            case 'method':
106 12
                return $this->getMethod();
107 12
            case 'url':
108 12
                return $this->getUrl();
109 12
            case 'data':
110 12
                return $this->getData();
111 12
            case 'ip':
112 12
                return $this->getIp();
113
            case 'status_code':
114 12
                if ($e === null) {
115 12
                    return 0;
116
                }
117
                return $this->getStatusCode($e);
118 12
            default:
119
                ddd();// what to do here ??????????
120
//                throw new Exception("{$key} is not supported! Therefore it cannot be collected!");
121
        }
122
    }
123
124
    /**
125
     * Gets the ID of the User that is logged in
126
     * @return integer|null The ID of the User or Null if not logged in
127
     */
128 12
    protected function getUserId() {
129 12
        $user = Auth::user();
130 12
        if (is_object($user) && !empty($user->id)) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
131
            return $user->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
132
        } else {
133 12
            return null;
134
        }
135
    }
136
137
    /**
138
     * Gets the Method of the Request
139
     * @return string|null Possible values are null or GET, POST, DELETE, PUT, etc...
140
     */
141 12
    protected function getMethod() {
142 12
        $method = Request::method();
143 12
        if (!empty($method)) {
144 12
            return $method;
145
        } else {
146
            return null;
147
        }
148
    }
149
150
    /**
151
     * Gets the input data of the Request
152
     * @return array|null The Input data or null
153
     */
154 15
    protected function getData() {
155 15
        $data = Request::all();
156 15
        if (is_array($data)) {
157 15
            return $this->excludeKeys($data);
158
        } else {
159
            return null;
160
        }
161
    }
162
163
    /**
164
     * Gets the URL of the Request
165
     * @return string|null Returns a URL string or null
166
     */
167 12
    protected function getUrl() {
168 12
        $url = Request::url();
169 12
        if (is_string($url)) {
170 12
            return $url;
171
        } else {
172
            return null;
173
        }
174
    }
175
176
    /**
177
     * Returns the IP from the request
178
     *
179
     * @return string
180
     */
181
    protected function getIp() {
182
        return Request::ip();
183
    }
184
185
    /**
186
     * Gets the status code of the Throwable
187
     * @param  Throwable $e The Throwable to check
188
     * @return string|integer The status code value
189
     */
190 12
    protected function getStatusCode(Throwable $e) {
191 12
        if ($e instanceof HttpExceptionInterface) {
192
            return $e->getStatusCode();
193
        } else {
194 12
            return 0;
195
        }
196
    }
197
198
    /**
199
     * This function will remove all keys from an array recursively as defined in the config file
200
     * @param  array $data The array to remove keys from
201
     * @return array $data
202
     */
203 21
    protected function excludeKeys(array $data) {
204 21
        $keys = isset($this->config['excludeKeys']) ? $this->config['excludeKeys'] : [];
205 21
        foreach ($data as $key => &$value) {
206 9
            if (in_array($key, $keys)) {
207 9
                unset($data[$key]);
208 9
            } else if (is_array($value)) {
209 9
                $value = $this->excludeKeys($value);
210
            }
211
        }
212
213 21
        return $data;
214
    }
215
}
216