diff --git a/src/Common/DoctrineListRepresentationFactory.php b/src/Common/DoctrineListRepresentationFactory.php index 30b28d3..643bd2a 100644 --- a/src/Common/DoctrineListRepresentationFactory.php +++ b/src/Common/DoctrineListRepresentationFactory.php @@ -4,6 +4,7 @@ namespace Manuxi\SuluEventBundle\Common; +use Sulu\Bundle\MediaBundle\Media\Manager\MediaManagerInterface; use Sulu\Component\Rest\ListBuilder\Doctrine\DoctrineListBuilderFactory; use Sulu\Component\Rest\ListBuilder\Doctrine\FieldDescriptor\DoctrineFieldDescriptor; use Sulu\Component\Rest\ListBuilder\Metadata\FieldDescriptorFactoryInterface; @@ -15,15 +16,18 @@ class DoctrineListRepresentationFactory private $restHelper; private $listBuilderFactory; private $fieldDescriptorFactory; + private $mediaManager; public function __construct( RestHelperInterface $restHelper, DoctrineListBuilderFactory $listBuilderFactory, - FieldDescriptorFactoryInterface $fieldDescriptorFactory + FieldDescriptorFactoryInterface $fieldDescriptorFactory, + MediaManagerInterface $mediaManager ) { $this->restHelper = $restHelper; $this->listBuilderFactory = $listBuilderFactory; $this->fieldDescriptorFactory = $fieldDescriptorFactory; + $this->mediaManager = $mediaManager; } /** @@ -34,7 +38,8 @@ public function createDoctrineListRepresentation( string $resourceKey, array $filters = [], array $parameters = [] - ): PaginatedRepresentation { + ): PaginatedRepresentation + { /** @var DoctrineFieldDescriptor[] $fieldDescriptors */ $fieldDescriptors = $this->fieldDescriptorFactory->getFieldDescriptors($resourceKey); @@ -50,6 +55,7 @@ public function createDoctrineListRepresentation( } $list = $listBuilder->execute(); + $list = $this->addImagesToListElements($list, $parameters['locale'] ?? null); return new PaginatedRepresentation( $list, @@ -59,4 +65,23 @@ public function createDoctrineListRepresentation( (int) $listBuilder->count() ); } + + /** + * @param mixed[] + */ + private function addImagesToListElements(array $listeElements, ?string $locale): array + { + $ids = array_filter(array_column($listeElements, 'image')); + $images = $this->mediaManager->getFormatUrls($ids, $locale); + foreach ($listeElements as $key => $element) { + if (\array_key_exists('image', $element) + && $element['image'] + && \array_key_exists($element['image'], $images) + ) { + $listeElements[$key]['image'] = $images[$element['image']]; + } + } + + return $listeElements; + } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index b0660fd..aec24b8 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -5,7 +5,19 @@ namespace Manuxi\SuluEventBundle\DependencyInjection; use Manuxi\SuluEventBundle\Entity\Event; +use Manuxi\SuluEventBundle\Entity\EventExcerpt; +use Manuxi\SuluEventBundle\Entity\EventExcerptTranslation; +use Manuxi\SuluEventBundle\Entity\EventSeo; +use Manuxi\SuluEventBundle\Entity\EventSeoTranslation; +use Manuxi\SuluEventBundle\Entity\EventTranslation; +use Manuxi\SuluEventBundle\Entity\Location; +use Manuxi\SuluEventBundle\Repository\EventExcerptRepository; +use Manuxi\SuluEventBundle\Repository\EventExcerptTranslationRepository; use Manuxi\SuluEventBundle\Repository\EventRepository; +use Manuxi\SuluEventBundle\Repository\EventSeoRepository; +use Manuxi\SuluEventBundle\Repository\EventSeoTranslationRepository; +use Manuxi\SuluEventBundle\Repository\EventTranslationRepository; +use Manuxi\SuluEventBundle\Repository\LocationRepository; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -17,20 +29,62 @@ public function getConfigTreeBuilder() $treeBuilder = new TreeBuilder('sulu_event'); $root = $treeBuilder->getRootNode(); -// $root->children() -// ->arrayNode('objects') -// ->addDefaultsIfNotSet() -// ->children() -// ->arrayNode('news') -// ->addDefaultsIfNotSet() -// ->children() -// ->scalarNode('model')->defaultValue(Event::class)->end() -// ->scalarNode('repository')->defaultValue(EventRepository::class)->end() -// ->end() -// ->end() -// ->end() -// ->end() -// ->end(); + $root + ->children() + ->arrayNode('objects') + ->addDefaultsIfNotSet() + ->children() + ->arrayNode('event') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(Event::class)->end() + ->scalarNode('repository')->defaultValue(EventRepository::class)->end() + ->end() + ->end() + ->arrayNode('event_translation') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(EventTranslation::class)->end() + ->scalarNode('repository')->defaultValue(EventTranslationRepository::class)->end() + ->end() + ->end() + ->arrayNode('event_seo') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(EventSeo::class)->end() + ->scalarNode('repository')->defaultValue(EventSeoRepository::class)->end() + ->end() + ->end() + ->arrayNode('event_seo_translation') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(EventSeoTranslation::class)->end() + ->scalarNode('repository')->defaultValue(EventSeoTranslationRepository::class)->end() + ->end() + ->end() + ->arrayNode('event_excerpt') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(EventExcerpt::class)->end() + ->scalarNode('repository')->defaultValue(EventExcerptRepository::class)->end() + ->end() + ->end() + ->arrayNode('event_excerpt_translation') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(EventExcerptTranslation::class)->end() + ->scalarNode('repository')->defaultValue(EventExcerptTranslationRepository::class)->end() + ->end() + ->end() + ->arrayNode('location') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(Location::class)->end() + ->scalarNode('repository')->defaultValue(LocationRepository::class)->end() + ->end() + ->end() + ->end() + ->end(); return $treeBuilder; } diff --git a/src/DependencyInjection/SuluEventExtension.php b/src/DependencyInjection/SuluEventExtension.php index e11a2d2..0724756 100644 --- a/src/DependencyInjection/SuluEventExtension.php +++ b/src/DependencyInjection/SuluEventExtension.php @@ -7,6 +7,7 @@ use Manuxi\SuluEventBundle\Admin\EventAdmin; use Manuxi\SuluEventBundle\Entity\Event; use Manuxi\SuluEventBundle\Entity\Location; +use Sulu\Bundle\PersistenceBundle\DependencyInjection\PersistenceExtensionTrait; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; @@ -15,7 +16,11 @@ class SuluEventExtension extends Extension implements PrependExtensionInterface { + use PersistenceExtensionTrait; + /** + * @throws \Exception + */ public function load(array $configs, ContainerBuilder $container) { @@ -26,8 +31,7 @@ public function load(array $configs, ContainerBuilder $container) $loader->load('services.xml'); $loader->load('controller.xml'); - -// $this->configurePersistence($config['objects'], $container); + $this->configurePersistence($config['objects'], $container); } public function prepend(ContainerBuilder $container) diff --git a/src/Entity/Event.php b/src/Entity/Event.php index 20eade3..e728223 100644 --- a/src/Entity/Event.php +++ b/src/Entity/Event.php @@ -77,7 +77,7 @@ class Event implements AuditableTranslationInterface */ private $translations; - protected $locale = 'en'; + private $locale = 'en'; private $ext = []; diff --git a/src/Entity/Location.php b/src/Entity/Location.php index 535f7a2..544b1c7 100644 --- a/src/Entity/Location.php +++ b/src/Entity/Location.php @@ -6,6 +6,7 @@ use Manuxi\SuluEventBundle\Repository\LocationRepository; use Doctrine\ORM\Mapping as ORM; +use Sulu\Bundle\MediaBundle\Entity\MediaInterface; /** * @ORM\Entity @@ -50,6 +51,11 @@ class Location */ private $city; + /** + * @ORM\Column(type="string", length=255, nullable=true) + */ + private $state; + /** * @ORM\Column(type="string", length=255, nullable=true) */ @@ -60,6 +66,11 @@ class Location */ private $notes; + /** + * @ORM\ManyToOne(targetEntity="Sulu\Bundle\MediaBundle\Entity\MediaInterface") + */ + private $image; + public function getId(): ?int { return $this->id; @@ -120,6 +131,17 @@ public function setCity(?string $city): self return $this; } + public function getState(): ?string + { + return $this->state; + } + + public function setState(?string $state): self + { + $this->state = $state; + return $this; + } + public function getCountryCode(): ?string { return $this->countryCode; @@ -142,4 +164,28 @@ public function setNotes($notes): self return $this; } + public function getImage(): ?MediaInterface + { + return $this->image; + } + + /** + * @return array|null + */ + public function getImageData(): ?array + { + if (!$this->image) { + return null; + } + + return [ + 'id' => $this->image->getId(), + ]; + } + + public function setImage(?MediaInterface $image): self + { + $this->image = $image; + return $this; + } } diff --git a/src/Entity/Models/LocationModel.php b/src/Entity/Models/LocationModel.php index 599219d..75ba788 100644 --- a/src/Entity/Models/LocationModel.php +++ b/src/Entity/Models/LocationModel.php @@ -10,6 +10,7 @@ use Manuxi\SuluEventBundle\Entity\Location; use Manuxi\SuluEventBundle\Entity\Traits\ArrayPropertyTrait; use Manuxi\SuluEventBundle\Repository\LocationRepository; +use Sulu\Bundle\MediaBundle\Entity\MediaRepositoryInterface; use Sulu\Component\Rest\Exception\EntityNotFoundException; use Symfony\Component\HttpFoundation\Request; @@ -18,14 +19,18 @@ class LocationModel implements LocationModelInterface use ArrayPropertyTrait; private $locationRepository; + private $mediaRepository; public function __construct( - LocationRepository $locationRepository + LocationRepository $locationRepository, + MediaRepositoryInterface $mediaRepository ) { $this->locationRepository = $locationRepository; + $this->mediaRepository = $mediaRepository; } /** + * @throws EntityNotFoundException * @throws ORMException * @throws OptimisticLockException */ @@ -43,7 +48,7 @@ public function createLocation(Request $request): Location */ public function updateLocation(int $id, Request $request): Location { - $location = $this->getLocation($id, $request); + $location = $this->getLocation($id); $location = $this->mapDataToEntity($location, $request->request->all()); return $this->locationRepository->save($location); } @@ -69,6 +74,9 @@ public function deleteLocation(int $id): void $this->locationRepository->remove($id); } + /** + * @throws EntityNotFoundException + */ private function mapDataToEntity(Location $location, array $data): Location { $name = $this->getProperty($data, 'name'); @@ -91,6 +99,10 @@ private function mapDataToEntity(Location $location, array $data): Location if ($postalCode) { $location->setPostalCode($postalCode); } + $state = $this->getProperty($data, 'state'); + if ($state) { + $location->setState($state); + } $countryCode = $this->getProperty($data, 'countryCode'); if ($countryCode) { $location->setCountryCode($countryCode); @@ -99,6 +111,14 @@ private function mapDataToEntity(Location $location, array $data): Location if ($notes) { $location->setNotes($notes); } + $imageId = $this->getPropertyMulti($data, ['image', 'id']); + if ($imageId) { + $image = $this->mediaRepository->findMediaById((int) $imageId); + if (!$image) { + throw new EntityNotFoundException($this->mediaRepository->getClassName(), $imageId); + } + $location->setImage($image); + } return $location; } } diff --git a/src/Resources/config/controller.xml b/src/Resources/config/controller.xml index 03b3674..753c68f 100644 --- a/src/Resources/config/controller.xml +++ b/src/Resources/config/controller.xml @@ -4,9 +4,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd"> - - + @@ -15,8 +13,7 @@ - + @@ -29,8 +26,7 @@ - + diff --git a/src/Resources/config/forms/location_details.xml b/src/Resources/config/forms/location_details.xml index 56cc649..abe3b6c 100644 --- a/src/Resources/config/forms/location_details.xml +++ b/src/Resources/config/forms/location_details.xml @@ -6,12 +6,21 @@ location_details - + sulu_admin.name + + + sulu_event.image + + + + + + sulu_contact.street @@ -30,13 +39,19 @@ - + sulu_contact.city - + + + sulu_contact.state + + + + sulu_contact.country diff --git a/src/Resources/config/lists/events.xml b/src/Resources/config/lists/events.xml index baacd6f..a8a5457 100644 --- a/src/Resources/config/lists/events.xml +++ b/src/Resources/config/lists/events.xml @@ -4,23 +4,23 @@ - Manuxi\SuluEventBundle\Entity\EventTranslation - Manuxi\SuluEventBundle\Entity\Event.translations - Manuxi\SuluEventBundle\Entity\EventTranslation.locale = :locale + %sulu.model.event_translation.class% + %sulu.model.event.class%.translations + %sulu.model.event_translation.class%.locale = :locale - Manuxi\SuluEventBundle\Entity\Location - Manuxi\SuluEventBundle\Entity\Event.location + %sulu.model.location.class% + %sulu.model.event.class%.location %sulu.model.user.class%_changer - Manuxi\SuluEventBundle\Entity\EventTranslation.changer + %sulu.model.event_translation.class%.changer %sulu.model.contact.class%_changer @@ -31,7 +31,7 @@ %sulu.model.user.class%_creator - Manuxi\SuluEventBundle\Entity\EventTranslation.creator + %sulu.model.event_translation.class%.creator %sulu.model.contact.class%_creator @@ -42,55 +42,68 @@ id - Manuxi\SuluEventBundle\Entity\Event + %sulu.model.event.class% title - Manuxi\SuluEventBundle\Entity\EventTranslation + %sulu.model.event_translation.class% + + id + SuluMediaBundle:Media + + + SuluMediaBundle:Media + %sulu.model.event.class%.image + + + + + + name - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% teaser - Manuxi\SuluEventBundle\Entity\EventTranslation + %sulu.model.event_translation.class% description - Manuxi\SuluEventBundle\Entity\EventTranslation + %sulu.model.event_translation.class% enabled - Manuxi\SuluEventBundle\Entity\Event + %sulu.model.event.class% startDate - Manuxi\SuluEventBundle\Entity\Event + %sulu.model.event.class% endDate - Manuxi\SuluEventBundle\Entity\Event + %sulu.model.event.class% created - Manuxi\SuluEventBundle\Entity\EventTranslation + %sulu.model.event_translation.class% @@ -112,7 +125,7 @@ changed - Manuxi\SuluEventBundle\Entity\EventTranslation + %sulu.model.event_translation.class% diff --git a/src/Resources/config/lists/locations.xml b/src/Resources/config/lists/locations.xml index 59b5c1f..ac51306 100644 --- a/src/Resources/config/lists/locations.xml +++ b/src/Resources/config/lists/locations.xml @@ -5,42 +5,60 @@ id - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% name - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% + + + + id + SuluMediaBundle:Media + + + SuluMediaBundle:Media + %sulu.model.location.class%.image + + + + street - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% number - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% postalCode - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% city - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% + + + + state + %sulu.model.location.class% countryCode - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% notes - Manuxi\SuluEventBundle\Entity\Location + %sulu.model.location.class% diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 590e67f..0914bf0 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -25,6 +25,7 @@ + @@ -118,6 +119,7 @@ + diff --git a/tests/Unit/Entity/LocationTest.php b/tests/Unit/Entity/LocationTest.php index e154e7f..eae3dde 100644 --- a/tests/Unit/Entity/LocationTest.php +++ b/tests/Unit/Entity/LocationTest.php @@ -6,6 +6,7 @@ use Manuxi\SuluEventBundle\Entity\Location; use PHPUnit\Framework\TestCase; +use Sulu\Bundle\MediaBundle\Entity\MediaInterface; class LocationTest extends TestCase { @@ -19,17 +20,17 @@ protected function setUp(): void public function testName(): void { $this->assertNull($this->location->getName()); - $this->assertSame($this->location, $this->location->setName('Sulu GmbH')); + $this->assertSame($this->location, $this->location->setName('Schlosshotel')); $this->assertNotNull($this->location->getName()); - $this->assertSame('Sulu GmbH', $this->location->getName()); + $this->assertSame('Schlosshotel', $this->location->getName()); } public function testStreet(): void { $this->assertNull($this->location->getStreet()); - $this->assertSame($this->location, $this->location->setStreet('Teststreet')); + $this->assertSame($this->location, $this->location->setStreet('Luetzowplatz')); $this->assertNotNull($this->location->getStreet()); - $this->assertSame('Teststreet', $this->location->getStreet()); + $this->assertSame('Luetzowplatz', $this->location->getStreet()); } public function testNumber(): void @@ -43,24 +44,53 @@ public function testNumber(): void public function testPostalCode(): void { $this->assertNull($this->location->getPostalCode()); - $this->assertSame($this->location, $this->location->setPostalCode('6850')); + $this->assertSame($this->location, $this->location->setPostalCode('54636')); $this->assertNotNull($this->location->getPostalCode()); - $this->assertSame('6850', $this->location->getPostalCode()); + $this->assertSame('54636', $this->location->getPostalCode()); } public function testCity(): void { $this->assertNull($this->location->getCity()); - $this->assertSame($this->location, $this->location->setCity('Dornbirn')); + $this->assertSame($this->location, $this->location->setCity('Wiersdorf')); $this->assertNotNull($this->location->getCity()); - $this->assertSame('Dornbirn', $this->location->getCity()); + $this->assertSame('Wiersdorf', $this->location->getCity()); + } + + public function testState(): void + { + $this->assertNull($this->location->getState()); + $this->assertSame($this->location, $this->location->setState('NRW')); + $this->assertNotNull($this->location->getState()); + $this->assertSame('NRW', $this->location->getState()); } public function testCountryCode(): void { $this->assertNull($this->location->getCountryCode()); - $this->assertSame($this->location, $this->location->setCountryCode('AT')); + $this->assertSame($this->location, $this->location->setCountryCode('DE')); $this->assertNotNull($this->location->getCountryCode()); - $this->assertSame('AT', $this->location->getCountryCode()); + $this->assertSame('DE', $this->location->getCountryCode()); + } + + public function testNotes(): void + { + $notes = 'Lorem ipsum dolor sit amet.'; + $this->assertNull($this->location->getNotes()); + $this->assertSame($this->location, $this->location->setNotes($notes)); + $this->assertNotNull($this->location->getNotes()); + $this->assertSame($notes, $this->location->getNotes()); + } + + public function testImage(): void + { + $image = $this->prophesize(MediaInterface::class); + $image->getId()->willReturn(42); + + $this->assertNull($this->location->getImage()); + $this->assertNull($this->location->getImageData()); + $this->assertSame($this->location, $this->location->setImage($image->reveal())); + $this->assertSame($image->reveal(), $this->location->getImage()); + $this->assertSame(['id' => 42], $this->location->getImageData()); } }