Passed
Push — master ( 6282ae...86ce5d )
by Gabor
04:01
created

FinalMiddleware::filterHeaderName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * WebHemi.
4
 *
5
 * PHP version 7.1
6
 *
7
 * @copyright 2012 - 2018 Gixx-web (http://www.gixx-web.com)
8
 * @license   https://opensource.org/licenses/MIT The MIT License (MIT)
9
 *
10
 * @link      http://www.gixx-web.com
11
 */
12
declare(strict_types = 1);
13
14
namespace WebHemi\Middleware\Common;
15
16
use RuntimeException;
17
use Throwable;
18
use WebHemi\Auth\ServiceInterface as AuthInterface;
19
use WebHemi\Data\Entity\User\UserEntity;
20
use WebHemi\Environment\ServiceInterface as EnvironmentInterface;
21
use WebHemi\Http\ResponseInterface;
22
use WebHemi\Http\ServerRequestInterface;
23
use WebHemi\Logger\ServiceInterface as LoggerInterface;
24
use WebHemi\Middleware\MiddlewareInterface;
25
26
/**
27
 * Class FinalMiddleware.
28
 */
29
class FinalMiddleware implements MiddlewareInterface
30
{
31
    /** @var AuthInterface */
32
    private $authAdapter;
33
    /** @var EnvironmentInterface */
34
    private $environmentManager;
35
    /** @var LoggerInterface */
36
    private $logAdapter;
37
38
    /**
39
     * FinalMiddleware constructor.
40
     *
41
     * @param AuthInterface        $authAdapter
42
     * @param EnvironmentInterface $environmentManager
43
     * @param LoggerInterface      $logAdapter
44
     */
45 3
    public function __construct(
46
        AuthInterface $authAdapter,
47
        EnvironmentInterface $environmentManager,
48
        LoggerInterface $logAdapter
49
    ) {
50 3
        $this->authAdapter = $authAdapter;
51 3
        $this->environmentManager = $environmentManager;
52 3
        $this->logAdapter = $logAdapter;
53 3
    }
54
55
    /**
56
     * Sends out the headers and prints the response body to the output.
57
     *
58
     * @param ServerRequestInterface $request
59
     * @param ResponseInterface      $response
60
     * @return void
61
     */
62 3
    public function __invoke(ServerRequestInterface&$request, ResponseInterface&$response) : void
63
    {
64
        // Handle errors here.
65 3
        if (!in_array($response->getStatusCode(), [ResponseInterface::STATUS_OK, ResponseInterface::STATUS_REDIRECT])) {
66 2
            $exception = $request->getAttribute(ServerRequestInterface::REQUEST_ATTR_MIDDLEWARE_EXCEPTION)
67 2
                ?? new RuntimeException($response->getReasonPhrase(), $response->getStatusCode());
68
69
            // Make sure that the Request has the exception.
70 2
            $request = $request->withAttribute(ServerRequestInterface::REQUEST_ATTR_MIDDLEWARE_EXCEPTION, $exception);
71
72 2
            $this->logErrorResponse($exception, $request, $response);
73
        }
74 3
    }
75
76
    /**
77
     * Logs the error.
78
     *
79
     * @param Throwable              $exception
80
     * @param ServerRequestInterface $request
81
     * @param ResponseInterface      $response
82
     */
83 2
    private function logErrorResponse(
84
        Throwable $exception,
85
        ServerRequestInterface&$request,
86
        ResponseInterface&$response
87
    ) : void {
88 2
        $identity = 'Unauthenticated user';
89
90 2
        if ($this->authAdapter->hasIdentity()) {
91
            /** @var UserEntity $userEntity */
92 2
            $userEntity = $this->authAdapter->getIdentity();
93 2
            $identity = $userEntity->getEmail();
94
        }
95
96
        $logData = [
97 2
            'User' => $identity,
98 2
            'IP' => $this->environmentManager->getClientIp(),
99 2
            'RequestUri' => $request->getUri()->getPath().'?'.$request->getUri()->getQuery(),
100 2
            'RequestMethod' => $request->getMethod(),
101 2
            'Error' => $response->getStatusCode().' '.$response->getReasonPhrase(),
102 2
            'Exception' => $this->getExceptionAsString($exception),
103 2
            'Parameters' => $request->getParsedBody()
104
        ];
105 2
        $this->logAdapter->log('error', json_encode($logData));
106 2
    }
107
108
    /**
109
     * Convert the exception into plain text instead of the fancy HTML output of the xdebug...
110
     *
111
     * @param Throwable $exception
112
     * @return string
113
     */
114 2
    private function getExceptionAsString(Throwable $exception)
115
    {
116 2
        return 'Exception ('.$exception->getCode().'): "'.$exception->getMessage().'" '
117 2
            .'in '.$exception->getFile().' on line '.$exception->getLine().PHP_EOL
118 2
            .'Call stack'.PHP_EOL
119 2
            .$exception->getTraceAsString();
120
    }
121
}
122