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

ArticlePageController::postAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 12
cts 12
cp 1
rs 9.6
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
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\Routing\ClassResourceInterface;
16
use FOS\RestBundle\View\ViewHandlerInterface;
17
use Sulu\Bundle\ArticleBundle\Admin\ArticleAdmin;
18
use Sulu\Bundle\ArticleBundle\Exception\ArticlePageNotFoundException;
19
use Sulu\Bundle\ArticleBundle\Exception\ParameterNotAllowedException;
20
use Sulu\Component\Content\Form\Exception\InvalidFormException;
21
use Sulu\Component\DocumentManager\DocumentManagerInterface;
22
use Sulu\Component\DocumentManager\MetadataFactoryInterface;
23
use Sulu\Component\Hash\RequestHashCheckerInterface;
24
use Sulu\Component\Rest\AbstractRestController;
25
use Sulu\Component\Rest\Exception\MissingParameterException;
26
use Sulu\Component\Rest\RequestParametersTrait;
27
use Sulu\Component\Security\SecuredControllerInterface;
28
use Symfony\Component\Form\FormFactoryInterface;
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
 * Provides API for article-pages.
35
 */
36
class ArticlePageController extends AbstractRestController implements ClassResourceInterface, SecuredControllerInterface
37
{
38
    const DOCUMENT_TYPE = 'article_page';
39
40
    use RequestParametersTrait;
41
42
    /**
43
     * @var DocumentManagerInterface
44
     */
45
    private $documentManager;
46
47
    /**
48
     * @var MetadataFactoryInterface
49
     */
50
    private $metadataFactory;
51 1
52
    /**
53 1
     * @var FormFactoryInterface
54 1
     */
55 1
    private $formFactory;
56 1
57
    /**
58 1
     * @var RequestHashCheckerInterface
59
     */
60
    private $requestHashChecker;
61
62
    public function __construct(
63 1
        ViewHandlerInterface $viewHandler,
64
        DocumentManagerInterface $documentManager,
65
        MetadataFactoryInterface $metadataFactory,
66
        FormFactoryInterface $formFactory,
67
        RequestHashCheckerInterface $requestHashChecker,
68
        ?TokenStorageInterface $tokenStorage = null
69
    ) {
70 1
        parent::__construct($viewHandler, $tokenStorage);
71 1
72 1
        $this->documentManager = $documentManager;
73 1
        $this->metadataFactory = $metadataFactory;
74 1
        $this->formFactory = $formFactory;
75
        $this->requestHashChecker = $requestHashChecker;
76
    }
77
78
    /**
79
     * Returns single article-page.
80
     *
81
     * @param string $articleUuid
82
     * @param string $uuid
83
     *
84
     * @return Response
85
     *
86
     * @throws ArticlePageNotFoundException
87 8
     */
88
    public function getAction($articleUuid, $uuid, Request $request)
89 8
    {
90 8
        $locale = $this->getRequestParameter($request, 'locale', true);
91 8
        $document = $this->documentManager->find(
92 8
            $uuid,
93
            $locale,
94 8
            [
95 8
                'load_ghost_content' => true,
96 8
                'load_shadow_content' => true,
97
            ]
98 8
        );
99 8
100 8
        if ($articleUuid !== $document->getParent()->getUuid()) {
101 8
            // it is required that the parent will be called to resolve the proxy.
102 8
            // this wont be done in the serialization process.
103
104
            throw new ArticlePageNotFoundException($uuid, $articleUuid);
105
        }
106
107
        $context = new Context();
108
        $context->setSerializeNull(true);
109
        $context->setGroups(['defaultPage', 'defaultArticlePage', 'smallArticle']);
110
111
        return $this->handleView(
112
            $this->view($document)->setContext($context)
113
        );
114
    }
115
116 3
    /**
117
     * Create article-page.
118 3
     *
119 3
     * @param string $articleUuid
120 3
     *
121
     * @return Response
122 3
     */
123 3
    public function postAction($articleUuid, Request $request)
124 3
    {
125
        $action = $request->get('action');
126 3
        $document = $this->documentManager->create(self::DOCUMENT_TYPE);
127
128
        $locale = $this->getRequestParameter($request, 'locale', true);
129
        $data = $request->request->all();
130
131 3
        $this->persistDocument($data, $document, $locale, $articleUuid);
132
        $this->handleActionParameter($action, $document->getParent(), $locale);
133 3
        $this->documentManager->flush();
134 3
135 3
        $context = new Context();
136
        $context->setSerializeNull(true);
137 3
        $context->setGroups(['defaultPage', 'defaultArticlePage', 'smallArticle']);
138 3
139 3
        return $this->handleView(
140 3
            $this->view($document)->setContext($context)
141 3
        );
142
    }
143
144
    /**
145
     * Update article-page.
146
     *
147
     * @param string $articleUuid
148
     * @param string $uuid
149
     *
150
     * @return Response
151
     */
152
    public function putAction($articleUuid, $uuid, Request $request)
153
    {
154
        $locale = $this->getRequestParameter($request, 'locale', true);
155 1
        $action = $request->get('action');
156
        $data = $request->request->all();
157 1
158
        $document = $this->documentManager->find(
159 1
            $uuid,
160 1
            $locale,
161 1
            [
162 1
                'load_ghost_content' => false,
163
                'load_shadow_content' => false,
164 1
            ]
165
        );
166
167
        $this->requestHashChecker->checkHash($request, $document, $document->getUuid());
168
169
        $this->persistDocument($data, $document, $locale, $articleUuid);
170 8
        $this->handleActionParameter($action, $document->getParent(), $locale);
171
        $this->documentManager->flush();
172 8
173
        $context = new Context();
174
        $context->setSerializeNull(true);
175
        $context->setGroups(['defaultPage', 'defaultArticlePage', 'smallArticle']);
176
177
        return $this->handleView(
178
            $this->view($document)->setContext($context)
179
        );
180
    }
181
182
    /**
183
     * Delete article-page.
184
     *
185
     * @param string $articleUuid
186
     * @param string $uuid
187 8
     *
188
     * @return Response
189 8
     */
190
    public function deleteAction($articleUuid, $uuid, Request $request)
191
    {
192
        $locale = $this->getRequestParameter($request, 'locale', true);
193 8
194 8
        $document = $this->documentManager->find($uuid, $locale);
195 3
        $this->documentManager->remove($document);
196
        $this->documentManager->flush();
197
198 8
        return $this->handleView($this->view(null));
199 8
    }
200 8
201
    /**
202
     * {@inheritdoc}
203 8
     */
204
    public function getSecurityContext()
205
    {
206 8
        return ArticleAdmin::SECURITY_CONTEXT;
207
    }
208 8
209
    /**
210 8
     * Persists the document using the given information.
211
     *
212
     * @param array $data
213
     * @param object $document
214 8
     * @param string $locale
215 8
     * @param string $articleUuid
216 8
     *
217
     * @throws InvalidFormException
218 8
     * @throws MissingParameterException
219
     * @throws ParameterNotAllowedException
220
     */
221
    private function persistDocument($data, $document, $locale, $articleUuid)
222
    {
223
        if (array_key_exists('title', $data)) {
224 8
            throw new ParameterNotAllowedException('title', get_class($document));
225
        }
226
227
        $article = $this->documentManager->find($articleUuid, $locale);
228
229
        if (!array_key_exists('template', $data)) {
230
            $data['template'] = $article->getStructureType();
231 8
        }
232
233 8
        $formType = $this->metadataFactory->getMetadataForAlias('article_page')->getFormType();
234
235
        $form = $this->formFactory->create(
236
            $formType,
237
            $document,
238
            [
239
                // disable csrf protection, since we can't produce a token, because the form is cached on the client
240
                'csrf_protection' => false,
241
            ]
242
        );
243
        $form->submit($data, false);
244
245
        $document->setParent($article);
246
247
        if (!$form->isValid()) {
248
            throw new InvalidFormException($form);
249
        }
250
251 8
        $this->documentManager->persist(
252
            $document,
253
            $locale,
254 8
            [
255
                'user' => $this->getUser()->getId(),
256
                'clear_missing_content' => false,
257
                'auto_name' => false,
258 8
                'auto_rename' => false,
259
            ]
260
        );
261
    }
262
263
    /**
264
     * Delegates actions by given actionParameter, which can be retrieved from the request.
265
     *
266
     * @param string $actionParameter
267
     * @param object $document
268
     * @param string $locale
269
     */
270
    private function handleActionParameter($actionParameter, $document, $locale)
271
    {
272
        switch ($actionParameter) {
273
            case 'publish':
274
                $this->documentManager->publish($document, $locale);
275
                break;
276
        }
277
    }
278
}
279