From 69b1e17c462d5f477d8b543bcc9051e7a1a71066 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 + config/routes_admin.yaml | 6 + src/Admin/EventAdmin.php | 133 +++++++++++++++++++++++ src/Controller/Admin/EventController.php | 114 +++++++++++++++++++ src/Entity/Event.php | 118 ++++++++++++++++++++ translations/admin.de.json | 5 +- translations/admin.en.json | 5 +- 9 files changed, 452 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..3e0a60c1 --- /dev/null +++ b/config/packages/app_event_admin.yaml @@ -0,0 +1,6 @@ +sulu_admin: + resources: + events: + routes: + list: 'app.get_events' + detail: 'app.get_event' diff --git a/config/routes_admin.yaml b/config/routes_admin.yaml index d084e01e..9dd26ce7 100644 --- a/config/routes_admin.yaml +++ b/config/routes_admin.yaml @@ -4,3 +4,9 @@ app.album_api: prefix: /admin/api resource: App\Controller\Admin\AlbumController name_prefix: app. + +app.event_api: + type: rest + prefix: /admin/api + resource: App\Controller\Admin\EventController + name_prefix: app. diff --git a/src/Admin/EventAdmin.php b/src/Admin/EventAdmin.php new file mode 100644 index 00000000..c7429e49 --- /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..3f3f4cb1 --- /dev/null +++ b/src/Controller/Admin/EventController.php @@ -0,0 +1,114 @@ +doctrineListRepresentationFactory = $doctrineListRepresentationFactory; + $this->entityManager = $entityManager; + $this->mediaManager = $mediaManager; + + parent::__construct($viewHandler, $tokenStorage); + } + + public function cgetAction(): Response + { + $listRepresentation = $this->doctrineListRepresentationFactory->createDoctrineListRepresentation( + Event::RESOURCE_KEY + ); + + return $this->handleView($this->view($listRepresentation)); + } + + public function getAction(int $id): Response + { + $event = $this->entityManager->getRepository(Event::class)->find($id); + if (!$event) { + throw new NotFoundHttpException(); + } + + return $this->handleView($this->view($event)); + } + + public function putAction(Request $request, int $id): Response + { + $event = $this->entityManager->getRepository(Event::class)->find($id); + if (!$event) { + throw new NotFoundHttpException(); + } + + $this->mapDataToEntity($request->request->all(), $event); + $this->entityManager->flush(); + + return $this->handleView($this->view($event)); + } + + public function postAction(Request $request): Response + { + $event = new Event(); + + $this->mapDataToEntity($request->request->all(), $event); + $this->entityManager->persist($event); + $this->entityManager->flush(); + + return $this->handleView($this->view($event, 201)); + } + + 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->handleView($this->view(null, 204)); + } + + /** + * @param array $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; + } +} diff --git a/src/Entity/Event.php b/src/Entity/Event.php new file mode 100644 index 00000000..5b9e44f8 --- /dev/null +++ b/src/Entity/Event.php @@ -0,0 +1,118 @@ +id; + } + + public function getName(): string + { + return $this->name ?? ''; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getImage(): ?MediaInterface + { + return $this->image; + } + + /** + * @return array + * + * @Serializer\VirtualProperty() + * @Serializer\SerializedName("image") + */ + public function getImageData(): ?array + { + if ($image = $this->getImage()) { + return [ + 'id' => $image->getId(), + ]; + } + + return null; + } + + 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" }