From 18cd7be9708e7f544ae13b9d844f75b7de36592c Mon Sep 17 00:00:00 2001 From: Niklas Natter Date: Mon, 9 Nov 2020 14:23:36 +0100 Subject: [PATCH] Implement custom event entity --- config/forms/event_details.xml | 37 ++++++ config/lists/events.xml | 30 +++++ config/packages/app_event_admin.yaml | 6 + src/Admin/EventAdmin.php | 133 +++++++++++++++++++ src/Controller/Admin/EventController.php | 157 +++++++++++++++++++++++ src/Entity/Event.php | 91 +++++++++++++ translations/admin.de.json | 5 +- translations/admin.en.json | 5 +- 8 files changed, 462 insertions(+), 2 deletions(-) create mode 100644 config/forms/event_details.xml create mode 100644 config/lists/events.xml create mode 100644 config/packages/app_event_admin.yaml create mode 100644 src/Admin/EventAdmin.php create mode 100644 src/Controller/Admin/EventController.php create mode 100644 src/Entity/Event.php diff --git a/config/forms/event_details.xml b/config/forms/event_details.xml new file mode 100644 index 00000000..7c624dcc --- /dev/null +++ b/config/forms/event_details.xml @@ -0,0 +1,37 @@ + +
+ event_details + + + + + sulu_admin.name + + + + + + + + + + app.image + + + + + + app.start_date + + + + + + app.end_date + + + +
diff --git a/config/lists/events.xml b/config/lists/events.xml new file mode 100644 index 00000000..2e3951ee --- /dev/null +++ b/config/lists/events.xml @@ -0,0 +1,30 @@ + + + events + + + + id + App\Entity\Event + + + + name + App\Entity\Event + + + + startDate + App\Entity\Event + + + + + + endDate + App\Entity\Event + + + + + diff --git a/config/packages/app_event_admin.yaml b/config/packages/app_event_admin.yaml new file mode 100644 index 00000000..0d8d410f --- /dev/null +++ b/config/packages/app_event_admin.yaml @@ -0,0 +1,6 @@ +sulu_admin: + resources: + events: + routes: + list: 'app.get_event_list' + detail: 'app.get_event' diff --git a/src/Admin/EventAdmin.php b/src/Admin/EventAdmin.php new file mode 100644 index 00000000..5adf424c --- /dev/null +++ b/src/Admin/EventAdmin.php @@ -0,0 +1,133 @@ +viewBuilderFactory = $viewBuilderFactory; + $this->securityChecker = $securityChecker; + } + + public function configureNavigationItems(NavigationItemCollection $navigationItemCollection): void + { + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::EDIT)) { + $rootNavigationItem = new NavigationItem('app.events'); + $rootNavigationItem->setIcon('su-calendar'); + $rootNavigationItem->setPosition(30); + $rootNavigationItem->setView(static::LIST_VIEW); + + $navigationItemCollection->add($rootNavigationItem); + } + } + + public function configureViews(ViewCollection $viewCollection): void + { + $formToolbarActions = []; + $listToolbarActions = []; + + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::ADD)) { + $listToolbarActions[] = new ToolbarAction('sulu_admin.add'); + } + + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::EDIT)) { + $formToolbarActions[] = new ToolbarAction('sulu_admin.save'); + } + + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::DELETE)) { + $formToolbarActions[] = new ToolbarAction('sulu_admin.delete'); + $listToolbarActions[] = new ToolbarAction('sulu_admin.delete'); + } + + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::VIEW)) { + $listToolbarActions[] = new ToolbarAction('sulu_admin.export'); + } + + if ($this->securityChecker->hasPermission(Event::SECURITY_CONTEXT, PermissionTypes::EDIT)) { + $viewCollection->add( + $this->viewBuilderFactory->createListViewBuilder(static::LIST_VIEW, '/events') + ->setResourceKey(Event::RESOURCE_KEY) + ->setListKey(Event::LIST_KEY) + ->setTitle('app.events') + ->addListAdapters(['table']) + ->setAddView(static::ADD_FORM_VIEW) + ->setEditView(static::EDIT_FORM_VIEW) + ->addToolbarActions($listToolbarActions) + ); + + $viewCollection->add( + $this->viewBuilderFactory->createResourceTabViewBuilder(static::ADD_FORM_VIEW, '/events/add') + ->setResourceKey(Event::RESOURCE_KEY) + ->setBackView(static::LIST_VIEW) + ); + + $viewCollection->add( + $this->viewBuilderFactory->createFormViewBuilder(static::ADD_FORM_DETAILS_VIEW, '/details') + ->setResourceKey(Event::RESOURCE_KEY) + ->setFormKey(Event::FORM_KEY) + ->setTabTitle('sulu_admin.details') + ->setEditView(static::EDIT_FORM_VIEW) + ->addToolbarActions($formToolbarActions) + ->setParent(static::ADD_FORM_VIEW) + ); + + $viewCollection->add( + $this->viewBuilderFactory->createResourceTabViewBuilder(static::EDIT_FORM_VIEW, '/events/:id') + ->setResourceKey(Event::RESOURCE_KEY) + ->setBackView(static::LIST_VIEW) + ); + + $viewCollection->add( + $this->viewBuilderFactory->createFormViewBuilder(static::EDIT_FORM_DETAILS_VIEW, '/details') + ->setResourceKey(Event::RESOURCE_KEY) + ->setFormKey(Event::FORM_KEY) + ->setTabTitle('sulu_admin.details') + ->addToolbarActions($formToolbarActions) + ->setParent(static::EDIT_FORM_VIEW) + ); + } + } + + /** + * @return mixed[] + */ + public function getSecurityContexts(): array + { + return [ + self::SULU_ADMIN_SECURITY_SYSTEM => [ + 'Events' => [ + Event::SECURITY_CONTEXT => [ + PermissionTypes::VIEW, + PermissionTypes::ADD, + PermissionTypes::EDIT, + PermissionTypes::DELETE, + ], + ], + ], + ]; + } +} diff --git a/src/Controller/Admin/EventController.php b/src/Controller/Admin/EventController.php new file mode 100644 index 00000000..c0c4077d --- /dev/null +++ b/src/Controller/Admin/EventController.php @@ -0,0 +1,157 @@ +doctrineListRepresentationFactory = $doctrineListRepresentationFactory; + $this->entityManager = $entityManager; + $this->mediaManager = $mediaManager; + } + + /** + * @Route("/admin/api/events/{id}", methods={"GET"}, name="app.get_event") + */ + public function getAction(int $id): Response + { + $event = $this->entityManager->getRepository(Event::class)->find($id); + if (!$event) { + throw new NotFoundHttpException(); + } + + return $this->json($this->getDataForEntity($event)); + } + + /** + * @Route("/admin/api/events/{id}", methods={"PUT"}, name="app.put_event") + */ + public function putAction(Request $request, int $id): Response + { + $event = $this->entityManager->getRepository(Event::class)->find($id); + if (!$event) { + throw new NotFoundHttpException(); + } + + /** @var EventData $data */ + $data = $request->toArray(); + $this->mapDataToEntity($data, $event); + $this->entityManager->flush(); + + return $this->json($this->getDataForEntity($event)); + } + + /** + * @Route("/admin/api/events", methods={"POST"}, name="app.post_event") + */ + public function postAction(Request $request): Response + { + $event = new Event(); + + /** @var EventData $data */ + $data = $request->toArray(); + $this->mapDataToEntity($data, $event); + $this->entityManager->persist($event); + $this->entityManager->flush(); + + return $this->json($this->getDataForEntity($event), 201); + } + + /** + * @Route("/admin/api/events/{id}", methods={"DELETE"}, name="app.delete_event") + */ + public function deleteAction(int $id): Response + { + /** @var Event $event */ + $event = $this->entityManager->getReference(Event::class, $id); + $this->entityManager->remove($event); + $this->entityManager->flush(); + + return $this->json(null, 204); + } + + /** + * @Route("/admin/api/events", methods={"GET"}, name="app.get_event_list") + */ + public function getListAction(): Response + { + $listRepresentation = $this->doctrineListRepresentationFactory->createDoctrineListRepresentation( + Event::RESOURCE_KEY + ); + + return $this->json($listRepresentation->toArray()); + } + + /** + * @return EventData $data + */ + protected function getDataForEntity(Event $entity): array + { + $image = $entity->getImage(); + $startDate = $entity->getStartDate(); + $endDate = $entity->getEndDate(); + + return [ + 'id' => $entity->getId(), + 'name' => $entity->getName(), + 'image' => $image + ? ['id' => $image->getId()] + : null, + 'startDate' => $startDate ? $startDate->format('c') : null, + 'endDate' => $endDate ? $endDate->format('c') : null, + ]; + } + + /** + * @param EventData $data + */ + protected function mapDataToEntity(array $data, Event $entity): void + { + $imageId = $data['image']['id'] ?? null; + + $entity->setName($data['name']); + $entity->setImage($imageId ? $this->mediaManager->getEntityById($imageId) : null); + $entity->setStartDate($data['startDate'] ? new \DateTimeImmutable($data['startDate']) : null); + $entity->setEndDate($data['endDate'] ? new \DateTimeImmutable($data['endDate']) : null); + } + + public function getSecurityContext(): string + { + return Event::SECURITY_CONTEXT; + } + + public function getLocale(Request $request): ?string + { + return $request->query->get('locale'); + } +} diff --git a/src/Entity/Event.php b/src/Entity/Event.php new file mode 100644 index 00000000..b85c5117 --- /dev/null +++ b/src/Entity/Event.php @@ -0,0 +1,91 @@ +id; + } + + public function getName(): string + { + return $this->name ?? ''; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getImage(): ?MediaInterface + { + return $this->image; + } + + public function setImage(?MediaInterface $image): void + { + $this->image = $image; + } + + public function getStartDate(): ?\DateTimeImmutable + { + return $this->startDate; + } + + public function setStartDate(?\DateTimeImmutable $startDate): void + { + $this->startDate = $startDate; + } + + public function getEndDate(): ?\DateTimeImmutable + { + return $this->endDate; + } + + public function setEndDate(?\DateTimeImmutable $endDate): void + { + $this->endDate = $endDate; + } +} diff --git a/translations/admin.de.json b/translations/admin.de.json index 4565f68a..f012133c 100644 --- a/translations/admin.de.json +++ b/translations/admin.de.json @@ -10,5 +10,8 @@ "app.album_selection_label": "{count} {count, plural, =1 {Album} other {Alben}} ausgewählt", "app.select_albums": "Alben auswählen", "app.no_album_selected": "Kein Album ausgewählt", - "app.select_album": "Album auswählen" + "app.select_album": "Album auswählen", + "app.events": "Events", + "app.start_date": "Startdatum", + "app.end_date": "Enddatum" } diff --git a/translations/admin.en.json b/translations/admin.en.json index 2160e113..109345a2 100644 --- a/translations/admin.en.json +++ b/translations/admin.en.json @@ -10,5 +10,8 @@ "app.album_selection_label": "{count} {count, plural, =1 {album} other {albums}} selected", "app.select_albums": "Select albums", "app.no_album_selected": "No album selected", - "app.select_album": "Select album" + "app.select_album": "Select album", + "app.events": "Events", + "app.start_date": "Start Date", + "app.end_date": "End Date" }