Handler::context()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 10
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
namespace App\Exceptions;
4
5
use Illuminate\Auth\Access\AuthorizationException;
6
use Illuminate\Auth\AuthenticationException;
7
use Illuminate\Database\Eloquent\ModelNotFoundException;
8
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
9
use Illuminate\Http\Exceptions\HttpResponseException;
10
use Illuminate\Session\TokenMismatchException;
11
use Illuminate\Support\Facades\Auth;
12
use Illuminate\Support\Facades\Lang;
13
use Illuminate\Support\Facades\Log;
14
use Illuminate\Support\Facades\Request;
15
use Illuminate\Validation\ValidationException;
16
use Symfony\Component\HttpKernel\Exception\HttpException;
17
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
18
use Throwable;
19
20
class Handler extends ExceptionHandler
21
{
22
    /**
23
     * A list of the exception types that are not reported.
24
     *
25
     * @var array
26
     */
27
    protected $dontReport = [];
28
29
    /**
30
     * A list of the inputs that are never flashed for validation exceptions.
31
     *
32
     * @var array
33
     */
34
    protected $dontFlash = [
35
        'password',
36
        'password_confirmation',
37
        'current_password',
38
        'new_password',
39
        'new_password_confirmation',
40
    ];
41 11
42
    /**
43 11
     * OVERRIDE
44 11
     * A list of the internal exception types that should not be reported.
45
     *
46
     * @var array
47
     */
48
    protected $internalDontReport = [
49
        AuthenticationException::class,
50
        AuthorizationException::class,
51
        HttpResponseException::class,
52
        ModelNotFoundException::class,
53 11
        ValidationException::class,
54
    ];
55 11
56
    /**
57
     * Report or log an exception.
58 11
     *
59
     * This is a great spot to send exceptions to Flare, Sentry, Bugsnag, etc.
60
     *
61
     * @param  \Throwable  $exception
62
     * @return void
63
     */
64
    public function report(Throwable $exception)
65
    {
66
        if ($exception instanceof TokenMismatchException) {
67
            $logData = [
68 1
                'requestToken' => request()->header('x-csrf-token'),
0 ignored issues
show
Bug introduced by
The function request 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

68
                'requestToken' => /** @scrutinizer ignore-call */ request()->header('x-csrf-token'),
Loading history...
69
                'sessionToken' => session()->token(),
0 ignored issues
show
Bug introduced by
The function session 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

69
                'sessionToken' => /** @scrutinizer ignore-call */ session()->token(),
Loading history...
70 1
                'session' => session()->all(),
71
                'user' => request()->user(),
72
                'requestUrl' => request()->url()
73 1
            ];
74
            $message = '419 CSRF Token Mismatch. ' . collect($logData)->toJson();
0 ignored issues
show
Bug introduced by
The function collect 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

74
            $message = '419 CSRF Token Mismatch. ' . /** @scrutinizer ignore-call */ collect($logData)->toJson();
Loading history...
75
            Log::debug($message);
76 1
        }
77
78 1
        parent::report($exception);
79
    }
80
81
    /**
82
     * OVERRIDE
83
     * Get the default context variables for logging.
84
     *
85
     * @return array
86
     */
87
    protected function context()
88 2
    {
89
        try {
90 2
            return array_filter([
91 2
                'userId' => Auth::id(),
92 2
                'url' => Request::path(),
93 2
                'method' => Request::method(),
94 2
                'referer' => Request::header('referer', '')
95
            ]);
96
        } catch (\Throwable $e) {
97
            return [];
98 2
        }
99
    }
100
101
    /**
102
     * Render an exception into an HTTP response.
103
     *
104
     * @param  \Illuminate\Http\Request  $request
105
     * @param  Throwable  $exception
106
     * @return \Illuminate\Http\Response
107
     *
108
     * @throws Throwable
109
     */
110
    public function render($request, Throwable $exception)
111
    {
112
        // Redirect upper case URLs to lower case route.
113
        $url = $request->url();
114
        $loweredCaseUrl = strtolower($url);
115
        if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException && $url !== $loweredCaseUrl) {
116
            return redirect($loweredCaseUrl);
0 ignored issues
show
Bug introduced by
The function redirect 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

116
            return /** @scrutinizer ignore-call */ redirect($loweredCaseUrl);
Loading history...
117
        }
118
119
        // Laravel will render out the error page by default even for JSON
120
        // requests... this will return a standardized JSON response with a 403
121
        // if unauthorized.
122
        if ($exception instanceof AuthorizationException && $request->wantsJson()) {
123
            return response()->json(['message' => $exception->getMessage()], 403);
0 ignored issues
show
Bug introduced by
The function response 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

123
            return /** @scrutinizer ignore-call */ response()->json(['message' => $exception->getMessage()], 403);
Loading history...
124
        }
125
        if ($exception instanceof AdminException) {
126
            return $exception->render($request);
127
        }
128
        if ($exception instanceof TwoFactorRequiredException) {
129
            return $exception->render($request);
130
        }
131
        if ($exception instanceof TokenMismatchException) {
132
            $newMessage = $exception->getMessage() . ' ' . Lang::get('errors.refresh_page');
133
            $modifiedException = new TokenMismatchException($newMessage, $exception->getCode(), $exception);
134
            return parent::render($request, $modifiedException);
135
        }
136
        if ($exception instanceof StateMachineException) {
137
            return parent::render($request, new HttpException(400, $exception->getMessage()));
138
        }
139
        if ($exception instanceof SendEmailException) {
140
            return parent::render($request, new HttpException(400, $exception->getMessage()));
141
        }
142
        return parent::render($request, $exception);
143
    }
144
145
    /**
146
     * Convert an authentication exception into an unauthenticated response.
147
     *
148
     * @param  \Illuminate\Http\Request  $request
149
     * @param  \Illuminate\Auth\AuthenticationException  $exception
150
     * @return \Illuminate\Http\Response
151
     */
152
    protected function unauthenticated($request, AuthenticationException $exception)
153
    {
154
        if ($request->expectsJson()) {
155
            return response()->json(['error' => 'Unauthenticated.'], 401);
0 ignored issues
show
Bug introduced by
The function response 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

155
            return /** @scrutinizer ignore-call */ response()->json(['error' => 'Unauthenticated.'], 401);
Loading history...
156
        }
157
        $loginRoute = ($exception->redirectTo() !== null && $exception->redirectTo() !== '')
158
            ? $exception->redirectTo()
159
            : route('login');
0 ignored issues
show
Bug introduced by
The function route 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

159
            : /** @scrutinizer ignore-call */ route('login');
Loading history...
160
        return redirect()->guest($loginRoute);
0 ignored issues
show
Bug introduced by
The function redirect 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

160
        return /** @scrutinizer ignore-call */ redirect()->guest($loginRoute);
Loading history...
161
    }
162
163
    /**
164
     * OVERRIDE
165
     * Render the given HttpException.
166
     *
167
     * @param  \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface  $e
168
     * @return \Symfony\Component\HttpFoundation\Response
169
     */
170
    protected function renderHttpException(HttpExceptionInterface $e)
171
    {
172
        if (!view()->exists("errors.{$e->getStatusCode()}")) {
0 ignored issues
show
Bug introduced by
The function view 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

172
        if (!/** @scrutinizer ignore-call */ view()->exists("errors.{$e->getStatusCode()}")) {
Loading history...
173
            return response()->view('errors.default', [
0 ignored issues
show
Bug introduced by
The function response 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

173
            return /** @scrutinizer ignore-call */ response()->view('errors.default', [
Loading history...
174
                'exception' => $e,
175
                'goc' => Lang::get('common/goc'),
176
                'alert' => Lang::get('common/alert'),
177
                'error' => Lang::get('errors')['default'],
178
            ], $e->getStatusCode(), $e->getHeaders());
179
        }
180
        return parent::renderHttpException($e);
181
    }
182
}
183