diff --git a/Content/ContentTypeResolver/BlockResolver.php b/Content/ContentTypeResolver/BlockResolver.php index 42fdbeb..da6fe31 100644 --- a/Content/ContentTypeResolver/BlockResolver.php +++ b/Content/ContentTypeResolver/BlockResolver.php @@ -29,7 +29,7 @@ public static function getContentType(): string /** * @var ContentResolverInterface */ - private $resolver; + private $contentResolver; /** * @var \Traversable @@ -41,7 +41,7 @@ public static function getContentType(): string */ public function __construct(ContentResolverInterface $contentResolver, \Traversable $blockVisitors) { - $this->resolver = $contentResolver; + $this->contentResolver = $contentResolver; $this->blockVisitors = $blockVisitors; } @@ -74,7 +74,7 @@ public function resolve($data, PropertyInterface $property, string $locale, arra $view[$i] = []; foreach ($blockPropertyType->getChildProperties() as $childProperty) { - $contentView = $this->resolver->resolve($childProperty->getValue(), $childProperty, $locale, $attributes); + $contentView = $this->contentResolver->resolve($childProperty->getValue(), $childProperty, $locale, $attributes); $content[$i][$childProperty->getName()] = $contentView->getContent(); $view[$i][$childProperty->getName()] = $contentView->getView(); diff --git a/Content/ContentTypeResolver/ImageMapResolver.php b/Content/ContentTypeResolver/ImageMapResolver.php new file mode 100644 index 0000000..3144040 --- /dev/null +++ b/Content/ContentTypeResolver/ImageMapResolver.php @@ -0,0 +1,86 @@ +mediaManager = $mediaManager; + $this->mediaSerializer = $mediaSerializer; + $this->contentResolver = $contentResolver; + } + + public function resolve($data, PropertyInterface $property, string $locale, array $attributes = []): ContentView + { + $imageId = $data['imageId'] ?? null; + $hotspots = $data['hotspots'] ?? []; + + $content = []; + $view = []; + if ($imageId) { + $media = $this->mediaManager->getById($imageId, $locale); + $content['image'] = $this->mediaSerializer->serialize($media->getEntity(), $locale); + $view['image'] = ['id' => $imageId]; + } + + foreach ($hotspots as $i => $hotspot) { + $hotspotView = []; + + $propertyType = $property->initProperties($i, $hotspot['type']); + foreach ($propertyType->getChildProperties() as $childProperty) { + $key = $childProperty->getName(); + + $childProperty->setValue($hotspot[$key] ?? null); + $result = $this->contentResolver->resolve($childProperty->getValue(), $childProperty, $locale, $attributes); + $hotspot[$key] = $result->getContent(); + $hotspotView[$key] = $result->getView(); + } + + $content['hotspots'][] = $hotspot; + $view['hotspots'][] = $hotspotView; + } + + return new ContentView($content, $view); + } +} diff --git a/Resources/config/content-type-resolvers.xml b/Resources/config/content-type-resolvers.xml index c560a57..508b1d5 100644 --- a/Resources/config/content-type-resolvers.xml +++ b/Resources/config/content-type-resolvers.xml @@ -190,5 +190,17 @@ + + + + + + + + diff --git a/Tests/Unit/Content/ContentTypeResolver/ImageMapResolverTest.php b/Tests/Unit/Content/ContentTypeResolver/ImageMapResolverTest.php new file mode 100644 index 0000000..713b377 --- /dev/null +++ b/Tests/Unit/Content/ContentTypeResolver/ImageMapResolverTest.php @@ -0,0 +1,337 @@ +mediaManager = $this->prophesize(MediaManagerInterface::class); + $this->mediaSerializer = $this->prophesize(MediaSerializerInterface::class); + $this->contentResolver = $this->prophesize(ContentResolverInterface::class); + + $this->imageMapResolver = new ImageMapResolver( + $this->mediaManager->reveal(), + $this->mediaSerializer->reveal(), + $this->contentResolver->reveal() + ); + } + + public function testGetContentType(): void + { + self::assertSame('image_map', $this->imageMapResolver::getContentType()); + } + + public function testResolve(): void + { + $locale = 'en'; + $data = [ + 'imageId' => 1, + 'hotspots' => [ + [ + 'type' => 'basic', + 'hotspot' => [ + 'type' => 'point', + 'left' => 1, + 'top' => 1, + 'radius' => 0, + ], + 'title' => 'Test Point', + 'description' => 'Test Point description', + ], + [ + 'type' => 'advanced', + 'hotspot' => [ + 'type' => 'rectangle', + 'width' => 1, + 'height' => 2, + 'left' => 1, + 'top' => 1, + ], + 'media' => [ + 'id' => 1, + ], + 'block_1' => [ + [ + 'type' => 'text-with-image', + 'image' => [ + 'displayOption' => null, + 'id' => 1, + ], + 'title' => 'Example title', + ], + ], + ], + ], + ]; + + /** @var Media|ObjectProphecy $media */ + $media = $this->prophesize(Media::class); + /** @var \Sulu\Bundle\MediaBundle\Entity\Media|ObjectProphecy $mediaEntity */ + $mediaEntity = $this->prophesize(\Sulu\Bundle\MediaBundle\Entity\Media::class); + $media->getEntity() + ->shouldBeCalled() + ->willReturn($mediaEntity->reveal()); + + $this->mediaManager->getById(1, $locale) + ->shouldBeCalled() + ->willReturn($media->reveal()); + $this->mediaSerializer->serialize($mediaEntity, $locale) + ->shouldBeCalled() + ->willReturn([ + 'id' => 1, + 'locale' => 'en', + ]); + + /** @var PropertyInterface|ObjectProphecy $property */ + $property = $this->prophesize(PropertyInterface::class); + + // Basic hotspot + $propertyTypeBasic = $this->prophesize(PropertyType::class); + $property->initProperties(0, 'basic') + ->shouldBeCalled() + ->willReturn($propertyTypeBasic->reveal()); + + $propertyTextLine = $this->prophesize(Property::class); + $propertyTextLine->getName() + ->shouldBeCalled() + ->willReturn('title'); + $propertyTextLine->setValue('Test Point') + ->shouldBeCalled(); + $propertyTextLine->getValue() + ->shouldBeCalled() + ->willReturn('Test Point'); + + $propertyTextArea = $this->prophesize(Property::class); + $propertyTextArea->getName() + ->shouldBeCalled() + ->willReturn('description'); + $propertyTextArea->setValue('Test Point description') + ->shouldBeCalled(); + $propertyTextArea->getValue() + ->shouldBeCalled() + ->willReturn('Test Point description'); + + $propertyTypeBasic->getChildProperties() + ->shouldBeCalled() + ->willReturn([$propertyTextLine->reveal(), $propertyTextArea->reveal()]); + + $contentViewTextLine = new ContentView('Test Point', []); + $contentViewTextArea = new ContentView('Test Point description', []); + + $this->contentResolver->resolve('Test Point', $propertyTextLine, $locale, []) + ->shouldBeCalled() + ->willReturn($contentViewTextLine); + + $this->contentResolver->resolve('Test Point description', $propertyTextArea, $locale, []) + ->shouldBeCalled() + ->willReturn($contentViewTextArea); + + // Advanced hotspot + $propertyTypeAdvanced = $this->prophesize(PropertyType::class); + $property->initProperties(1, 'advanced') + ->shouldBeCalled() + ->willReturn($propertyTypeAdvanced->reveal()); + + $propertyMediaSelection = $this->prophesize(Property::class); + $propertyMediaSelection->getName() + ->shouldBeCalled() + ->willReturn('media'); + $propertyMediaSelection->setValue(['id' => 1]) + ->shouldBeCalled(); + $propertyMediaSelection->getValue() + ->shouldBeCalled() + ->willReturn(['id' => 1]); + + $propertyBlock = $this->prophesize(BlockProperty::class); + $propertyBlock->getName() + ->shouldBeCalled() + ->willReturn('block_1'); + $blockValue = [ + [ + 'type' => 'text-with-image', + 'image' => [ + 'id' => 1, + 'displayOption' => null, + ], + 'title' => 'Example title', + ], + ]; + $propertyBlock->setValue($blockValue) + ->shouldBeCalled(); + $propertyBlock->getValue() + ->shouldBeCalled() + ->willReturn($blockValue); + + $propertyTypeAdvanced->getChildProperties() + ->shouldBeCalled() + ->willReturn([$propertyMediaSelection, $propertyBlock]); + + $contentViewMedia = new ContentView(['id' => 1, 'locale' => 'en'], ['id' => 1]); + $contentViewBlock = new ContentView( + [ + [ + 'type' => 'text-with-image', + 'image' => [ + 'id' => 1, + 'locale' => 'en', + ], + 'title' => 'Example title', + ], + ], + [ + [ + 'image' => [ + 'id' => 1, + 'displayOption' => null, + ], + 'title' => [], + ], + ] + ); + + $this->contentResolver->resolve(['id' => 1], $propertyMediaSelection, $locale, []) + ->shouldBeCalled() + ->willReturn($contentViewMedia); + + $this->contentResolver->resolve($blockValue, $propertyBlock, $locale, []) + ->shouldBeCalled() + ->willReturn($contentViewBlock); + + $contentView = $this->imageMapResolver->resolve($data, $property->reveal(), $locale); + + self::assertSame([ + 'image' => [ + 'id' => 1, + 'locale' => 'en', + ], + 'hotspots' => [ + [ + 'type' => 'basic', + 'hotspot' => [ + 'type' => 'point', + 'left' => 1, + 'top' => 1, + 'radius' => 0, + ], + 'title' => 'Test Point', + 'description' => 'Test Point description', + ], + [ + 'type' => 'advanced', + 'hotspot' => [ + 'type' => 'rectangle', + 'width' => 1, + 'height' => 2, + 'left' => 1, + 'top' => 1, + ], + 'media' => [ + 'id' => 1, + 'locale' => 'en', + ], + 'block_1' => [ + [ + 'type' => 'text-with-image', + 'image' => [ + 'id' => 1, + 'locale' => 'en', + ], + 'title' => 'Example title', + ], + ], + ], + ], + ], $contentView->getContent()); + + self::assertSame([ + 'image' => [ + 'id' => 1, + ], + 'hotspots' => [ + [ + 'title' => [], + 'description' => [], + ], + [ + 'media' => ['id' => 1], + 'block_1' => [ + [ + 'image' => [ + 'id' => 1, + 'displayOption' => null, + ], + 'title' => [], + ], + ], + ], + ], + ], $contentView->getView()); + } + + public function testResolveDataIsNull(): void + { + $locale = 'en'; + $property = $this->prophesize(Property::class); + + $result = $this->imageMapResolver->resolve(null, $property->reveal(), $locale); + + self::assertSame([], $result->getContent()); + self::assertSame([], $result->getView()); + } + + public function testResolveDataIsEmptyArray(): void + { + $locale = 'en'; + $property = $this->prophesize(Property::class); + + $result = $this->imageMapResolver->resolve([], $property->reveal(), $locale); + + self::assertSame([], $result->getContent()); + self::assertSame([], $result->getView()); + } +}