Completed
Push — master ( c67e2b...ab6b60 )
by Tyler
02:09
created

Recorder::getStatusCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 3
cts 4
cp 0.75
rs 10
cc 2
nc 2
nop 1
crap 2.0625
1
<?php
2
3
namespace Tylercd100\LERN\Components;
4
5
use Exception;
6
use Illuminate\Support\Facades\Auth;
7
use Illuminate\Support\Facades\Input;
8
use Illuminate\Support\Facades\Request;
9
use Illuminate\Support\Facades\Cache;
10
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
11
use Tylercd100\LERN\Exceptions\RecorderFailedException;
12
use Tylercd100\LERN\Models\ExceptionModel;
13
use Carbon\Carbon;
14
15
class Recorder extends Component {
16
17
    /**
18
     * @var mixed
19
     */
20
    protected $config = [];
21
22
    /**
23
     * @var array
24
     */
25
    protected $absolutelyDontHandle = [
26
        \Tylercd100\LERN\Exceptions\RecorderFailedException::class,
27
        \Doctrine\DBAL\Driver\PDOException::class,
28
    ];
29
30
    /**
31
     * The constructor
32
     */
33 57
    public function __construct() {
34 57
        $this->config = config('lern.record');
35 57
    }
36
37
    /**
38
     * Records an Exception to the database
39
     * @param  Exception $e The exception you want to record
40
     * @return false|ExceptionModel
41
     * @throws RecorderFailedException
42
     */
43 18
    public function record(Exception $e)
44
    {
45 18
        if ($this->shouldntHandle($e)) {
46 6
            return false;
47
        }
48
49
        $opts = [
50 15
            'class'       => get_class($e),
51 15
            'file'        => $e->getFile(),
52 15
            'line'        => $e->getLine(),
53 15
            'code'        => (is_int($e->getCode()) ? $e->getCode() : 0),
54 15
            'message'     => $e->getMessage(),
55 15
            'trace'       => $e->getTraceAsString(),
56
        ];
57
58 15
        $configDependant = array_keys($this->config['collect']);
59
60 15
        foreach ($configDependant as $key) {
61 15
            if ($this->canCollect($key)) {
62 12
                $value = $this->collect($key, $e);
63 12
                if ($value !== null) {
64 15
                    $opts[$key] = $value;
65
                }
66
            }
67
        }
68
69 15
        $class = config('lern.recorder.model');
70 15
        $class = !empty($class) ? $class : ExceptionModel::class;
71
72 15
        $model = new $class();
73 15
        foreach($opts as $key => $value) {
74 15
            $model->{$key} = $value;
75
        }
76
77 15
        $model->save();
78
79 12
        Cache::forever($this->getCacheKey($e), Carbon::now());
80
81 12
        return $model;
82
    }
83
84
    /**
85
     * Checks the config to see if you can collect certain information
86
     * @param  string $type the config value you want to check
87
     * @return boolean      
88
     */
89 15
    private function canCollect($type) {
90 15
        if (!empty($this->config) && !empty($this->config['collect']) && !empty($this->config['collect'][$type])) {
91 12
            return $this->config['collect'][$type] === true;
92
        }
93 3
        return false;
94
    }
95
96
    /**
97
     * @param string $key
98
     * @param Exception $e
99
     * @return array|int|null|string
100
     * @throws Exception
101
     */
102 12
    protected function collect($key, Exception $e = null) {
103
        switch ($key) {
104 12
            case 'user_id':
105 12
                return $this->getUserId();
106 12
            case 'method':
107 12
                return $this->getMethod();
108 12
            case 'url':
109 12
                return $this->getUrl();
110 12
            case 'data':
111 12
                return $this->getData();
112 12
            case 'ip':
113
                return $this->getIp();
114 12
            case 'status_code':
115 12
                if ($e === null) {
116
                    return 0;
117
                }
118 12
                return $this->getStatusCode($e);
119
            default:
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 = Input::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 Exception
187
     * @param  Exception $e The Exception to check
188
     * @return string|integer The status code value
189
     */
190 12
    protected function getStatusCode(Exception $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 void
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