Completed
Push — master ( b1054d...eba5f2 )
by Christian
07:28 queued 11s
created

ExceptionController   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 90%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 7
dl 0
loc 123
ccs 27
cts 30
cp 0.9
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A showAction() 0 19 4
A createView() 0 4 2
A getStatusCode() 0 4 1
A getAndCleanOutputBuffering() 0 9 2
A getStatusCodeFromThrowable() 0 14 3
1
<?php
2
3
/*
4
 * This file is part of the FOSRestBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\RestBundle\Controller;
13
14
use FOS\RestBundle\Util\ExceptionValueMap;
15
use FOS\RestBundle\View\View;
16
use FOS\RestBundle\View\ViewHandlerInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
20
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
21
22
/**
23
 * Custom ExceptionController that uses the view layer and supports HTTP response status code mapping.
24
 *
25
 * @final since 2.8
26
 */
27
class ExceptionController
28
{
29
    /**
30
     * @var ViewHandlerInterface
31
     */
32
    private $viewHandler;
33
34
    /**
35
     * @var ExceptionValueMap
36
     */
37
    private $exceptionCodes;
38
39
    /**
40
     * @var bool
41
     */
42
    private $showException;
43
44 9
    public function __construct(
45
        ViewHandlerInterface $viewHandler,
46
        ExceptionValueMap $exceptionCodes,
47
        $showException
48
    ) {
49 9
        $this->viewHandler = $viewHandler;
50 9
        $this->exceptionCodes = $exceptionCodes;
51 9
        $this->showException = $showException;
52 9
    }
53
54
    /**
55
     * Converts an Exception to a Response.
56
     *
57
     * @param Request                   $request
58
     * @param \Exception|\Throwable     $exception
59
     * @param DebugLoggerInterface|null $logger
60
     *
61
     * @throws \InvalidArgumentException
62
     *
63
     * @return Response
64
     */
65 9
    public function showAction(Request $request, $exception, DebugLoggerInterface $logger = null)
0 ignored issues
show
Unused Code introduced by
The parameter $logger is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
66
    {
67 9
        $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1));
0 ignored issues
show
Unused Code introduced by
$currentContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
68
69 9
        if ($exception instanceof \Exception) {
70 8
            $code = $this->getStatusCode($exception);
71
        } else {
72 1
            $code = $this->getStatusCodeFromThrowable($exception);
73
        }
74 9
        if ($exception instanceof \Exception) {
75 8
            $view = $this->createView($exception, $code, $request, $this->showException);
0 ignored issues
show
Bug introduced by
It seems like $code can also be of type boolean; however, FOS\RestBundle\Controlle...ontroller::createView() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
76
        } else {
77 1
            $view = new View($exception, $code, $exception instanceof HttpExceptionInterface ? $exception->getHeaders() : []);
0 ignored issues
show
Bug introduced by
It seems like $code can also be of type boolean; however, FOS\RestBundle\View\View::__construct() does only seem to accept integer|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
78
        }
79
80 9
        $response = $this->viewHandler->handle($view);
81
82 9
        return $response;
83
    }
84
85
    /**
86
     * @param \Exception $exception
87
     * @param int        $code
88
     * @param Request    $request
89
     * @param bool       $showException
90
     *
91
     * @return View
92
     */
93 8
    protected function createView(\Exception $exception, $code, Request $request, $showException)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $showException is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
    {
95 8
        return new View($exception, $code, $exception instanceof HttpExceptionInterface ? $exception->getHeaders() : []);
96
    }
97
98
    /**
99
     * Determines the status code to use for the response.
100
     *
101
     * @param \Exception $exception
102
     *
103
     * @return int
104
     */
105 8
    protected function getStatusCode(\Exception $exception)
106
    {
107 8
        return $this->getStatusCodeFromThrowable($exception);
108
    }
109
110
    /**
111
     * Gets and cleans any content that was already outputted.
112
     *
113
     * This code comes from Symfony and should be synchronized on a regular basis
114
     * see src/Symfony/Bundle/TwigBundle/Controller/ExceptionController.php
115
     *
116
     * @return string
117
     */
118 9
    private function getAndCleanOutputBuffering($startObLevel)
119
    {
120 9
        if (ob_get_level() <= $startObLevel) {
121 9
            return '';
122
        }
123
        Response::closeOutputBuffers($startObLevel + 1, true);
124
125
        return ob_get_clean();
126
    }
127
128
    /**
129
     * Determines the status code to use for the response.
130
     *
131
     * @param \Throwable $exception
132
     *
133
     * @return int
134
     */
135 9
    private function getStatusCodeFromThrowable(\Throwable $exception)
136
    {
137
        // If matched
138 9
        if ($statusCode = $this->exceptionCodes->resolveException($exception)) {
139
            return $statusCode;
140
        }
141
142
        // Otherwise, default
143 9
        if ($exception instanceof HttpExceptionInterface) {
144 1
            return $exception->getStatusCode();
145
        }
146
147 8
        return 500;
148
    }
149
}
150