Completed
Push — master ( 3ef484...ea5778 )
by Paweł
08:46
created

ContentListItemController::batchUpdateAction()   C

Complexity

Conditions 11
Paths 13

Size

Total Lines 60
Code Lines 41

Duplication

Lines 13
Ratio 21.67 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
dl 13
loc 60
ccs 0
cts 0
cp 0
rs 6.2926
c 0
b 0
f 0
cc 11
eloc 41
nc 13
nop 2
crap 132

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Core Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\CoreBundle\Controller;
16
17
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
18
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
19
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
20
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
21
use SWP\Bundle\ContentListBundle\Form\Type\ContentListItemsType;
22
use SWP\Bundle\CoreBundle\Form\Type\ContentListItemType;
23
use SWP\Bundle\CoreBundle\Model\ContentListInterface;
24
use SWP\Bundle\CoreBundle\Model\ContentListItemInterface;
25
use SWP\Component\Common\Criteria\Criteria;
26
use SWP\Component\Common\Pagination\PaginationData;
27
use SWP\Component\Common\Response\ResourcesListResponse;
28
use SWP\Component\Common\Response\ResponseContext;
29
use SWP\Component\Common\Response\SingleResourceResponse;
30
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
33
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
34
35
class ContentListItemController extends Controller
36
{
37
    /**
38
     * List all items of content list.
39
     *
40
     * @ApiDoc(
41
     *     resource=true,
42
     *     description="Lists content list items",
43
     *     statusCodes={
44
     *         200="Returned on success.",
45
     *         404="Content list item not found.",
46
     *         500="Unexpected error."
47
     *     },
48
     *     filters={
49
     *         {"name"="sticky", "dataType"="boolean", "pattern"="true|false"},
50
     *         {"name"="sorting", "dataType"="string", "pattern"="[updatedAt]=asc|desc"}
51 5
     *     }
52
     * )
53 5
     * @Route("/api/{version}/content/lists/{id}/items/", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_core_list_items", requirements={"id"="\d+"})
54
     * @Method("GET")
55 5
     */
56 5
    public function listAction(Request $request, $id)
57 5
    {
58 5
        $repository = $this->get('swp.repository.content_list_item');
59
60 5
        $items = $repository->getPaginatedByCriteria(
61 5
            new Criteria([
62
                'contentList' => $id,
63
                'sticky' => $request->query->get('sticky', ''),
64 5
            ]),
65
            $request->query->get('sorting', ['sticky' => 'desc', 'createdAt' => 'desc']),
66
            new PaginationData($request)
67
        );
68
69
        return new ResourcesListResponse($items);
70
    }
71
72
    /**
73
     * @ApiDoc(
74
     *     resource=true,
75
     *     description="Get single content list item",
76
     *     statusCodes={
77
     *         200="Returned on success."
78
     *     }
79
     * )
80 4
     * @Route("/api/{version}/content/lists/{listId}/items/{id}", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_core_show_lists_item", requirements={"id"="\d+"})
81
     * @Method("GET")
82 4
     *
83
     * @Cache(expires="10 minutes", public=true)
84
     */
85
    public function getAction($listId, $id)
86
    {
87
        return new SingleResourceResponse($this->findOr404($listId, $id));
88
    }
89
90
    /**
91
     * @ApiDoc(
92
     *     resource=true,
93
     *     description="Update single content list item",
94
     *     statusCodes={
95
     *         200="Returned on success.",
96
     *         400="Returned when not valid data.",
97
     *         404="Returned when not found."
98
     *     },
99 1
     *     input="SWP\Bundle\CoreBundle\Form\Type\ContentListItemType"
100
     * )
101 1
     * @Route("/api/{version}/content/lists/{listId}/items/{id}", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_core_update_lists_item", requirements={"id"="\d+", "listId"="\d+"})
102 1
     * @Method("PATCH")
103 1
     */
104 1
    public function updateAction(Request $request, $listId, $id)
105
    {
106 1
        $objectManager = $this->get('swp.object_manager.content_list_item');
107
        $contentListItem = $this->findOr404($listId, $id);
108
        $form = $this->createForm(
109 1
            ContentListItemType::class,
110
            $contentListItem,
111 1
            ['method' => $request->getMethod()]
112 1
        );
113
114 1
        $form->handleRequest($request);
115
116
        if ($form->isValid()) {
117
            $objectManager->flush();
118
119
            return new SingleResourceResponse($contentListItem);
120 4
        }
121
122 4
        return new SingleResourceResponse($form, new ResponseContext(400));
123 4
    }
124 4
125
    /**
126
     * Tips:
127 4
     *  - position "-1" will place element at end of list.
128 2
     *  - make sure that "updated_at" value is filled with value fetched from list.
129
     *
130
     * Possible actions: move, add, delete
131 2
     *
132
     * @ApiDoc(
133
     *     resource=true,
134
     *     description="Update many content list items",
135
     *     statusCodes={
136
     *         200="Returned on success.",
137
     *         400="Returned when not valid data.",
138
     *         404="Returned when not found."
139
     *     },
140
     *     input="SWP\Bundle\ContentListBundle\Form\Type\ContentListItemsType"
141
     * )
142
     * @Route("/api/{version}/content/lists/{listId}/items/", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_core_batch_update_lists_item", requirements={"listId"="\d+"})
143
     * @Method("PATCH")
144
     */
145
    public function batchUpdateAction(Request $request, $listId)
146
    {
147
        /** @var ContentListInterface $list */
148
        $list = $this->get('swp.repository.content_list')->findOneBy([
149
            'id' => $listId,
150
        ]);
151
152
        if (null === $list) {
153
            throw new NotFoundHttpException(sprintf('Content list with id "%s" was not found.', $list));
154
        }
155
156
        $objectManager = $this->get('swp.object_manager.content_list_item');
157
        $form = $this->createForm(ContentListItemsType::class, [], ['method' => $request->getMethod()]);
158
159
        $form->handleRequest($request);
160
        if ($form->isValid()) {
161
            $data = $form->getData();
162
            $updatedAt = \DateTime::createFromFormat(\DateTime::RFC3339, $data['updated_at'], new \DateTimeZone('UTC'));
163
            $updatedAt->setTimezone(new \DateTimeZone('UTC'));
164
            if ($updatedAt != $list->getUpdatedAt()) {
165
                throw new ConflictHttpException('List was already updated');
166
            }
167
168
            foreach ($data['items'] as $item) {
169
                if (!is_array($item)) {
170
                    continue;
171
                }
172
173
                if (!isset($item['position']) || !is_numeric($item['position'])) {
174
                    $item['position'] = 0;
175
                }
176
177
                switch ($item['action']) {
178 View Code Duplication
                    case 'move':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
                        /** @var ContentListItemInterface $contentListItem */
180
                        $contentListItem = $this->findByContentOr404($list, $item['content_id']);
181
                        $contentListItem->setPosition($item['position']);
182
                        $list->setUpdatedAt(new \DateTime('now'));
183
                        $objectManager->flush();
184
                        break;
185
                    case 'add':
186
                        $object = $this->get('swp.repository.article')->findOneById($item['content_id']);
187
                        $contentListItem = $this->get('swp.service.content_list')
188
                            ->addArticleToContentList($list, $object, $item['position']);
189
                        $objectManager->persist($contentListItem);
190
                        $list->setUpdatedAt(new \DateTime('now'));
191
                        $objectManager->flush();
192
                        break;
193 View Code Duplication
                    case 'delete':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
                        $contentListItem = $this->findByContentOr404($list, $item['content_id']);
195
                        $objectManager->remove($contentListItem);
196
                        $list->setUpdatedAt(new \DateTime('now'));
197
                        $objectManager->flush();
198
                        break;
199
                }
200
            }
201
202
            return new SingleResourceResponse($list, new ResponseContext(201));
203
        }
204
    }
205
206 View Code Duplication
    private function findByContentOr404($listId, $contentId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
207
    {
208
        $listItem = $this->get('swp.repository.content_list_item')->findOneBy([
209
            'contentList' => $listId,
210
            'content' => $contentId,
211
        ]);
212
213
        if (null === $listItem) {
214
            throw new NotFoundHttpException(sprintf('Content list item with content_id "%s" was not found.', $contentId));
215
        }
216
217
        return $listItem;
218
    }
219
220 View Code Duplication
    private function findOr404($listId, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
    {
222
        $listItem = $this->get('swp.repository.content_list_item')->findOneBy([
223
            'contentList' => $listId,
224
            'id' => $id,
225
        ]);
226
227
        if (null === $listItem) {
228
            throw new NotFoundHttpException(sprintf('Content list item with id "%s" was not found.', $id));
229
        }
230
231
        return $listItem;
232
    }
233
}
234