Complex classes like RestResourceController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use RestResourceController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class RestResourceController implements ContainerAwareInterface, RestResourceControllerInterface |
||
31 | { |
||
32 | use ContainerAwareTrait; |
||
33 | |||
34 | /** |
||
35 | * {@inheritdoc} |
||
36 | */ |
||
37 | 10 | public function listAction(Request $request) |
|
62 | |||
63 | /** |
||
64 | * {@inheritdoc} |
||
65 | */ |
||
66 | 4 | public function postAction(Request $request) |
|
67 | { |
||
68 | 4 | $this->assertPostGranted(); |
|
69 | 2 | $entity = $this->getRequestParser()->parseEntity($request, $this->getEntityClass()); |
|
70 | 2 | $entity = $this->postProcessPostedEntity($entity); |
|
71 | |||
72 | 2 | $errors = $this->getValidator()->validate($entity); |
|
73 | 2 | if ($errors->count() > 0) { |
|
74 | 2 | return new JsonResponse($this->parseConstraintViolations($errors), Response::HTTP_BAD_REQUEST); |
|
75 | } |
||
76 | |||
77 | $entity = $this->createEntity($entity); |
||
78 | |||
79 | $content = $this->getNormalizer()->normalize($entity, $this->parseIncludes($request)); |
||
80 | |||
81 | return new JsonResponse($content, Response::HTTP_CREATED); |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * {@inheritdoc} |
||
86 | */ |
||
87 | 16 | public function getAction(Request $request, $id) |
|
96 | |||
97 | /** |
||
98 | * {@inheritdoc} |
||
99 | */ |
||
100 | 4 | public function putAction(Request $request, $id) |
|
118 | |||
119 | /** |
||
120 | * {@inheritdoc} |
||
121 | */ |
||
122 | 4 | public function deleteAction(Request $request, $id) |
|
123 | { |
||
124 | 4 | $entity = $this->fetchEntity($id); |
|
125 | 4 | $this->assertDeleteGranted($entity); |
|
126 | 2 | $this->getService()->remove($entity); |
|
127 | |||
128 | 2 | return new JsonResponse(null, Response::HTTP_NO_CONTENT); |
|
129 | } |
||
130 | |||
131 | /** |
||
132 | * {@inheritdoc} |
||
133 | */ |
||
134 | 6 | public function listSubresourceAction(Request $request, $id) |
|
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | 4 | public function postSubresourceAction(Request $request, $id) |
|
188 | |||
189 | /** |
||
190 | * {@inheritdoc} |
||
191 | */ |
||
192 | 4 | public function putSubresourceAction(Request $request, $id, $subId) |
|
201 | |||
202 | /** |
||
203 | * {@inheritdoc} |
||
204 | */ |
||
205 | 4 | public function deleteSubresourceAction(Request $request, $id, $subId = null) |
|
214 | |||
215 | /** |
||
216 | * @return CrudServiceInterface |
||
217 | */ |
||
218 | 38 | protected function getService(): CrudServiceInterface |
|
243 | |||
244 | /** |
||
245 | * @param object $entity |
||
246 | * |
||
247 | * @return object |
||
248 | */ |
||
249 | 2 | protected function postProcessPostedEntity($entity) |
|
250 | { |
||
251 | 2 | return $entity; |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * @param object $entity |
||
256 | * |
||
257 | * @return object |
||
258 | */ |
||
259 | 2 | protected function postProcessPuttedEntity($entity) |
|
263 | |||
264 | /** |
||
265 | * @param string $subresource |
||
266 | * @param object $parent |
||
267 | * @param object $entity |
||
268 | * |
||
269 | * @return object |
||
270 | */ |
||
271 | 2 | protected function postProcessSubResourcePostedEntity($subresource, $entity, $parent) |
|
275 | |||
276 | 32 | protected function fetchEntity($id) |
|
277 | { |
||
278 | 32 | $entity = $this->getService()->find($id); |
|
279 | 32 | if (null === $entity) { |
|
280 | 2 | throw new NotFoundHttpException(); |
|
281 | } |
||
282 | |||
283 | 32 | return $entity; |
|
284 | } |
||
285 | |||
286 | /** |
||
287 | * @param int $page |
||
288 | * @param int $perPage |
||
289 | * |
||
290 | * @return Paginator|array |
||
291 | */ |
||
292 | 6 | protected function listEntities(int $page = 1, int $perPage = 50) |
|
296 | |||
297 | protected function createEntity($entity) |
||
301 | |||
302 | 2 | protected function updateEntity($entity) |
|
306 | |||
307 | /** |
||
308 | * @param object $entity |
||
309 | * @param string $property |
||
310 | * @param int $page |
||
311 | * @param int $perPage |
||
312 | * |
||
313 | * @return Paginator|array |
||
314 | */ |
||
315 | 6 | protected function listSubresource($entity, string $property, int $page = 1, int $perPage = 50) |
|
319 | |||
320 | 46 | protected function getEntityClass() |
|
324 | |||
325 | protected function getShortName() |
||
329 | |||
330 | 38 | protected function getServiceId() |
|
334 | |||
335 | 46 | protected function getCurrentRequest() |
|
339 | |||
340 | 10 | protected function assertListGranted() |
|
347 | |||
348 | 4 | protected function assertPostGranted() |
|
349 | { |
||
350 | 4 | $method = $this->getClassMetadata()->getMethod(Method::POST); |
|
351 | 4 | $right = $method->right; |
|
352 | 4 | if (null === $right) { |
|
353 | throw new AccessDeniedException(); |
||
354 | } |
||
355 | |||
356 | 4 | $this->denyAccessUnlessGranted($right->attributes); |
|
357 | 2 | } |
|
358 | |||
359 | 14 | protected function assertGetGranted($entity) |
|
366 | |||
367 | 4 | protected function assertPutGranted($entity) |
|
377 | |||
378 | 4 | protected function assertDeleteGranted($entity) |
|
379 | { |
||
380 | 4 | $method = $this->getClassMetadata()->getMethod(Method::POST); |
|
381 | 4 | $right = $method->right; |
|
382 | 4 | if (null === $right) { |
|
383 | throw new AccessDeniedException(); |
||
384 | } |
||
385 | |||
386 | 4 | $this->assertRightGranted($entity, $right); |
|
387 | 2 | } |
|
388 | |||
389 | 6 | protected function assertSubresourceListGranted($entity, $subresource) |
|
402 | |||
403 | 4 | protected function assertSubresourcePostGranted($entity, $subresource) |
|
416 | |||
417 | 4 | protected function assertSubresourcePutGranted($entity, $subresource) |
|
430 | |||
431 | 4 | protected function assertSubresourceDeleteGranted($entity, $subresource) |
|
444 | |||
445 | /** |
||
446 | * @return ClassMetadata |
||
447 | */ |
||
448 | 46 | protected function getClassMetadata() |
|
456 | |||
457 | 2 | protected function getSubResourceEntityClass($subresource) |
|
464 | |||
465 | protected function resolveSubject($entity, $propertyPath) |
||
474 | |||
475 | /** |
||
476 | * @param object $entity |
||
477 | * @param Right $right |
||
478 | */ |
||
479 | 28 | protected function assertRightGranted($entity, Right $right) |
|
489 | |||
490 | /** |
||
491 | * @param object $parent |
||
492 | * @param string $subresource |
||
493 | * @param object $entity |
||
494 | * |
||
495 | * @return |
||
496 | */ |
||
497 | 2 | protected function createSubResource($parent, $subresource, $entity) |
|
501 | |||
502 | /** |
||
503 | * @return string|null |
||
504 | */ |
||
505 | 14 | protected function getSubresource() |
|
509 | |||
510 | 28 | protected function parseIncludes(Request $request) |
|
526 | |||
527 | 2 | private function parseConstraintViolations(ConstraintViolationListInterface $errors) |
|
528 | { |
||
529 | 2 | $data = []; |
|
530 | /** @var ConstraintViolationInterface $error */ |
||
531 | 2 | foreach ($errors as $error) { |
|
532 | 2 | $data[] = [ |
|
533 | 2 | 'propertyPath' => $error->getPropertyPath(), |
|
534 | 2 | 'message' => $error->getMessage(), |
|
535 | 2 | 'value' => $error->getInvalidValue() |
|
536 | ]; |
||
537 | } |
||
538 | |||
539 | 2 | return $data; |
|
540 | } |
||
541 | |||
542 | 12 | private function addPaginationHeaders(Response $response, int $page, int $perPage, int $total) |
|
553 | |||
554 | 40 | protected function denyAccessUnlessGranted($attributes, $object = null, $message = 'Access Denied.') |
|
560 | |||
561 | /** |
||
562 | * @return Normalizer |
||
563 | */ |
||
564 | 28 | protected function getNormalizer() |
|
568 | |||
569 | /** |
||
570 | * @return ValidatorInterface |
||
571 | */ |
||
572 | 6 | protected function getValidator() |
|
576 | |||
577 | /** |
||
578 | * @return RestRequestParser |
||
579 | */ |
||
580 | 6 | protected function getRequestParser() |
|
584 | |||
585 | /** |
||
586 | * @return RequestStack |
||
587 | */ |
||
588 | 46 | protected function getRequestStack() |
|
592 | |||
593 | /** |
||
594 | * @return MetadataFactoryInterface |
||
595 | */ |
||
596 | 46 | protected function getMetadataFactory() |
|
600 | |||
601 | /** |
||
602 | * @return PropertyAccessorInterface |
||
603 | */ |
||
604 | protected function getPropertyAccessor() |
||
608 | |||
609 | /** |
||
610 | * @return AuthorizationCheckerInterface |
||
611 | */ |
||
612 | 40 | protected function getAuthorizationChecker() |
|
616 | } |
||
617 |
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.