Passed
Push — 2.0 ( 6127f1...6cb80b )
by Samuel
02:33
created

AbstractHandler::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SMartins\Exceptions\Handlers;
4
5
use Exception;
6
use InvalidArgumentException;
7
use Illuminate\Support\Collection;
8
use SMartins\Exceptions\JsonApi\Error;
9
use SMartins\Exceptions\JsonApi\Response;
10
use Illuminate\Auth\AuthenticationException;
11
use Illuminate\Validation\ValidationException;
12
use SMartins\Exceptions\JsonApi\ErrorCollection;
13
use Illuminate\Auth\Access\AuthorizationException;
14
use Illuminate\Database\Eloquent\ModelNotFoundException;
15
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
17
18
abstract class AbstractHandler
19
{
20
    /**
21
     * The exception thrown.
22
     *
23
     * @var \Exception
24
     */
25
    protected $exception;
26
27
    /**
28
     * An array where the key is the class exception and the value is the handler
29
     * class that will treat the exception.
30
     *
31
     * @var array
32
     */
33
    protected $exceptionHandlers = [];
34
35
    /**
36
     * An internal array where the key is the exception class and the value is
37
     * the handler class that will treat the exception.
38
     *
39
     * @var array
40
     */
41
    protected $internalExceptionHandlers = [
42
        Exception::class => Handler::class,
43
        ModelNotFoundException::class => ModelNotFoundHandler::class,
44
        AuthenticationException::class => AuthenticationHandler::class,
45
        AuthorizationException::class => AuthorizationHandler::class,
46
        AuthorizationException::class => AuthorizationHandler::class,
47
        ValidationException::class => ValidationHandler::class,
48
        BadRequestHttpException::class => BadRequestHttpHandler::class,
49
        NotFoundHttpException::class => NotFoundHttpHandler::class,
50
        'Laravel\Passport\Exceptions\MissingScopeException' => MissingScopeHandler::class,
51
        'League\OAuth2\Server\Exception\OAuthServerException' => OAuthServerHandler::class,
52
    ];
53
54
    /**
55
     * Create instance using the Exception to be handled.
56
     *
57
     * @param Exception $e
58
     */
59
    public function __construct(Exception $e)
60
    {
61
        $this->exception = $e;
62
    }
63
64
    /**
65
     * Handle with an exception according to specific definitions. Returns one
66
     * or more errors using the exception from $exceptions attribute.
67
     *
68
     * @todo Change the return type to any interface to make more extensible.
69
     *
70
     * @return \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection
71
     */
72
    abstract public function handle();
73
74
    /**
75
     * Get error code. If code is empty from config file based on type.
76
     *
77
     * @param  string $type Code type from config file
78
     * @return int
79
     */
80
    public function getCode($type = 'default')
81
    {
82
        $code = $this->exception->getCode();
83
        if (empty($this->exception->getCode())) {
84
            $code = config('json-exception-handler.codes.'.$type);
85
        }
86
87
        return $code;
88
    }
89
90
    /**
91
     * Return response with handled exception.
92
     *
93
     * @return \SMartins\Exceptions\JsonApi\Response
94
     */
95
    public function handleException()
96
    {
97
        $handler = $this->getExceptionHandler();
98
99
        $errors = $this->validatedHandledException($handler->handle());
100
101
        return new Response($errors);
102
    }
103
104
    /**
105
     * Validate response from handle method of handler class.
106
     *
107
     * @param \SMartins\Exceptions\JsonApi\Error|\Smartins\Exceptions\JsonApi\ErrorCollection $errors
108
     * @return \SMartins\Exceptions\JsonApi\ErrorCollection
109
     *
110
     * @throws \InvalidArgumentException
111
     */
112
    public function validatedHandledException($errors)
113
    {
114
        if ($errors instanceof ErrorCollection) {
115
            return $errors->validated();
116
        } elseif ($errors instanceof Error) {
0 ignored issues
show
introduced by
$errors is always a sub-type of SMartins\Exceptions\JsonApi\Error.
Loading history...
117
            return (new ErrorCollection([$errors]))->setStatusCode($errors->getStatus());
118
        }
119
120
        throw new InvalidArgumentException('The errors must be an instance of ['.Error::class.'] or ['.ErrorCollection::class.'].');
121
    }
122
123
    /**
124
     * Get the class the will handle the Exception from exceptionHandlers attributes.
125
     *
126
     * @return mixed
127
     */
128
    public function getExceptionHandler()
129
    {
130
        $handlers = array_merge($this->exceptionHandlers, $this->internalExceptionHandlers);
131
132
        $handler = isset($handlers[get_class($this->exception)])
133
            ? $handlers[get_class($this->exception)]
134
            : $this->defaultHandler();
135
136
        return new $handler($this->exception);
137
    }
138
139
    /**
140
     * Get default pointer using file and line of exception.
141
     *
142
     * @return string
143
     */
144
    public function getDefaultPointer()
145
    {
146
        return $this->exception->getFile().':'.$this->exception->getLine();
147
    }
148
149
    /**
150
     * Get default title from exception.
151
     *
152
     * @return string
153
     */
154
    public function getDefaultTitle()
155
    {
156
        return snake_case(class_basename($this->exception));
157
    }
158
159
    /**
160
     * Get default http code. Check if exception has getStatusCode() methods.
161
     * If not get from config file.
162
     *
163
     * @return int
164
     */
165
    public function getStatusCode()
166
    {
167
        if (method_exists($this->exception, 'getStatusCode')) {
168
            return $this->exception->getStatusCode();
169
        }
170
171
        return config('json-exception-handler.http_code');
172
    }
173
174
    /**
175
     * The default handler to handle not treated exceptions.
176
     *
177
     * @return \SMartins\Exceptions\Handlers\Handler
178
     */
179
    public function defaultHandler()
180
    {
181
        return new Handler($this->exception);
182
    }
183
}
184