Completed
Pull Request — develop (#453)
by Luca
21:47 queued 06:50
created

VersionController::getSecuredObjectId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of Sulu.
5
 *
6
 * (c) Sulu GmbH
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Sulu\Bundle\ArticleBundle\Controller;
13
14
use FOS\RestBundle\Context\Context;
15
use FOS\RestBundle\Controller\Annotations\Post;
16
use FOS\RestBundle\Routing\ClassResourceInterface;
17
use FOS\RestBundle\View\ViewHandlerInterface;
18
use Sulu\Bundle\ArticleBundle\Admin\ArticleAdmin;
19
use Sulu\Component\Content\Document\Behavior\SecurityBehavior;
20
use Sulu\Component\DocumentManager\DocumentManagerInterface;
21
use Sulu\Component\DocumentManager\Version;
22
use Sulu\Component\Rest\AbstractRestController;
23
use Sulu\Component\Rest\Exception\RestException;
24
use Sulu\Component\Rest\ListBuilder\ListRepresentation;
25
use Sulu\Component\Rest\ListBuilder\ListRestHelperInterface;
26
use Sulu\Component\Rest\RequestParametersTrait;
27
use Sulu\Component\Security\Authentication\UserRepositoryInterface;
28
use Sulu\Component\Security\SecuredControllerInterface;
29
use Symfony\Component\HttpFoundation\Request;
30
use Symfony\Component\HttpFoundation\Response;
31
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
32
33
/**
34
 * Handles the versions of articles.
35
 */
36
class VersionController extends AbstractRestController implements ClassResourceInterface, SecuredControllerInterface
37
{
38
    use RequestParametersTrait;
39
40
    /**
41
     * @var DocumentManagerInterface
42
     */
43
    private $documentManager;
44
45
    /**
46
     * @var ListRestHelperInterface
47
     */
48
    private $restHelper;
49
50
    /**
51
     * @var UserRepositoryInterface
52
     */
53
    private $userRepository;
54
55
    public function __construct(
56
        ViewHandlerInterface $viewHandler,
57
        DocumentManagerInterface $documentManager,
58
        ListRestHelperInterface $restHelper,
59
        UserRepositoryInterface $userRepository,
60
        ?TokenStorageInterface $tokenStorage = null
61
    ) {
62
        parent::__construct($viewHandler, $tokenStorage);
63
64
        $this->documentManager = $documentManager;
65
        $this->restHelper = $restHelper;
66
        $this->userRepository = $userRepository;
67
    }
68
69
    /**
70
     * Returns the versions for the article with the given UUID.
71
     *
72
     * @param string $uuid
73
     *
74
     * @return Response
75
     */
76
    public function cgetAction(Request $request, $uuid)
77
    {
78
        $locale = $this->getRequestParameter($request, 'locale', true);
79
80
        $document = $this->documentManager->find($uuid, $request->query->get('locale'));
81
        $versions = array_reverse(
82
            array_filter(
83
                $document->getVersions(),
84
                function($version) use ($locale) {
85
                    /** @var Version $version */
86
                    return $version->getLocale() === $locale;
87
                }
88
            )
89
        );
90
        $total = count($versions);
91
92
        $limit = $this->restHelper->getLimit();
93
94
        $versions = array_slice($versions, $this->restHelper->getOffset(), $limit);
95
96
        $userIds = array_unique(
97
            array_map(
98
                function($version) {
99
                    /** @var Version $version */
100
                    return $version->getAuthor();
101
                },
102
                $versions
103
            )
104
        );
105
106
        $users = $this->userRepository->findUsersById($userIds);
107
        $fullNamesByIds = [];
108
        foreach ($users as $user) {
109
            $fullNamesByIds[$user->getId()] = $user->getContact()->getFullName();
110
        }
111
112
        $versionData = [];
113
        foreach ($versions as $version) {
114
            $versionData[] = [
115
                'id' => str_replace('.', '_', $version->getId()),
116
                'locale' => $version->getLocale(),
117
                'author' => array_key_exists($version->getAuthor(), $fullNamesByIds)
118
                    ? $fullNamesByIds[$version->getAuthor()] : '',
119
                'authored' => $version->getAuthored(),
120
            ];
121
        }
122
123
        $versionCollection = new ListRepresentation(
124
            $versionData,
125
            'versions',
126
            $request->attributes->get('_route'),
127
            [
128
                'uuid' => $uuid,
129
                'locale' => $locale,
130
            ],
131
            $this->restHelper->getPage(),
132
            $limit,
133
            $total
134
        );
135
136
        return $this->handleView($this->view($versionCollection));
137
    }
138
139
    /**
140
     * @param string $uuid
141
     * @param int $version
142
     *
143
     * @Post("/articles/{uuid}/versions/{version}")
144
     *
145
     * @return Response
146
     *
147
     * @throws RestException
148
     */
149
    public function postTriggerAction(Request $request, $uuid, $version)
150
    {
151
        $action = $this->getRequestParameter($request, 'action', true);
152
        $locale = $this->getLocale($request);
153
154
        switch ($action) {
155
            case 'restore':
156
                $document = $this->documentManager->find($uuid, $locale);
157
158
                $this->documentManager->restore(
159
                    $document,
160
                    $locale,
161
                    str_replace('_', '.', $version)
162
                );
163
                $this->documentManager->flush();
164
165
                $data = $this->documentManager->find($uuid, $locale);
166
                $view = $this->view($data, null !== $data ? Response::HTTP_OK : Response::HTTP_NO_CONTENT);
167
168
                $context = new Context();
169
                $context->setGroups(['defaultPage', 'defaultArticle', 'smallArticlePage']);
170
                $context->setSerializeNull(true);
171
                $view->setContext($context);
172
173
                break;
174
            default:
175
                throw new RestException(sprintf('Unrecognized action: "%s"', $action));
176
        }
177
178
        return $this->handleView($view);
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function getSecurityContext()
185
    {
186
        return ArticleAdmin::SECURITY_CONTEXT;
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    public function getLocale(Request $request)
193
    {
194
        return $this->getRequestParameter($request, 'locale', true);
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200
    public function getSecuredClass()
201
    {
202
        return SecurityBehavior::class;
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208
    public function getSecuredObjectId(Request $request)
209
    {
210
        return $request->get('uuid');
211
    }
212
}
213