Completed
Push — ezp-30639-deprecated-view-acti... ( 6b3a78 )
by
unknown
14:01
created

ViewController::viewAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the ViewController class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\MVC\Symfony\Controller\Content;
10
11
use eZ\Publish\API\Repository\Repository;
12
use eZ\Publish\API\Repository\Values\Content\Content;
13
use eZ\Publish\API\Repository\Values\Content\Location;
14
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
15
use eZ\Publish\Core\MVC\Symfony\Controller\Controller;
16
use eZ\Publish\Core\MVC\Symfony\MVCEvents;
17
use eZ\Publish\Core\MVC\Symfony\Event\APIContentExceptionEvent;
18
use eZ\Publish\Core\MVC\Symfony\Security\Authorization\Attribute as AuthorizationAttribute;
19
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
20
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
21
use eZ\Publish\Core\MVC\Symfony\View\ViewManagerInterface;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
24
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
25
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
26
use DateTime;
27
use Exception;
28
29
/**
30
 * This controller provides the content view feature.
31
 *
32
 * @since 6.0.0 All methods except `view()` are deprecated and will be removed in the future.
33
 */
34
class ViewController extends Controller
35
{
36
    /** @var \eZ\Publish\Core\MVC\Symfony\View\ViewManagerInterface */
37
    protected $viewManager;
38
39
    /** @var \Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface */
40
    private $authorizationChecker;
41
42
    public function __construct(ViewManagerInterface $viewManager, AuthorizationCheckerInterface $authorizationChecker)
43
    {
44
        $this->viewManager = $viewManager;
45
        $this->authorizationChecker = $authorizationChecker;
46
    }
47
48
    /**
49
     * This is the default view action or a ContentView object.
50
     *
51
     * It doesn't do anything by itself: the returned View object is rendered by the ViewRendererListener
52
     * into an HttpFoundation Response.
53
     *
54
     * This action can be selectively replaced by a custom action by means of content_view
55
     * configuration. Custom actions can add parameters to the view and customize the Response the View will be
56
     * converted to. They may also bypass the ViewRenderer by returning an HttpFoundation Response.
57
     *
58
     * Cache is in both cases handled by the CacheViewResponseListener.
59
     *
60
     * @param \eZ\Publish\Core\MVC\Symfony\View\ContentView $view
61
     *
62
     * @return \eZ\Publish\Core\MVC\Symfony\View\ContentView
63
     */
64
    public function viewAction(ContentView $view)
65
    {
66
        return $view;
67
    }
68
69
    /**
70
     * Embed a content.
71
     * Behaves mostly like viewAction(), but with specific content load permission handling.
72
     *
73
     * @param \eZ\Publish\Core\MVC\Symfony\View\ContentView $view
74
     *
75
     * @return \eZ\Publish\Core\MVC\Symfony\View\ContentView
76
     */
77
    public function embedAction(ContentView $view)
78
    {
79
        return $view;
80
    }
81
82
    /**
83
     * Build the response so that depending on settings it's cacheable.
84
     *
85
     * @param string|null $etag
86
     * @param \DateTime|null $lastModified
87
     *
88
     * @return \Symfony\Component\HttpFoundation\Response
89
     */
90
    protected function buildResponse($etag = null, DateTime $lastModified = null)
91
    {
92
        $request = $this->getRequest();
93
        $response = new Response();
94
        if ($this->getParameter('content.view_cache') === true) {
95
            $response->setPublic();
96
            if ($etag !== null) {
97
                $response->setEtag($etag);
98
            }
99
100
            if ($this->getParameter('content.ttl_cache') === true) {
101
                $response->setSharedMaxAge(
102
                    $this->getParameter('content.default_ttl')
103
                );
104
            }
105
106
            // Make the response vary against X-User-Context-Hash header ensures that an HTTP
107
            // reverse proxy caches the different possible variations of the
108
            // response as it can depend on user role for instance.
109
            if ($request->headers->has('X-User-Context-Hash')) {
110
                $response->setVary('X-User-Context-Hash');
111
            }
112
113
            if ($lastModified != null) {
114
                $response->setLastModified($lastModified);
115
            }
116
        }
117
118
        return $response;
119
    }
120
121
    protected function handleViewException(Response $response, $params, Exception $e, $viewType, $contentId = null, $locationId = null)
122
    {
123
        $event = new APIContentExceptionEvent(
124
            $e,
125
            [
126
                'contentId' => $contentId,
127
                'locationId' => $locationId,
128
                'viewType' => $viewType,
129
            ]
130
        );
131
        $this->getEventDispatcher()->dispatch(MVCEvents::API_CONTENT_EXCEPTION, $event);
132
        if ($event->hasContentView()) {
133
            $response->setContent(
134
                $this->viewManager->renderContentView(
135
                    $event->getContentView(),
136
                    $params
137
                )
138
            );
139
140
            return $response;
141
        }
142
143
        throw $e;
144
    }
145
146
    /**
147
     * Creates the content to be returned when viewing a Location.
148
     *
149
     * @param Location $location
150
     * @param string $viewType
151
     * @param bool $layout
152
     * @param array $params
153
     *
154
     * @return string
155
     */
156
    protected function renderLocation(Location $location, $viewType, $layout = false, array $params = [])
157
    {
158
        return $this->viewManager->renderLocation($location, $viewType, $params + ['no_layout' => !$layout]);
159
    }
160
161
    /**
162
     * Creates the content to be returned when viewing a Content.
163
     *
164
     * @param Content $content
165
     * @param string $viewType
166
     * @param bool $layout
167
     * @param array $params
168
     *
169
     * @return string
170
     */
171
    protected function renderContent(Content $content, $viewType, $layout = false, array $params = [])
172
    {
173
        return $this->viewManager->renderContent($content, $viewType, $params + ['no_layout' => !$layout]);
174
    }
175
176
    /**
177
     * Performs the access checks.
178
     */
179
    protected function performAccessChecks()
180
    {
181
        if (!$this->isGranted(new AuthorizationAttribute('content', 'read'))) {
182
            throw new AccessDeniedException();
183
        }
184
    }
185
}
186