From 3e2bde343d16f7a6161f752ff44dacd075dcfb16 Mon Sep 17 00:00:00 2001 From: Oliver Kossin Date: Sat, 21 Nov 2020 19:21:49 +0100 Subject: [PATCH 1/3] [ADD] "single_snippet_selection" content type resolver --- .../SingleSnippetSelectionResolver.php | 115 ++++++++ Resources/config/content-type-resolvers.xml | 12 + .../SingleSnippetSelectionResolverTest.php | 268 ++++++++++++++++++ 3 files changed, 395 insertions(+) create mode 100644 Content/ContentTypeResolver/SingleSnippetSelectionResolver.php create mode 100644 Tests/Unit/Content/ContentTypeResolver/SingleSnippetSelectionResolverTest.php diff --git a/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php new file mode 100644 index 0000000..7066860 --- /dev/null +++ b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php @@ -0,0 +1,115 @@ +contentMapper = $contentMapper; + $this->structureResolver = $structureResolver; + $this->defaultSnippetManager = $defaultSnippetManager; + } + + public static function getContentType(): string + { + return 'single_snippet_selection'; + } + + /** + * {@inheritdoc} + */ + public function resolve($data, PropertyInterface $property, string $locale, array $attributes = []): ContentView + { + /** @var StructureBridge $structure */ + $structure = $property->getStructure(); + $webspaceKey = $structure->getWebspaceKey(); + $shadowLocale = $structure->getIsShadow() ? $structure->getShadowBaseLanguage() : null; + + $params = $property->getParams(); + /** @var bool $loadExcerpt */ + $loadExcerpt = isset($params['loadExcerpt']) ? $params['loadExcerpt']->getValue() : false; + /** @var string $defaultArea */ + $defaultArea = isset($params['default']) ? $params['default']->getValue() : null; + + $snippetId = $data ?? null; + if (empty($snippetId) && $defaultArea) { + $defaultSnippetId = $this->getDefaultSnippetId($webspaceKey, $defaultArea, $locale); + $snippetId = $defaultSnippetId ?: null; + } + + if (null === $snippetId) { + return new ContentView(null); + } + + /** @var SnippetBridge $snippet */ + $snippet = $this->contentMapper->load($snippetId, $webspaceKey, $locale); + + if (!$snippet->getHasTranslation() && null !== $shadowLocale) { + /** @var SnippetBridge $snippet */ + $snippet = $this->contentMapper->load($snippetId, $webspaceKey, $shadowLocale); + } + + $snippet->setIsShadow(null !== $shadowLocale); + $snippet->setShadowBaseLanguage($shadowLocale); + + $resolvedSnippet = $this->structureResolver->resolve($snippet, $locale, $loadExcerpt); + + return new ContentView($resolvedSnippet, ['id' => $data]); + } + + private function getDefaultSnippetId(string $webspaceKey, string $snippetArea, string $locale): ?string + { + try { + /** @var SnippetDocument|null $snippet */ + $snippet = $this->defaultSnippetManager->load($webspaceKey, $snippetArea, $locale); + } catch (WrongSnippetTypeException $exception) { + return null; + } + + if (!$snippet) { + return null; + } + + return $snippet->getUuid(); + } +} diff --git a/Resources/config/content-type-resolvers.xml b/Resources/config/content-type-resolvers.xml index 41d4db1..1a26cc7 100644 --- a/Resources/config/content-type-resolvers.xml +++ b/Resources/config/content-type-resolvers.xml @@ -157,5 +157,17 @@ + + + + + + + + diff --git a/Tests/Unit/Content/ContentTypeResolver/SingleSnippetSelectionResolverTest.php b/Tests/Unit/Content/ContentTypeResolver/SingleSnippetSelectionResolverTest.php new file mode 100644 index 0000000..131808f --- /dev/null +++ b/Tests/Unit/Content/ContentTypeResolver/SingleSnippetSelectionResolverTest.php @@ -0,0 +1,268 @@ +contentMapper = $this->prophesize(ContentMapperInterface::class); + $this->structureResolver = $this->prophesize(StructureResolverInterface::class); + $this->defaultSnippetManager = $this->prophesize(DefaultSnippetManagerInterface::class); + + $this->snippetSelectionResolver = new SingleSnippetSelectionResolver( + $this->contentMapper->reveal(), + $this->structureResolver->reveal(), + $this->defaultSnippetManager->reveal() + ); + } + + public function testGetContentType(): void + { + self::assertSame('single_snippet_selection', $this->snippetSelectionResolver::getContentType()); + } + + public function testResolveWithExcerpt(): void + { + $structure = $this->prophesize(StructureBridge::class); + $structure->getWebspaceKey()->willReturn('webspace-key'); + $structure->getIsShadow()->willReturn(false); + + $property = $this->prophesize(PropertyInterface::class); + $property->getStructure()->willReturn($structure->reveal()); + $property->getParams()->willReturn([ + 'loadExcerpt' => new PropertyParameter('loadExcerpt', true), + ]); + + $snippet1 = $this->prophesize(SnippetBridge::class); + $snippet1->getHasTranslation()->willReturn(true); + $snippet1->setIsShadow(false)->shouldBeCalled(); + $snippet1->setShadowBaseLanguage(null)->shouldBeCalled(); + + $this->contentMapper->load('snippet-1', 'webspace-key', 'en')->willReturn($snippet1->reveal()); + $this->structureResolver->resolve($snippet1->reveal(), 'en', true)->willReturn([ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ]); + + $result = $this->snippetSelectionResolver->resolve('snippet-1', $property->reveal(), 'en', []); + $this->assertInstanceOf(ContentView::class, $result); + $this->assertSame( + [ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ], + $result->getContent() + ); + + $this->assertSame( + ['id' => 'snippet-1'], + $result->getView() + ); + } + + public function testResolveShadowLocale(): void + { + $structure = $this->prophesize(StructureBridge::class); + $structure->getWebspaceKey()->willReturn('webspace-key'); + $structure->getIsShadow()->willReturn(true); + $structure->getShadowBaseLanguage()->willReturn('de'); + + $property = $this->prophesize(PropertyInterface::class); + $property->getStructure()->willReturn($structure->reveal()); + $property->getParams()->willReturn([]); + + $snippet1 = $this->prophesize(SnippetBridge::class); + $snippet1->getHasTranslation()->willReturn(true); + $snippet1->setIsShadow(true)->shouldBeCalled(); + $snippet1->setShadowBaseLanguage('de')->shouldBeCalled(); + + $this->contentMapper->load('snippet-1', 'webspace-key', 'en')->willReturn($snippet1->reveal()); + $this->structureResolver->resolve($snippet1->reveal(), 'en', false)->willReturn([ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ]); + + $result = $this->snippetSelectionResolver->resolve('snippet-1', $property->reveal(), 'en', []); + $this->assertInstanceOf(ContentView::class, $result); + $this->assertSame( + [ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ], + $result->getContent() + ); + + $this->assertSame( + ['id' => 'snippet-1'], + $result->getView() + ); + } + + public function testResolveShadowLocaleNoTranslation(): void + { + $structure = $this->prophesize(StructureBridge::class); + $structure->getWebspaceKey()->willReturn('webspace-key'); + $structure->getIsShadow()->willReturn(true); + $structure->getShadowBaseLanguage()->willReturn('de'); + + $property = $this->prophesize(PropertyInterface::class); + $property->getStructure()->willReturn($structure->reveal()); + $property->getParams()->willReturn([]); + + $snippet1en = $this->prophesize(SnippetBridge::class); + $snippet1en->getHasTranslation()->willReturn(false); + + $snippet1de = $this->prophesize(SnippetBridge::class); + $snippet1de->setIsShadow(true)->shouldBeCalled(); + $snippet1de->setShadowBaseLanguage('de')->shouldBeCalled(); + + $this->contentMapper->load('snippet-1', 'webspace-key', 'en')->willReturn($snippet1en->reveal()); + $this->contentMapper->load('snippet-1', 'webspace-key', 'de')->willReturn($snippet1de->reveal()); + $this->structureResolver->resolve($snippet1de->reveal(), 'en', false)->willReturn([ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ]); + + $result = $this->snippetSelectionResolver->resolve('snippet-1', $property->reveal(), 'en', []); + $this->assertInstanceOf(ContentView::class, $result); + $this->assertSame( + [ + 'id' => 'snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ], + $result->getContent() + ); + + $this->assertSame( + ['id' => 'snippet-1'], + $result->getView() + ); + } + + public function testResolveDataIsNull(): void + { + $structure = $this->prophesize(StructureBridge::class); + $structure->getWebspaceKey()->willReturn('webspace-key'); + $structure->getIsShadow()->willReturn(false); + + $property = $this->prophesize(PropertyInterface::class); + $property->getStructure()->willReturn($structure->reveal()); + $property->getParams()->willReturn([]); + + $result = $this->snippetSelectionResolver->resolve(null, $property->reveal(), 'en', []); + $this->assertInstanceOf(ContentView::class, $result); + $this->assertNull( + $result->getContent() + ); + + $this->assertSame( + [], + $result->getView() + ); + } + + public function testResolveDataIsNullWithDefaultArea(): void + { + $structure = $this->prophesize(StructureBridge::class); + $structure->getWebspaceKey()->willReturn('webspace-key'); + $structure->getIsShadow()->willReturn(false); + + $property = $this->prophesize(PropertyInterface::class); + $property->getStructure()->willReturn($structure->reveal()); + $property->getParams()->willReturn([ + 'default' => new PropertyParameter('default', 'test-snippet-area'), + ]); + + $defaultSnippetDocument = $this->prophesize(SnippetDocument::class); + $defaultSnippetDocument->getUuid()->willReturn('default-snippet-1'); + $this->defaultSnippetManager->load('webspace-key', 'test-snippet-area', 'en') + ->willReturn($defaultSnippetDocument->reveal()); + + $defaultSnippet = $this->prophesize(SnippetBridge::class); + $defaultSnippet->getHasTranslation()->willReturn(true); + $defaultSnippet->setIsShadow(false)->shouldBeCalled(); + $defaultSnippet->setShadowBaseLanguage(null)->shouldBeCalled(); + + $this->contentMapper->load('default-snippet-1', 'webspace-key', 'en')->willReturn($defaultSnippet->reveal()); + $this->structureResolver->resolve($defaultSnippet->reveal(), 'en', false)->willReturn([ + 'id' => 'default-snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ]); + + $result = $this->snippetSelectionResolver->resolve(null, $property->reveal(), 'en', []); + $this->assertInstanceOf(ContentView::class, $result); + $this->assertSame( + [ + 'id' => 'default-snippet-1', + 'template' => 'test', + 'content' => [], + 'view' => [], + ], + $result->getContent() + ); + + $this->assertSame( + ['id' => null], + $result->getView() + ); + } +} From 0f86267d37d84e6d81ca69c8f9453b27dcebb7ec Mon Sep 17 00:00:00 2001 From: Oliver Kossin Date: Mon, 23 Nov 2020 11:26:50 +0100 Subject: [PATCH 2/3] add review --- Content/ContentTypeResolver/SingleSnippetSelectionResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php index 7066860..0ddf765 100644 --- a/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php +++ b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php @@ -77,7 +77,7 @@ public function resolve($data, PropertyInterface $property, string $locale, arra $snippetId = $defaultSnippetId ?: null; } - if (null === $snippetId) { + if (empty($snippetIds)) { return new ContentView(null); } From 3845227dbbbb401319b4433c937da956396e8afe Mon Sep 17 00:00:00 2001 From: Oliver Kossin Date: Mon, 23 Nov 2020 11:28:42 +0100 Subject: [PATCH 3/3] fix typo --- Content/ContentTypeResolver/SingleSnippetSelectionResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php index 0ddf765..b7fccb3 100644 --- a/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php +++ b/Content/ContentTypeResolver/SingleSnippetSelectionResolver.php @@ -77,7 +77,7 @@ public function resolve($data, PropertyInterface $property, string $locale, arra $snippetId = $defaultSnippetId ?: null; } - if (empty($snippetIds)) { + if (empty($snippetId)) { return new ContentView(null); }