AbstractController::createNotFoundResponse()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * (c) Lukasz D. Tulikowski <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace App\Controller;
13
14
use App\Interfaces\RepositoryInterface;
15
use App\Repository\AbstractRepository;
16
use App\Resource\PaginationResource;
17
use App\Traits\ControllerTrait;
18
use Doctrine\Common\Inflector\Inflector;
19
use Doctrine\Common\Persistence\ObjectRepository;
20
use Doctrine\ORM\EntityManagerInterface;
21
use Doctrine\ORM\Query;
22
use JMS\Serializer\SerializationContext;
23
use Pagerfanta\Adapter\DoctrineORMAdapter;
24
use Pagerfanta\Pagerfanta;
25
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
26
use Symfony\Component\Form\FormInterface;
27
use Symfony\Component\HttpFoundation\JsonResponse;
28
use Symfony\Component\HttpFoundation\Request;
29
use Symfony\Component\HttpFoundation\Response;
30
31
abstract class AbstractController extends Controller
32
{
33
    use ControllerTrait;
34
35
    public const DELETED = ['success' => 'Deleted.'];
36
    public const NOT_FOUND = ['error' => 'Resource not found.'];
37
    public const GENERAL_ERROR = ['error' => 'Something went wrong.'];
38
39
    /**
40
     * @var string
41
     */
42
    protected $entity;
43
44
    /**
45
     * @var EntityManagerInterface
46
     */
47
    protected $entityManager;
48
49
    /**
50
     * @var AbstractRepository
51
     */
52
    protected $repository;
53
54
    /**
55
     * BaseController constructor.
56
     *
57
     * @param string $entity
58
     */
59 51
    public function __construct(string $entity)
60
    {
61 51
        $this->entity = $entity;
62 51
    }
63
64
    /**
65
     * @required
66
     */
67 51
    public function setManager()
68
    {
69 51
        $this->entityManager = $this->getDoctrine()->getManager();
70 51
    }
71
72
    /**
73
     * @return ObjectRepository
74
     */
75 8
    public function getRepository()
76
    {
77 8
        return $this->entityManager->getRepository($this->entity);
78
    }
79
80
    /**
81
     * @param Pagerfanta $paginator
82
     *
83
     * @return JsonResponse
84
     */
85 8
    public function createCollectionResponse(PagerFanta $paginator): JsonResponse
86
    {
87 8
        $this->responseCreator->setCollectionData(
88 8
            $this->serializer->toArray(
89 8
                $paginator->getIterator()->getArrayCopy(),
0 ignored issues
show
Bug introduced by
The method getArrayCopy() does not exist on Traversable. It seems like you code against a sub-type of Traversable such as Nette\Utils\Finder or Nette\Utils\Html or Nette\Utils\ArrayList or ArrayObject or Nette\Iterators\CachingIterator or ArrayIterator or Symfony\Component\Proper...ss\PropertyPathIterator or RecursiveArrayIterator or Symfony\Component\Proper...ss\PropertyPathIterator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
                $paginator->getIterator()->/** @scrutinizer ignore-call */ getArrayCopy(),
Loading history...
90 8
                $this->serializationService->createBaseOnRequest()
91
            ),
92 8
            (new PaginationResource())->createFromPagerfanta($paginator)
93
        );
94
95 8
        return $this->responseCreator->getResponse(Response::HTTP_OK, $this->getEntityResponseField());
96
    }
97
98
    /**
99
     * @param $resource
100
     * @param int $status
101
     * @param SerializationContext|null $context
102
     *
103
     * @return JsonResponse
104
     */
105 12
    public function createResourceResponse($resource, $status = Response::HTTP_OK, SerializationContext $context = null): JsonResponse
106
    {
107 12
        if (!$context) {
108 12
            $context = $this->serializationService->createBaseOnRequest();
109
        }
110
111 12
        $this->responseCreator->setData($this->serializer->toArray($resource, $context));
112
113 12
        return $this->responseCreator->getResponse($status);
114
    }
115
116
    /**
117
     * @param array $data
118
     * @param int $status
119
     *
120
     * @return JsonResponse
121
     */
122 4
    public function createSuccessfulApiResponse(array $data = [], $status = Response::HTTP_OK): JsonResponse
123
    {
124 4
        $this->responseCreator->setData($data);
125
126 4
        return $this->responseCreator->getResponse($status, $this->getEntityResponseField());
127
    }
128
129
    /**
130
     * @return JsonResponse
131
     */
132 12
    public function createNotFoundResponse(): JsonResponse
133
    {
134 12
        $this->responseCreator->setData(self::NOT_FOUND);
135
136 12
        return $this->responseCreator->getResponse(Response::HTTP_NOT_FOUND, $this->getEntityResponseField());
137
    }
138
139
    /**
140
     * @param \Exception $exception
141
     *
142
     * @return JsonResponse
143
     */
144
    public function createGenericErrorResponse(\Exception $exception): JsonResponse
145
    {
146
        $this->responseCreator->setData(
147
            array_merge(self::GENERAL_ERROR, ['details' => $exception->getMessage()])
148
        );
149
150
        return $this->responseCreator->getResponse(
151
            Response::HTTP_INTERNAL_SERVER_ERROR,
152
            $this->getEntityResponseField()
153
        );
154
    }
155
156
    /**
157
     * @param Request $request
158
     * @param Query $query
159
     *
160
     * @return Pagerfanta
161
     */
162 8
    public function createPaginator(Request $request, Query $query): Pagerfanta
163
    {
164
        //  Construct the doctrine adapter using the query.
165 8
        $adapter = new DoctrineORMAdapter($query);
166 8
        $paginator = new Pagerfanta($adapter);
167
168 8
        $limit = $request->attributes->get('limit');
169 8
        $limit = (1 <= $limit) && ($limit <= 100) ?: 10;
170
171
        //  Set pages based on the request parameters.
172 8
        $paginator->setMaxPerPage($request->query->get('limit', $limit));
173 8
        $paginator->setCurrentPage($request->query->get('page', 1));
174
175 8
        return $paginator;
176
    }
177
178
    /**
179
     * @param Request $request
180
     * @param string $filterForm
181
     *
182
     * @return Pagerfanta
183
     */
184 8
    public function handleFilterForm(Request $request, string $filterForm): Pagerfanta
185
    {
186
        /** @var RepositoryInterface $repository */
187 8
        $repository = $this->getRepository();
188 8
        $queryBuilder = $repository->getQueryBuilder();
189
190 8
        $form = $this->getForm($filterForm);
191
192 8
        if ($request->query->has($form->getName())) {
193 4
            $form->submit($request->query->get($form->getName()));
194
195 4
            $queryBuilder = $this->get('lexik_form_filter.query_builder_updater')
196 4
                ->addFilterConditions($form, $queryBuilder);
197
        }
198
199 8
        $paginagor = $this->createPaginator($request, $queryBuilder->getQuery());
200
201 8
        return $paginagor;
202
    }
203
204
    /**
205
     * @return string
206
     */
207 24
    public function getEntityResponseField()
208
    {
209 24
        $path = explode('\\', $this->entity);
210
211 24
        return $this->inflector::pluralize(strtolower(array_pop($path)));
212
    }
213
214
    /**
215
     * @param string $type
216
     * @param $data
217
     * @param array $options
218
     *
219
     * @return FormInterface
220
     */
221 20
    public function getForm(string $type, $data = null, array $options = []): FormInterface
222
    {
223 20
        $session = $this->get('session');
224 20
        $inflector = new Inflector();
225
226
        try {
227 20
            $reflectionClass = new \ReflectionClass($type);
228
        } catch (\ReflectionException $e) {
229
            throw new \RuntimeException($e->getMessage());
230
        }
231
232 20
        $name = $reflectionClass->getShortName();
233 20
        $options = array_merge($options, ['csrf_protection' => false, 'allow_extra_fields' => true]);
234
235 20
        if ($formData = $session->get($type, null)) {
236
            $data = $this->serializer
237
                ->deserialize($formData->getJson(), $formData->getClassName(), 'json');
238
        }
239
240 20
        $form = $this->formFactory
241 20
            ->createNamedBuilder($inflector->tableize($name), $type, $data, $options)
242 20
            ->getForm();
243
244 20
        return $form;
245
    }
246
}
247