From a2ba9fb8751d840bcd0c890897a0bb1fc7601bd8 Mon Sep 17 00:00:00 2001 From: Johannes Wachter Date: Wed, 25 Sep 2019 07:48:24 +0200 Subject: [PATCH] 11 - Add a relation between events and locations --- config/forms/event_details.xml | 2 +- config/packages/sulu_admin.yaml | 14 ++++++++++ src/Controller/Admin/EventController.php | 9 ++++--- src/DataFixtures/ORM/AppFixtures.php | 22 ++++++++++++--- src/Entity/Event.php | 9 ++++--- .../Controller/Admin/EventControllerTest.php | 27 ++++++++++++------- tests/Unit/Entity/EventTest.php | 16 +++++++++-- translations/admin.de.json | 3 ++- translations/admin.en.json | 3 ++- 9 files changed, 79 insertions(+), 26 deletions(-) diff --git a/config/forms/event_details.xml b/config/forms/event_details.xml index c30baef..2de73ca 100644 --- a/config/forms/event_details.xml +++ b/config/forms/event_details.xml @@ -24,7 +24,7 @@ - + app.location diff --git a/config/packages/sulu_admin.yaml b/config/packages/sulu_admin.yaml index a669187..d84555c 100644 --- a/config/packages/sulu_admin.yaml +++ b/config/packages/sulu_admin.yaml @@ -38,3 +38,17 @@ sulu_admin: icon: fa-calendar label: 'app.events' overlay_title: 'app.events' + + single_selection: + single_location_selection: + default_type: list_overlay + resource_key: locations + types: + list_overlay: + adapter: table + list_key: locations + display_properties: + - name + icon: fa-home + empty_text: 'app.location.no_selections' + overlay_title: 'app.locations' diff --git a/src/Controller/Admin/EventController.php b/src/Controller/Admin/EventController.php index 49fda03..5daaa16 100644 --- a/src/Controller/Admin/EventController.php +++ b/src/Controller/Admin/EventController.php @@ -7,6 +7,7 @@ use App\Common\DoctrineListRepresentationFactory; use App\Entity\Event; use App\Repository\EventRepository; +use App\Repository\LocationRepository; use DateTimeImmutable; use Sulu\Bundle\MediaBundle\Entity\MediaRepositoryInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -25,7 +26,7 @@ * description: string|null, * startDate: string|null, * endDate: string|null, - * location: string|null, + * locationId: number|null, * } */ class EventController extends AbstractController @@ -34,6 +35,7 @@ public function __construct( private readonly EventRepository $eventRepository, private readonly MediaRepositoryInterface $mediaRepository, private readonly DoctrineListRepresentationFactory $doctrineListRepresentationFactory, + private readonly LocationRepository $locationRepository, ) { } @@ -127,6 +129,7 @@ protected function getDataForEntity(Event $entity): array $image = $entity->getImage(); $startDate = $entity->getStartDate(); $endDate = $entity->getEndDate(); + $location = $entity->getLocation(); return [ 'id' => $entity->getId(), @@ -139,7 +142,7 @@ protected function getDataForEntity(Event $entity): array 'description' => $entity->getDescription(), 'startDate' => null !== $startDate ? $startDate->format('c') : null, 'endDate' => null !== $endDate ? $endDate->format('c') : null, - 'location' => $entity->getLocation(), + 'locationId' => null !== $location ? $location->getId() : null, ]; } @@ -156,7 +159,7 @@ protected function mapDataToEntity(array $data, Event $entity): void $entity->setDescription($data['description'] ?? ''); $entity->setStartDate($data['startDate'] ? new DateTimeImmutable($data['startDate']) : null); $entity->setEndDate($data['endDate'] ? new DateTimeImmutable($data['endDate']) : null); - $entity->setLocation($data['location'] ?? null); + $entity->setLocation($data['locationId'] ? $this->locationRepository->findById((int) $data['locationId']) : null); } protected function load(int $id, Request $request): ?Event diff --git a/src/DataFixtures/ORM/AppFixtures.php b/src/DataFixtures/ORM/AppFixtures.php index 6e9dac1..01d5a0a 100644 --- a/src/DataFixtures/ORM/AppFixtures.php +++ b/src/DataFixtures/ORM/AppFixtures.php @@ -5,6 +5,7 @@ namespace App\DataFixtures\ORM; use App\Entity\Event; +use App\Entity\Location; use DateTimeImmutable; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; @@ -53,7 +54,8 @@ public function load(ObjectManager $manager): void */ private function loadEvents(ObjectManager $manager, array $images): void { - $repository = $manager->getRepository(Event::class); + $eventRepository = $manager->getRepository(Event::class); + $locationRepository = $manager->getRepository(Location::class); $data = [ [ @@ -129,18 +131,30 @@ private function loadEvents(ObjectManager $manager, array $images): void ]; foreach ($data as $item) { - $event = $repository->create(self::LOCALE); + $location = null; + if ($item['location']) { + $location = $locationRepository->create(); + $location->setName($item['location']); + $location->setStreet(''); + $location->setNumber(''); + $location->setCity(''); + $location->setCountryCode(''); + $location->setPostalCode(''); + $locationRepository->save($location); + } + + $event = $eventRepository->create(self::LOCALE); $event->setTitle($item['title']); $event->setImage($images[$item['image']] ?? null); - $event->setLocation($item['location']); + $event->setLocation($location); $event->setTeaser($item['teaser']); $event->setDescription('

' . $item['description'] . '

'); $event->setStartDate(new DateTimeImmutable($item['startDate'])); $event->setEndDate(new DateTimeImmutable($item['endDate'])); $event->setEnabled($item['enabled']); - $repository->save($event); + $eventRepository->save($event); } } diff --git a/src/Entity/Event.php b/src/Entity/Event.php index 244102d..dceda9f 100644 --- a/src/Entity/Event.php +++ b/src/Entity/Event.php @@ -31,8 +31,9 @@ class Event #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)] private ?DateTimeImmutable $endDate = null; - #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] - private ?string $location = null; + #[ORM\ManyToOne(targetEntity: Location::class)] + #[ORM\JoinColumn(onDelete: 'SET NULL')] + private ?Location $location = null; #[ORM\ManyToOne(targetEntity: MediaInterface::class)] #[ORM\JoinColumn(onDelete: 'SET NULL')] @@ -92,12 +93,12 @@ public function setEndDate(?DateTimeImmutable $endDate): self return $this; } - public function getLocation(): ?string + public function getLocation(): ?Location { return $this->location; } - public function setLocation(?string $location): self + public function setLocation(?Location $location): self { $this->location = $location; diff --git a/tests/Functional/Controller/Admin/EventControllerTest.php b/tests/Functional/Controller/Admin/EventControllerTest.php index 5a4780d..058d7ff 100644 --- a/tests/Functional/Controller/Admin/EventControllerTest.php +++ b/tests/Functional/Controller/Admin/EventControllerTest.php @@ -6,6 +6,7 @@ use App\Controller\Admin\EventController; use App\Tests\Functional\Traits\EventTrait; +use App\Tests\Functional\Traits\LocationTrait; use Sulu\Bundle\TestBundle\Testing\SuluTestCase; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Component\HttpFoundation\Response; @@ -16,6 +17,7 @@ class EventControllerTest extends SuluTestCase { use EventTrait; + use LocationTrait; private KernelBrowser $client; @@ -77,6 +79,8 @@ public function testGet(): void public function testPost(): void { + $location = $this->createLocation('Sulu HQ'); + $this->client->jsonRequest( 'POST', '/admin/api/events?locale=de', @@ -86,7 +90,7 @@ public function testPost(): void 'startDate' => '2019-01-01 12:00', 'endDate' => '2019-01-02 12:00', 'description' => 'Sulu is really awesome', - 'location' => 'Dornbirn', + 'locationId' => $location->getId(), ], ); @@ -104,7 +108,7 @@ public function testPost(): void $this->assertSame('2019-01-01T12:00:00+00:00', $result['startDate']); $this->assertSame('2019-01-02T12:00:00+00:00', $result['endDate']); $this->assertSame('Sulu is really awesome', $result['description']); - $this->assertSame('Dornbirn', $result['location']); + $this->assertSame($location->getId(), $result['locationId']); $result = $this->findEventById($result['id'], 'de'); @@ -117,7 +121,8 @@ public function testPost(): void $this->assertNotNull($result->getEndDate()); $this->assertSame('2019-01-02T12:00:00+00:00', $result->getEndDate()->format('c')); $this->assertSame('Sulu is really awesome', $result->getDescription()); - $this->assertSame('Dornbirn', $result->getLocation()); + $this->assertNotNull($result->getLocation()); + $this->assertSame($location->getId(), $result->getLocation()->getId()); } public function testPostNullValues(): void @@ -131,7 +136,7 @@ public function testPostNullValues(): void 'startDate' => null, 'endDate' => null, 'description' => null, - 'location' => null, + 'locationId' => null, ], ); @@ -149,7 +154,7 @@ public function testPostNullValues(): void $this->assertNull($result['startDate']); $this->assertNull($result['endDate']); $this->assertSame($result['description'], ''); - $this->assertNull($result['location']); + $this->assertNull($result['locationId']); $result = $this->findEventById($result['id'], 'de'); @@ -166,6 +171,7 @@ public function testPostNullValues(): void public function testPut(): void { $event = $this->createEvent('Symfony', 'de'); + $location = $this->createLocation('Sulu HQ'); $this->client->jsonRequest( 'PUT', @@ -176,7 +182,7 @@ public function testPut(): void 'startDate' => '2019-01-01 12:00', 'endDate' => '2019-01-02 12:00', 'description' => 'Symfony Live is really awesome', - 'location' => 'Dornbirn', + 'locationId' => $location->getId(), ], ); @@ -194,7 +200,7 @@ public function testPut(): void $this->assertSame('2019-01-01T12:00:00+00:00', $result['startDate']); $this->assertSame('2019-01-02T12:00:00+00:00', $result['endDate']); $this->assertSame('Symfony Live is really awesome', $result['description']); - $this->assertSame('Dornbirn', $result['location']); + $this->assertSame($location->getId(), $result['locationId']); $result = $this->findEventById($result['id'], 'de'); @@ -207,7 +213,8 @@ public function testPut(): void $this->assertNotNull($result->getEndDate()); $this->assertSame('2019-01-02T12:00:00+00:00', $result->getEndDate()->format('c')); $this->assertSame('Symfony Live is really awesome', $result->getDescription()); - $this->assertSame('Dornbirn', $result->getLocation()); + $this->assertNotNull($result->getLocation()); + $this->assertSame($location->getId(), $result->getLocation()->getId()); } public function testPutNullValues(): void @@ -223,7 +230,7 @@ public function testPutNullValues(): void 'startDate' => null, 'endDate' => null, 'description' => null, - 'location' => null, + 'locationId' => null, ], ); @@ -241,7 +248,7 @@ public function testPutNullValues(): void $this->assertNull($result['startDate']); $this->assertNull($result['endDate']); $this->assertSame($result['description'], ''); - $this->assertNull($result['location']); + $this->assertNull($result['locationId']); $result = $this->findEventById($result['id'], 'de'); diff --git a/tests/Unit/Entity/EventTest.php b/tests/Unit/Entity/EventTest.php index 6d1bfb4..851521a 100644 --- a/tests/Unit/Entity/EventTest.php +++ b/tests/Unit/Entity/EventTest.php @@ -6,19 +6,28 @@ use App\Entity\Event; use App\Entity\EventTranslation; +use App\Entity\Location; use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; +use Prophecy\Prophecy\ObjectProphecy; use Sulu\Bundle\MediaBundle\Entity\MediaInterface; class EventTest extends TestCase { use ProphecyTrait; + /** + * @var ObjectProphecy + */ + private ObjectProphecy $location; + private Event $event; protected function setUp(): void { + $this->location = $this->prophesize(Location::class); + $this->event = new Event(); $this->event->setLocale('de'); } @@ -52,9 +61,12 @@ public function testEndDate(): void public function testLocation(): void { + $this->location->getId()->willReturn(42); + $this->assertNull($this->event->getLocation()); - $this->assertSame($this->event, $this->event->setLocation('Amsterdam')); - $this->assertSame('Amsterdam', $this->event->getLocation()); + $this->assertSame($this->event, $this->event->setLocation($this->location->reveal())); + $this->assertNotNull($this->event->getLocation()); + $this->assertSame($this->location->reveal(), $this->event->getLocation()); } public function testImage(): void diff --git a/translations/admin.de.json b/translations/admin.de.json index ac72ae7..071d38b 100644 --- a/translations/admin.de.json +++ b/translations/admin.de.json @@ -8,5 +8,6 @@ "app.enable_event": "Veranstaltungen aktivieren", "app.enabled": "Aktiviert", "app.location": "Standort", - "app.locations": "Standorte" + "app.locations": "Standorte", + "app.location.no_selections": "Kein Standord ausgewählt" } diff --git a/translations/admin.en.json b/translations/admin.en.json index b073ae1..52a386b 100644 --- a/translations/admin.en.json +++ b/translations/admin.en.json @@ -8,5 +8,6 @@ "app.enable_event": "Enable event", "app.enabled": "Enabled", "app.location": "Location", - "app.locations": "Locations" + "app.locations": "Locations", + "app.location.no_selections": "No location selected" }