Completed
Push — master ( 1baeb0...6744a4 )
by Guilh
9s
created

ViewResponseListener   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 89.04%

Importance

Changes 8
Bugs 5 Features 0
Metric Value
wmc 31
c 8
b 5
f 0
lcom 1
cbo 8
dl 0
loc 132
ccs 65
cts 73
cp 0.8904
rs 9.8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getSubscribedEvents() 0 7 1
B getDefaultVars() 0 17 5
F onKernelView() 0 72 24
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\EventListener;
13
14
use FOS\RestBundle\Controller\Annotations\View as ViewAnnotation;
15
use FOS\RestBundle\FOSRestBundle;
16
use FOS\RestBundle\View\View;
17
use FOS\RestBundle\View\ViewHandlerInterface;
18
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
19
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
22
use Symfony\Component\HttpKernel\KernelEvents;
23
use Symfony\Component\Templating\TemplateReferenceInterface;
24
25
/**
26
 * The ViewResponseListener class handles the View core event as well as the "@extra:Template" annotation.
27
 *
28
 * @author Lukas Kahwe Smith <[email protected]>
29
 *
30
 * @internal
31
 */
32
class ViewResponseListener implements EventSubscriberInterface
33
{
34
    private $viewHandler;
35
    private $forceView;
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param ViewHandlerInterface $viewHandler
41
     * @param bool                 $forceView
42
     */
43 19
    public function __construct(ViewHandlerInterface $viewHandler, $forceView)
44
    {
45 19
        $this->viewHandler = $viewHandler;
46 19
        $this->forceView = $forceView;
47 19
    }
48
49
    /**
50
     * Renders the parameters and template and initializes a new response object with the
51
     * rendered content.
52
     *
53
     * @param GetResponseForControllerResultEvent $event
54
     */
55 19
    public function onKernelView(GetResponseForControllerResultEvent $event)
56
    {
57 19
        $request = $event->getRequest();
58
59 19
        if (!$request->attributes->get(FOSRestBundle::ZONE_ATTRIBUTE, true)) {
60
            return false;
61
        }
62
63 19
        $configuration = $request->attributes->get('_template');
64
65 19
        $view = $event->getControllerResult();
66 19
        if (!$view instanceof View) {
67 9
            if (!$configuration instanceof ViewAnnotation && !$this->forceView) {
68 1
                return;
69
            }
70
71 8
            $view = new View($view);
72 8
        }
73
74 18
        if ($configuration instanceof ViewAnnotation) {
75 12
            if ($configuration->getTemplateVar()) {
76
                $view->setTemplateVar($configuration->getTemplateVar());
77
            }
78 12
            if (null !== $configuration->getStatusCode() && (null === $view->getStatusCode() || Response::HTTP_OK === $view->getStatusCode())) {
79 1
                $view->setStatusCode($configuration->getStatusCode());
80 1
            }
81
82 12
            $context = $view->getContext();
83 12
            if ($configuration->getSerializerGroups()) {
84
                $context->addGroups($configuration->getSerializerGroups());
85
            }
86 12
            if ($configuration->getSerializerEnableMaxDepthChecks()) {
87
                $context->setMaxDepth(0);
88
            }
89
90 12
            list($controller, $action) = $configuration->getOwner();
91 12
            $vars = $this->getDefaultVars($configuration, $controller, $action);
92 12
        } else {
93 6
            $vars = null;
94
        }
95
96 18
        if (null === $view->getFormat()) {
97 18
            $view->setFormat($request->getRequestFormat());
98 18
        }
99
100 18
        if ($this->viewHandler->isFormatTemplating($view->getFormat())
101 18
            && !$view->getRoute()
0 ignored issues
show
Bug Best Practice introduced by
The expression $view->getRoute() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
102 18
            && !$view->getLocation()
0 ignored issues
show
Bug Best Practice introduced by
The expression $view->getLocation() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
103 18
        ) {
104 10
            if (null !== $vars && 0 !== count($vars)) {
105 4
                $parameters = (array) $this->viewHandler->prepareTemplateParameters($view);
106 4
                foreach ($vars as $var) {
107 4
                    if (!array_key_exists($var, $parameters)) {
108 3
                        $parameters[$var] = $request->attributes->get($var);
109 3
                    }
110 4
                }
111 4
                $view->setData($parameters);
112 4
            }
113
114 10
            if ($configuration && ($template = $configuration->getTemplate()) && !$view->getTemplate()) {
115 2
                if ($template instanceof TemplateReferenceInterface) {
116 1
                    $template->set('format', null);
117 1
                }
118
119 2
                $view->setTemplate($template);
120 2
            }
121 10
        }
122
123 18
        $response = $this->viewHandler->handle($view, $request);
124
125 18
        $event->setResponse($response);
126 18
    }
127
128 14
    public static function getSubscribedEvents()
129
    {
130
        // Must be executed before SensioFrameworkExtraBundle's listener
131
        return array(
132 14
            KernelEvents::VIEW => array('onKernelView', 30),
133 14
        );
134
    }
135
136
    /**
137
     * @param Request  $request
0 ignored issues
show
Bug introduced by
There is no parameter named $request. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
138
     * @param Template $template
139
     * @param object   $controller
140
     * @param string   $action
141
     *
142
     * @return array
143
     *
144
     * @see \Sensio\Bundle\FrameworkExtraBundle\EventListener\TemplateListener::resolveDefaultParameters()
145
     */
146 12
    private function getDefaultVars(Template $template = null, $controller, $action)
147
    {
148 12
        if (0 !== count($arguments = $template->getVars())) {
0 ignored issues
show
Bug introduced by
It seems like $template is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
149
            return $arguments;
150
        }
151
152 12
        if (!$template instanceof ViewAnnotation || $template->isPopulateDefaultVars()) {
153 11
            $r = new \ReflectionObject($controller);
154
155 11
            $arguments = array();
156 11
            foreach ($r->getMethod($action)->getParameters() as $param) {
157 8
                $arguments[] = $param->getName();
158 11
            }
159
160 11
            return $arguments;
161
        }
162 1
    }
163
}
164