Completed
Pull Request — develop (#305)
by Wachter
15:11
created

ArticleController::postAction()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 10
cts 10
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 16
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * This file is part of Sulu.
5
 *
6
 * (c) MASSIVE ART WebServices 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\Controller\Annotations\Post;
15
use FOS\RestBundle\Routing\ClassResourceInterface;
16
use JMS\Serializer\SerializationContext;
17
use ONGR\ElasticsearchBundle\Service\Manager;
18
use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
19
use ONGR\ElasticsearchDSL\Query\FullText\MatchPhrasePrefixQuery;
20
use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery;
21
use ONGR\ElasticsearchDSL\Query\MatchAllQuery;
22
use ONGR\ElasticsearchDSL\Query\TermLevel\IdsQuery;
23
use ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery;
24
use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery;
25
use ONGR\ElasticsearchDSL\Sort\FieldSort;
26
use Prooph\Common\Event\ProophActionEventEmitter;
27
use Prooph\Common\Messaging\FQCNMessageFactory;
28
use Prooph\EventStore\ActionEventEmitterEventStore;
29
use Prooph\EventStore\Pdo\MySqlEventStore;
30
use Prooph\EventStore\Pdo\PersistenceStrategy\MySqlAggregateStreamStrategy;
31
use Prooph\EventStore\Pdo\Projection\MySqlProjectionManager;
32
use Prooph\EventStoreBusBridge\EventPublisher;
33
use Prooph\ServiceBus\CommandBus;
34
use Prooph\ServiceBus\EventBus;
35
use Prooph\ServiceBus\Plugin\Router\CommandRouter;
36
use Prooph\ServiceBus\Plugin\Router\EventRouter;
37
use Prooph\SnapshotStore\Pdo\PdoSnapshotStore;
38
use Ramsey\Uuid\Uuid;
39
use Sulu\Bundle\ArticleBundle\Admin\ArticleAdmin;
40
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument;
41
use Sulu\Bundle\ArticleBundle\ListBuilder\ElasticSearchFieldDescriptor;
42
use Sulu\Bundle\ArticleBundle\Metadata\ArticleViewDocumentIdTrait;
43
use Sulu\Bundle\ArticleBundle\Prooph\Infrastruture\ArticleRepository;
44
use Sulu\Bundle\ArticleBundle\Prooph\Model\Article;
45
use Sulu\Bundle\ArticleBundle\Prooph\Model\Command\DeleteArticleCommand;
46
use Sulu\Bundle\ArticleBundle\Prooph\Model\Command\PostArticleCommand;
47
use Sulu\Bundle\ArticleBundle\Prooph\Model\Command\PublishArticleCommand;
48
use Sulu\Bundle\ArticleBundle\Prooph\Model\Command\PutArticleCommand;
49
use Sulu\Bundle\ArticleBundle\Prooph\Model\Command\UnpublishArticleCommand;
50
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\CreateTranslation;
51
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\ModifyTranslationStructure;
52
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\PublishTranslation;
53
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\RemoveArticle;
54
use Sulu\Bundle\ArticleBundle\Prooph\Model\Event\UnpublishTranslation;
55
use Sulu\Bundle\ArticleBundle\Prooph\Model\Handler\DeleteArticleHandler;
56
use Sulu\Bundle\ArticleBundle\Prooph\Model\Handler\PostArticleHandler;
57
use Sulu\Bundle\ArticleBundle\Prooph\Model\Handler\PublishArticleHandler;
58
use Sulu\Bundle\ArticleBundle\Prooph\Model\Handler\PutArticleHandler;
59
use Sulu\Bundle\ArticleBundle\Prooph\Model\Handler\UnpublishArticleHandler;
60
use Sulu\Bundle\ArticleBundle\Prooph\Projection\ArticleDocumentProjector;
61
use Sulu\Bundle\ArticleBundle\Prooph\Projection\ArticleIndexProjector;
62
use Sulu\Component\Content\Mapper\ContentMapperInterface;
63
use Sulu\Component\DocumentManager\DocumentManagerInterface;
64
use Sulu\Component\DocumentManager\Metadata\BaseMetadataFactory;
65
use Sulu\Component\Rest\Exception\RestException;
66
use Sulu\Component\Rest\ListBuilder\ListRepresentation;
67
use Sulu\Component\Rest\RequestParametersTrait;
68
use Sulu\Component\Rest\RestController;
69
use Sulu\Component\Security\Authorization\PermissionTypes;
70
use Sulu\Component\Security\Authorization\SecurityCondition;
71
use Sulu\Component\Security\SecuredControllerInterface;
72
use Symfony\Component\HttpFoundation\Request;
73
use Symfony\Component\HttpFoundation\Response;
74
75
/**
76
 * Provides API for articles.
77
 */
78
class ArticleController extends RestController implements ClassResourceInterface, SecuredControllerInterface
79
{
80
    const DOCUMENT_TYPE = 'article';
81
82
    use RequestParametersTrait;
83
    use ArticleViewDocumentIdTrait;
84
85
    /**
86
     * Create field-descriptor array.
87
     *
88
     * @return ElasticSearchFieldDescriptor[]
89
     */
90
    private function getFieldDescriptors()
91
    {
92
        return [
93
            'uuid' => new ElasticSearchFieldDescriptor('id', null, 'public.id', false, false, 'string', '', '', false),
94
            'typeTranslation' => new ElasticSearchFieldDescriptor(
95
                'typeTranslation',
96
                'typeTranslation.raw',
97
                'sulu_article.list.type',
98 12
                !$this->getParameter('sulu_article.display_tab_all'),
99
                false
100 12
            ),
101
            'title' => new ElasticSearchFieldDescriptor('title', 'title.raw', 'public.title', false, true),
102 12
            'creatorFullName' => new ElasticSearchFieldDescriptor(
103
                'creatorFullName',
104
                'creatorFullName.raw',
105 12
                'sulu_article.list.creator',
106 12
                true,
107 12
                false
108
            ),
109 12
            'changerFullName' => new ElasticSearchFieldDescriptor(
110 12
                'changerFullName',
111
                'changerFullName.raw',
112 12
                'sulu_article.list.changer',
113 12
                false,
114
                false
115
            ),
116 12
            'authorFullName' => new ElasticSearchFieldDescriptor(
117 1
                'authorFullName',
118 1
                'authorFullName.raw',
119
                'sulu_article.author',
120
                false,
121 12
                false
122 12
            ),
123
            'created' => new ElasticSearchFieldDescriptor('created', null, 'public.created', true, false, 'datetime'),
124 2
            'changed' => new ElasticSearchFieldDescriptor('changed', null, 'public.changed', false, false, 'datetime'),
125
            'authored' => new ElasticSearchFieldDescriptor('authored', null, 'sulu_article.authored', false, false, 'date'),
126
        ];
127 12
    }
128 10
129
    /**
130
     * Returns fields.
131 12
     *
132 1
     * @return Response
133 1
     */
134 1
    public function cgetFieldsAction()
135 1
    {
136 1
        $fieldDescriptors = $this->getFieldDescriptors();
137
138
        return $this->handleView($this->view(array_values($fieldDescriptors)));
0 ignored issues
show
Documentation introduced by
$this->view(array_values($fieldDescriptors)) is of type this<Sulu\Bundle\Article...ller\ArticleController>, but the function expects a object<FOS\RestBundle\View\View>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
139 12
    }
140 1
141
    /**
142
     * Returns list of articles.
143 12
     *
144
     * @param Request $request
145
     *
146
     * @return Response
147 12
     */
148
    public function cgetAction(Request $request)
149 12
    {
150 1
        $locale = $this->getRequestParameter($request, 'locale', true);
151 1
152
        $restHelper = $this->get('sulu_core.list_rest_helper');
153
154
        /** @var Manager $manager */
155 12
        $manager = $this->get('es.manager.default');
156 12
        $repository = $manager->getRepository($this->get('sulu_article.view_document.factory')->getClass('article'));
157
        $search = $repository->createSearch();
158 12
159 12
        $limit = (int) $restHelper->getLimit();
160 10
        $page = (int) $restHelper->getPage();
161 1
162
        if (null !== $locale) {
163 12
            $search->addQuery(new TermQuery('locale', $locale));
164
        }
165
166
        if (count($ids = array_filter(explode(',', $request->get('ids', ''))))) {
167 12
            $search->addQuery(new IdsQuery($this->getViewDocumentIds($ids, $locale)));
168 1
            $limit = count($ids);
169 1
        }
170
171
        if (!empty($searchPattern = $restHelper->getSearchPattern())
172 12
            && 0 < count($searchFields = $restHelper->getSearchFields())
173 12
        ) {
174 12
            $boolQuery = new BoolQuery();
175 12
            foreach ($searchFields as $searchField) {
176 12
                $boolQuery->add(new MatchPhrasePrefixQuery($searchField, $searchPattern), BoolQuery::SHOULD);
177 12
            }
178 12
            $search->addQuery($boolQuery);
179 12
        }
180 12
181 12
        if (null !== ($type = $request->get('type'))) {
182
            $search->addQuery(new TermQuery('type', $type));
183
        }
184
185
        if ($contactId = $request->get('contactId')) {
186
            $boolQuery = new BoolQuery();
187
            $boolQuery->add(new MatchQuery('changer_contact_id', $contactId), BoolQuery::SHOULD);
188
            $boolQuery->add(new MatchQuery('creator_contact_id', $contactId), BoolQuery::SHOULD);
189
            $boolQuery->add(new MatchQuery('author_id', $contactId), BoolQuery::SHOULD);
190
            $search->addQuery($boolQuery);
191
        }
192
193
        if ($categoryId = $request->get('categoryId')) {
194
            $search->addQuery(new TermQuery('excerpt.categories.id', $categoryId), BoolQuery::MUST);
195 9
        }
196
197 9
        if ($tagId = $request->get('tagId')) {
198 9
            $search->addQuery(new TermQuery('excerpt.tags.id', $tagId), BoolQuery::MUST);
199 9
        }
200 9
201
        if ($pageId = $request->get('pageId')) {
202 9
            $search->addQuery(new TermQuery('parent_page_uuid', $pageId), BoolQuery::MUST);
203
        }
204
205
        if ($workflowStage = $request->get('workflowStage')) {
206
            $search->addQuery(new TermQuery('published_state', 'published' === $workflowStage), BoolQuery::MUST);
0 ignored issues
show
Documentation introduced by
'published' === $workflowStage is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
207 9
        }
208 9
209 9
        $authoredFrom = $request->get('authoredFrom');
210 9
        $authoredTo = $request->get('authoredTo');
211 9
        if ($authoredFrom || $authoredTo) {
212
            $search->addQuery($this->getRangeQuery('authored', $authoredFrom, $authoredTo), BoolQuery::MUST);
213
        }
214
215
        if (null === $search->getQueries()) {
216
            $search->addQuery(new MatchAllQuery());
217
        }
218
219
        if (null !== $restHelper->getSortColumn() &&
220
            $sortField = $this->getSortFieldName($restHelper->getSortColumn())
221
        ) {
222
            $search->addSort(
223 51
                new FieldSort($sortField, $restHelper->getSortOrder())
224
            );
225 51
        }
226 51
227 51
        $search->setSize($limit);
228 51
        $search->setFrom(($page - 1) * $limit);
229
230 51
        $result = [];
231 51
        $searchResult = $repository->findDocuments($search);
232 51
        foreach ($searchResult as $document) {
233
            if (false !== ($index = array_search($document->getUuid(), $ids))) {
234 51
                $result[$index] = $document;
235 51
            } else {
236 51
                $result[] = $document;
237 51
            }
238 51
        }
239
240
        if (count($ids)) {
241
            ksort($result);
242
            $result = array_values($result);
243
        }
244
245
        return $this->handleView(
246
            $this->view(
0 ignored issues
show
Documentation introduced by
$this->view(new \Sulu\Co...searchResult->count())) is of type this<Sulu\Bundle\Article...ller\ArticleController>, but the function expects a object<FOS\RestBundle\View\View>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
247
                new ListRepresentation(
248
                    $result,
249
                    'articles',
250
                    'get_articles',
251 9
                    $request->query->all(),
252
                    $page,
253 9
                    $limit,
254 9
                    $searchResult->count()
255 9
                )
256
            )
257 9
        );
258 9
    }
259 9
260
    /**
261 9
     * Returns query to filter by given range.
262
     *
263
     * @param string $field
264
     * @param string $from
265
     * @param string $to
266 9
     *
267
     * @return RangeQuery
268 9
     */
269 9
    private function getRangeQuery($field, $from, $to)
270 9
    {
271
        return new RangeQuery($field, array_filter(['gte' => $from, 'lte' => $to]));
272 9
    }
273 9
274 9
    /**
275 9
     * Returns single article.
276 9
     *
277
     * @param string  $uuid
278
     * @param Request $request
279
     *
280
     * @return Response
281
     */
282
    public function getAction($uuid, Request $request)
283
    {
284
        $locale = $this->getRequestParameter($request, 'locale', true);
285
        $document = $this->getDocumentManager()->find(
286
            $uuid,
287
            $locale,
288 1
            [
289
                'load_ghost_content' => true,
290 1
                'load_shadow_content' => false,
291
            ]
292 1
        );
293 1
294 1
        return $this->handleView(
295 1
            $this->view($document)->setSerializationContext(
0 ignored issues
show
Bug introduced by
The method setSerializationContext() does not seem to exist on object<Sulu\Bundle\Artic...ller\ArticleController>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
296 1
                SerializationContext::create()
297
                    ->setSerializeNull(true)
298
                    ->setGroups(['defaultPage', 'defaultArticle', 'smallArticlePage'])
299 1
            )
300
        );
301
    }
302
303
    /**
304
     * Create article.
305
     *
306
     * @param Request $request
307
     *
308
     * @return Response
309 1
     */
310
    public function postAction(Request $request)
311 1
    {
312 1
        $id = Uuid::uuid4()->toString();
313 1
314 1
        $locale = $this->getRequestParameter($request, 'locale', true);
315
        $this->getCommandBus()->dispatch(
316 1
            new PostArticleCommand(
317
                [
318
                    'id' => $id,
319
                    'locale' => $locale,
320
                    'userId' => $this->getUser()->getId(),
321
                    'requestData' => $request->request->all(),
322
                ]
323
            )
324
        );
325
326
        $this->handleActionParameter($id, $request->get('action'), $locale);
327
328
        $document = $this->getDocumentManager()->find($id, $locale);
329 2
330
        return $this->handleView(
331
            $this->view($document)->setSerializationContext(
0 ignored issues
show
Bug introduced by
The method setSerializationContext() does not seem to exist on object<Sulu\Bundle\Artic...ller\ArticleController>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
332 2
                SerializationContext::create()
333 2
                    ->setSerializeNull(true)
334
                    ->setGroups(['defaultPage', 'defaultArticle', 'smallArticlePage'])
335
            )
336 2
        );
337 2
    }
338 2
339
    /**
340
     * Update articles.
341
     *
342 2
     * @param Request $request
343
     * @param string  $uuid
344
     *
345
     * @return Response
346
     */
347
    public function putAction(Request $request, $uuid)
348
    {
349 2
        $locale = $this->getRequestParameter($request, 'locale', true);
350
        $action = $request->get('action');
351
352
        $document = $this->getDocumentManager()->find(
353
            $uuid,
354 2
            $locale,
355 1
            [
356 1
                'load_ghost_content' => false,
357
                'load_shadow_content' => false,
358 1
            ]
359 1
        );
360 1
361 1
        $this->get('sulu_hash.request_hash_checker')->checkHash($request, $document, $document->getUuid());
362 1
363
        $this->getCommandBus()->dispatch(
364
            new PutArticleCommand(
365
                [
366 1
                    'id' => $uuid,
367
                    'locale' => $locale,
368 1
                    'userId' => $this->getUser()->getId(),
369 1
                    'requestData' => $request->request->all(),
370 1
                ]
371
            )
372
        );
373
374
        $this->handleActionParameter($uuid, $action, $locale);
375
376
        $document = $this->getDocumentManager()->find($uuid, $locale);
377
378 1
        return $this->handleView(
379 1
            $this->view($document)->setSerializationContext(
0 ignored issues
show
Bug introduced by
The method setSerializationContext() does not seem to exist on object<Sulu\Bundle\Artic...ller\ArticleController>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
380 1
                SerializationContext::create()
381 1
                    ->setSerializeNull(true)
382
                    ->setGroups(['defaultPage', 'defaultArticle', 'smallArticlePage'])
383 1
            )
384 1
        );
385
    }
386
387
    /**
388
     * Deletes multiple documents.
389
     *
390 2
     * @param Request $request
391 2
     *
392 2
     * @return Response
393 2
     */
394 2
    public function cdeleteAction(Request $request)
395
    {
396
        $ids = array_filter(explode(',', $request->get('ids', '')));
397
398
        foreach ($ids as $id) {
399
            $this->getCommandBus()->dispatch(
400 2
                new DeleteArticleCommand(
401
                    [
402
                        'id' => $id,
403
                        'userId' => $this->getUser()->getId(),
404
                    ]
405
                )
406
            );
407
        }
408
409 1
        return $this->handleView($this->view(null));
0 ignored issues
show
Documentation introduced by
$this->view(null) is of type this<Sulu\Bundle\Article...ller\ArticleController>, but the function expects a object<FOS\RestBundle\View\View>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
410
    }
411 1
412
    /**
413 1
     * Deletes multiple documents.
414 1
     *
415 1
     * @param string $id
416
     *
417 1
     * @return Response
418
     */
419
    public function deleteAction($id)
420
    {
421
        $this->getCommandBus()->dispatch(
422 52
            new DeleteArticleCommand(
423
                [
424 52
                    'id' => $id,
425
                    'userId' => $this->getUser()->getId(),
426
                ]
427
            )
428
        );
429
430
        return $this->handleView($this->view(null));
0 ignored issues
show
Documentation introduced by
$this->view(null) is of type this<Sulu\Bundle\Article...ller\ArticleController>, but the function expects a object<FOS\RestBundle\View\View>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
431
    }
432
433
    /**
434
     * Trigger a action for given article specified over get-action parameter.
435
     *
436
     * @Post("/articles/{uuid}")
437 51
     *
438
     * @param string $uuid
439 51
     * @param Request $request
440 51
     *
441 51
     * @return Response
442
     */
443
    public function postTriggerAction($uuid, Request $request)
444 51
    {
445
        // extract parameter
446
        $action = $this->getRequestParameter($request, 'action', true);
447 51
        $locale = $this->getRequestParameter($request, 'locale', true);
448
449 51
        // prepare vars
450
        $view = null;
451
        $data = null;
452
        $userId = $this->getUser()->getId();
453 51
454
        try {
455
            switch ($action) {
456
                case 'unpublish':
457 51
                    $this->getCommandBus()->dispatch(
458 51
                        new UnpublishArticleCommand(
459 51
                            [
460
                                'id' => $uuid,
461 51
                                'locale' => $locale,
462
                                'userId' => $this->getUser()->getId(),
463
                            ]
464
                        )
465 51
                    );
466
467
                    $data = $this->getDocumentManager()->find($uuid, $locale);
468
469
                    break;
470
                case 'remove-draft':
471
                    $data = $this->getDocumentManager()->find($uuid, $locale);
472 51
                    $this->getDocumentManager()->removeDraft($data, $locale);
473
                    $this->getDocumentManager()->flush();
474 51
475
                    break;
476
                case 'copy-locale':
477
                    $destLocales = $this->getRequestParameter($request, 'dest', true);
478
                    $destLocales = explode(',', $destLocales);
479
480 1
                    $securityChecker = $this->get('sulu_security.security_checker');
481
                    foreach ($destLocales as $destLocale) {
482 1
                        $securityChecker->checkPermission(
483
                            new SecurityCondition($this->getSecurityContext(), $destLocale),
484
                            PermissionTypes::EDIT
485
                        );
486
                    }
487
488
                    $this->getMapper()->copyLanguage($uuid, $userId, null, $locale, $destLocales);
489
490
                    $data = $this->getDocumentManager()->find($uuid, $locale);
491
492 51
                    break;
493
                case 'copy':
494
                    /** @var ArticleDocument $document */
495 51
                    $document = $this->getDocumentManager()->find($uuid, $locale);
496 17
                    $copiedPath = $this->getDocumentManager()->copy($document, dirname($document->getPath()));
497 17
                    $this->getDocumentManager()->flush();
498
499 51
                    $data = $this->getDocumentManager()->find($copiedPath, $locale);
500
501
                    break;
502
                case 'order':
503
                    $this->orderPages($this->getRequestParameter($request, 'pages', true), $locale);
0 ignored issues
show
Documentation introduced by
$this->getRequestParamet...request, 'pages', true) is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
504
                    $this->getDocumentManager()->flush();
505
                    $this->getDocumentManager()->clear();
506
507
                    $data = $this->getDocumentManager()->find($uuid, $locale);
508 1
509
                    break;
510 1
                default:
511 1
                    throw new RestException('Unrecognized action: ' . $action);
512 1
            }
513 1
514
            // prepare view
515
            $view = $this->view($data);
516 1
            $view->setSerializationContext(
0 ignored issues
show
Bug introduced by
The method setSerializationContext() does not seem to exist on object<Sulu\Bundle\Artic...ller\ArticleController>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
517
                SerializationContext::create()
518
                    ->setSerializeNull(true)
519
                    ->setGroups(['defaultPage', 'defaultArticle', 'smallArticlePage'])
520
            );
521
        } catch (RestException $exc) {
522
            $view = $this->view($exc->toArray(), 400);
523
        }
524
525
        return $this->handleView($view);
0 ignored issues
show
Documentation introduced by
$view is of type this<Sulu\Bundle\Article...ller\ArticleController>, but the function expects a object<FOS\RestBundle\View\View>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
526
    }
527
528
    /**
529
     * Ordering given pages.
530
     *
531
     * @param array $pages
532
     * @param string $locale
533
     */
534
    private function orderPages(array $pages, $locale)
535
    {
536
        $documentManager = $this->getDocumentManager();
537
538
        for ($i = 0; $i < count($pages); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
539
            $document = $documentManager->find($pages[$i], $locale);
540
            $documentManager->reorder($document, null);
541
        }
542
    }
543
544
    /**
545
     * {@inheritdoc}
546
     */
547
    public function getSecurityContext()
548
    {
549
        return ArticleAdmin::SECURITY_CONTEXT;
550
    }
551
552
    /**
553
     * Returns document-manager.
554
     *
555
     * @return DocumentManagerInterface
556
     */
557
    protected function getDocumentManager()
558
    {
559
        return $this->get('sulu_document_manager.document_manager');
560
    }
561
562
    /**
563
     * @return ContentMapperInterface
564
     */
565
    protected function getMapper()
566
    {
567
        return $this->get('sulu.content.mapper');
568
    }
569
570
    private function handleActionParameter(string $id, ?string $action, string $locale)
571
    {
572
        if ($action === 'publish') {
573
            $this->getCommandBus()->dispatch(
574
                new PublishArticleCommand(
575
                    [
576
                        'id' => $id,
577
                        'locale' => $locale,
578
                        'userId' => $this->getUser()->getId(),
579
                    ]
580
                )
581
            );
582
        }
583
    }
584
585
    /**
586
     * @param string $sortBy
587
     *
588
     * @return null|string
589
     */
590
    private function getSortFieldName($sortBy)
591
    {
592
        $sortBy = $this->uncamelize($sortBy);
593
        $fieldDescriptors = $this->getFieldDescriptors();
594
595
        if (array_key_exists($sortBy, $fieldDescriptors)) {
596
            return $fieldDescriptors[$sortBy]->getSortField();
597
        }
598
599
        return null;
600
    }
601
602
    /**
603
     * Converts camel case string into normalized string with underscore.
604
     *
605
     * @param string $camel
606
     *
607
     * @return string
608
     */
609
    private function uncamelize($camel)
610
    {
611
        $camel = preg_replace(
612
            '/(?!^)[[:upper:]][[:lower:]]/',
613
            '$0',
614
            preg_replace('/(?!^)[[:upper:]]+/', '_$0', $camel)
615
        );
616
617
        return strtolower($camel);
618
    }
619
620
    /**
621
     * @return BaseMetadataFactory
622
     */
623
    protected function getMetadataFactory()
624
    {
625
        return $this->get('sulu_document_manager.metadata_factory.base');
626
    }
627
628
    protected function getCommandBus()
629
    {
630
        $pdo = new \PDO('mysql:dbname=su_article_prooph;host=127.0.0.1', 'root', '');
631
        $eventStore = new MySqlEventStore(new FQCNMessageFactory(), $pdo, new MySqlAggregateStreamStrategy());
632
        $eventEmitter = new ProophActionEventEmitter();
633
        $eventStore = new ActionEventEmitterEventStore($eventStore, $eventEmitter);
634
635
        $eventBus = new EventBus($eventEmitter);
636
        $eventPublisher = new EventPublisher($eventBus);
637
        $eventPublisher->attachToEventStore($eventStore);
638
639
        $pdoSnapshotStore = new PdoSnapshotStore($pdo);
640
        $userRepository = new ArticleRepository(Article::class, $eventStore, $pdoSnapshotStore);
641
642
        $projectionManager = new MySqlProjectionManager($eventStore, $pdo);
0 ignored issues
show
Unused Code introduced by
$projectionManager 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...
643
644
        $structureFactory = $this->get('sulu_content.structure.factory');
645
        $routeGenerator = $this->get('sulu_route.chain_generator');
646
        $conflictResolver = $this->get('sulu_route.manager.conflict_resolver.auto_increment');
647
648
        $commandBus = new CommandBus();
649
        $router = new CommandRouter();
650
        $router->route(PostArticleCommand::class)->to(new PostArticleHandler($userRepository, $structureFactory, $routeGenerator, $conflictResolver));
651
        $router->route(PublishArticleCommand::class)->to(new PublishArticleHandler($userRepository));
652
        $router->route(UnpublishArticleCommand::class)->to(new UnpublishArticleHandler($userRepository));
653
        $router->route(PutArticleCommand::class)->to(new PutArticleHandler($userRepository, $structureFactory));
654
        $router->route(DeleteArticleCommand::class)->to(new DeleteArticleHandler($userRepository));
655
        $router->attachToMessageBus($commandBus);
656
657
        $documentProjector = new ArticleDocumentProjector(
658
            $this->getDocumentManager(),
659
            $this->getMetadataFactory(),
660
            $this->get('form.factory')
661
        );
662
663
        $indexProjector = new ArticleIndexProjector(
664
            $this->getDocumentManager(),
665
            $this->get('sulu_article.elastic_search.article_indexer'),
666
            $this->get('sulu_article.elastic_search.article_live_indexer')
667
        );
668
669
        $eventRouter = new EventRouter();
670
        $eventRouter->route(CreateTranslation::class)->to([$documentProjector, 'onCreateTranslation']);
671
        $eventRouter->route(CreateTranslation::class)->to([$indexProjector, 'onCreateTranslation']);
672
        $eventRouter->route(PublishTranslation::class)->to([$documentProjector, 'onPublishTranslation']);
673
        $eventRouter->route(PublishTranslation::class)->to([$indexProjector, 'onPublishTranslation']);
674
        $eventRouter->route(UnpublishTranslation::class)->to([$documentProjector, 'onUnpublishTranslation']);
675
        $eventRouter->route(UnpublishTranslation::class)->to([$indexProjector, 'onUnpublishTranslation']);
676
        $eventRouter->route(ModifyTranslationStructure::class)->to([$documentProjector, 'onModifyTranslationStructure']);
677
        $eventRouter->route(ModifyTranslationStructure::class)->to([$indexProjector, 'onModifyTranslationStructure']);
678
        $eventRouter->route(RemoveArticle::class)->to([$documentProjector, 'onRemoveArticle']);
679
        $eventRouter->route(RemoveArticle::class)->to([$indexProjector, 'onRemoveArticle']);
680
        $eventRouter->attachToMessageBus($eventBus);
681
682
        return $commandBus;
683
    }
684
}
685