Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 22 | final class GenericEntityRemoveController |
||
| 23 | { |
||
| 24 | |||
| 25 | private ControllerHelperInterface $controllerHelper; |
||
|
|
|||
| 26 | |||
| 27 | /** @var class-string */ |
||
| 28 | private string $entityClass; |
||
| 29 | |||
| 30 | private string $entityIdKey; |
||
| 31 | |||
| 32 | private ?string $authorizationAttribute; |
||
| 33 | |||
| 34 | public function __construct( |
||
| 35 | ControllerHelperInterface $controllerHelper, |
||
| 36 | array $options |
||
| 37 | ) { |
||
| 38 | Assert::keyExists($options, 'entity-class'); |
||
| 39 | |||
| 40 | $options = array_merge([ |
||
| 41 | 'authorization-attribute' => null, |
||
| 42 | 'entity-id-key' => 'entityId', |
||
| 43 | ], $options); |
||
| 44 | |||
| 45 | 7 | $this->controllerHelper = $controllerHelper; |
|
| 46 | $this->entityClass = $options['entity-class']; |
||
| 47 | $this->entityIdKey = $options['entity-id-key']; |
||
| 48 | $this->authorizationAttribute = $options['authorization-attribute']; |
||
| 49 | 7 | } |
|
| 50 | 7 | ||
| 51 | public function __invoke(): Response |
||
| 52 | 7 | { |
|
| 53 | 7 | /** @var Request $request */ |
|
| 54 | $request = $this->controllerHelper->getCurrentRequest(); |
||
| 55 | 7 | ||
| 56 | Assert::isInstanceOf($request, Request::class, "Cannot use controller outside of request-scope!"); |
||
| 57 | 7 | ||
| 58 | 7 | /** @var string $entityId */ |
|
| 59 | 7 | $entityId = $request->get($this->entityIdKey); |
|
| 60 | 7 | ||
| 61 | 7 | return $this->removeEntity($entityId); |
|
| 62 | } |
||
| 63 | 2 | ||
| 64 | public function removeEntity(string $entityId): Response |
||
| 65 | { |
||
| 66 | 2 | /** @var object|null $entity */ |
|
| 67 | $entity = $this->controllerHelper->findEntity($this->entityClass, $entityId); |
||
| 68 | 2 | ||
| 69 | if (is_null($entity)) { |
||
| 70 | throw new InvalidArgumentException(sprintf( |
||
| 71 | 1 | "Entity with id %s not found!", |
|
| 72 | $entityId |
||
| 73 | 1 | )); |
|
| 74 | } |
||
| 75 | |||
| 76 | 4 | if (!empty($this->authorizationAttribute)) { |
|
| 77 | $this->controllerHelper->denyAccessUnlessGranted($this->authorizationAttribute, $entity); |
||
| 78 | } |
||
| 79 | 4 | ||
| 80 | $this->controllerHelper->dispatchEvent("symfony_generics.entity_interaction", new EntityInteractionEvent( |
||
| 81 | 4 | $this->entityClass, |
|
| 82 | 1 | $entityId, |
|
| 83 | 1 | $entity, |
|
| 84 | 1 | "__destruct" |
|
| 85 | )); |
||
| 86 | |||
| 87 | $this->controllerHelper->removeEntity($entity); |
||
| 88 | 3 | ||
| 89 | 1 | return new Response("Entity removed!"); |
|
| 90 | } |
||
| 91 | |||
| 92 | } |
||
| 93 |