Skip to content

Commit

Permalink
Handle block settings by calling block-visitors in BlockResolver (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasnatter committed Jan 14, 2021
1 parent 2c18505 commit 91a57e1
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 23 deletions.
34 changes: 30 additions & 4 deletions Content/ContentTypeResolver/BlockResolver.php
Expand Up @@ -17,6 +17,7 @@
use Sulu\Bundle\HeadlessBundle\Content\ContentView;
use Sulu\Component\Content\Compat\Block\BlockPropertyInterface;
use Sulu\Component\Content\Compat\PropertyInterface;
use Sulu\Component\Content\Types\Block\BlockVisitorInterface;

class BlockResolver implements ContentTypeResolverInterface
{
Expand All @@ -30,26 +31,51 @@ public static function getContentType(): string
*/
private $resolver;

public function __construct(ContentResolverInterface $resolver)
/**
* @var \Traversable<BlockVisitorInterface>
*/
private $blockVisitors;

/**
* @param \Traversable<BlockVisitorInterface> $blockVisitors
*/
public function __construct(ContentResolverInterface $contentResolver, \Traversable $blockVisitors)
{
$this->resolver = $resolver;
$this->resolver = $contentResolver;
$this->blockVisitors = $blockVisitors;
}

/**
* @param BlockPropertyInterface $property
*/
public function resolve($data, PropertyInterface $property, string $locale, array $attributes = []): ContentView
{
$content = [];
$view = [];
$blockPropertyTypes = [];
for ($i = 0; $i < $property->getLength(); ++$i) {
$blockPropertyType = $property->getProperties($i);

foreach ($this->blockVisitors as $blockVisitor) {
$blockPropertyType = $blockVisitor->visit($blockPropertyType);

if (!$blockPropertyType) {
break;
}
}

if ($blockPropertyType) {
$blockPropertyTypes[] = $blockPropertyType;
}
}

$content = [];
$view = [];
foreach ($blockPropertyTypes as $i => $blockPropertyType) {
$content[$i] = ['type' => $blockPropertyType->getName()];
$view[$i] = [];

foreach ($blockPropertyType->getChildProperties() as $childProperty) {
$contentView = $this->resolver->resolve($childProperty->getValue(), $childProperty, $locale, $attributes);

$content[$i][$childProperty->getName()] = $contentView->getContent();
$view[$i][$childProperty->getName()] = $contentView->getView();
}
Expand Down
1 change: 1 addition & 0 deletions Resources/config/content-type-resolvers.xml
Expand Up @@ -128,6 +128,7 @@
lazy="true"
>
<argument type="service" id="sulu_headless.content_resolver"/>
<argument type="tagged" tag="sulu_content.block_visitor" />

<tag name="sulu_headless.content_type_resolver"/>
</service>
Expand Down
144 changes: 125 additions & 19 deletions Tests/Unit/Content/ContentTypeResolver/BlockResolverTest.php
Expand Up @@ -14,13 +14,15 @@
namespace Sulu\Bundle\HeadlessBundle\Tests\Unit\Content\ContentTypeResolver;

use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Sulu\Bundle\HeadlessBundle\Content\ContentResolverInterface;
use Sulu\Bundle\HeadlessBundle\Content\ContentTypeResolver\BlockResolver;
use Sulu\Bundle\HeadlessBundle\Content\ContentView;
use Sulu\Component\Content\Compat\Block\BlockPropertyInterface;
use Sulu\Component\Content\Compat\Block\BlockPropertyType;
use Sulu\Component\Content\Compat\PropertyInterface;
use Sulu\Component\Content\Types\Block\BlockVisitorInterface;

class BlockResolverTest extends TestCase
{
Expand All @@ -29,6 +31,16 @@ class BlockResolverTest extends TestCase
*/
private $contentResolver;

/**
* @var BlockVisitorInterface|ObjectProphecy
*/
private $blockVisitor1;

/**
* @var BlockVisitorInterface|ObjectProphecy
*/
private $blockVisitor2;

/**
* @var BlockResolver
*/
Expand All @@ -37,8 +49,16 @@ class BlockResolverTest extends TestCase
protected function setUp(): void
{
$this->contentResolver = $this->prophesize(ContentResolverInterface::class);
$this->blockVisitor1 = $this->prophesize(BlockVisitorInterface::class);
$this->blockVisitor2 = $this->prophesize(BlockVisitorInterface::class);

$this->blockResolver = new BlockResolver($this->contentResolver->reveal());
$this->blockVisitor1->visit(Argument::any())->will(function ($arguments) {return $arguments[0]; });
$this->blockVisitor2->visit(Argument::any())->will(function ($arguments) {return $arguments[0]; });

$this->blockResolver = new BlockResolver(
$this->contentResolver->reveal(),
new \ArrayIterator([$this->blockVisitor1->reveal(), $this->blockVisitor2->reveal()])
);
}

public function testGetContentType(): void
Expand All @@ -51,27 +71,40 @@ public function testResolve(): void
$titleProperty = $this->prophesize(PropertyInterface::class);
$titleProperty->getName()->willReturn('title');
$titleProperty->getValue()->willReturn('test-123');

$titleType = $this->prophesize(BlockPropertyType::class);
$titleType->getName()->willReturn('title');
$titleType->getChildProperties()->willReturn([$titleProperty->reveal()]);

$titleContentView = $this->prophesize(ContentView::class);
$titleContentView->getContent()->willReturn('test-123');
$titleContentView->getView()->willReturn([]);

$this->contentResolver->resolve(
'test-123',
$titleProperty->reveal(),
'en',
['webspaceKey' => 'sulu_io']
)->willReturn($titleContentView->reveal());

$mediaProperty = $this->prophesize(PropertyInterface::class);
$mediaProperty->getName()->willReturn('media');
$mediaProperty->getValue()->willReturn(['ids' => [1, 2, 3]]);

$contentView1 = $this->prophesize(ContentView::class);
$contentView1->getContent()->willReturn('test-123');
$contentView1->getView()->willReturn([]);

$this->contentResolver->resolve('test-123', $titleProperty->reveal(), 'en', ['webspaceKey' => 'sulu_io'])
->willReturn($contentView1->reveal());
$mediaType = $this->prophesize(BlockPropertyType::class);
$mediaType->getName()->willReturn('media');
$mediaType->getChildProperties()->willReturn([$mediaProperty->reveal()]);

$contentView2 = $this->prophesize(ContentView::class);
$contentView2->getContent()->willReturn(['media1', 'media2', 'media3']);
$contentView2->getView()->willReturn(['ids' => [1, 2, 3]]);
$mediaContentView = $this->prophesize(ContentView::class);
$mediaContentView->getContent()->willReturn(['media1', 'media2', 'media3']);
$mediaContentView->getView()->willReturn(['ids' => [1, 2, 3]]);

$this->contentResolver->resolve(
['ids' => [1, 2, 3]],
$mediaProperty->reveal(),
'en',
['webspaceKey' => 'sulu_io']
)->willReturn($contentView2->reveal());
)->willReturn($mediaContentView->reveal());

$data = [
[
Expand All @@ -88,16 +121,13 @@ public function testResolve(): void
$blockProperty->getValue()->willReturn($data);
$blockProperty->getLength()->willReturn(2);

$titleType = $this->prophesize(BlockPropertyType::class);
$titleType->getName()->willReturn('title');
$titleType->getChildProperties()->willReturn([$titleProperty->reveal()]);

$mediaType = $this->prophesize(BlockPropertyType::class);
$mediaType->getName()->willReturn('media');
$mediaType->getChildProperties()->willReturn([$mediaProperty->reveal()]);

$blockProperty->getProperties(0)->willReturn($titleType->reveal());
$this->blockVisitor1->visit($titleType->reveal())->willReturn($titleType->reveal());
$this->blockVisitor2->visit($titleType->reveal())->willReturn($titleType->reveal());

$blockProperty->getProperties(1)->willReturn($mediaType->reveal());
$this->blockVisitor1->visit($mediaType->reveal())->willReturn($mediaType->reveal());
$this->blockVisitor2->visit($mediaType->reveal())->willReturn($mediaType->reveal());

$result = $this->blockResolver->resolve($data, $blockProperty->reveal(), 'en', ['webspaceKey' => 'sulu_io']);

Expand Down Expand Up @@ -127,4 +157,80 @@ public function testResolve(): void
$result->getView()
);
}

public function testResolveWithSkips(): void
{
$titleProperty = $this->prophesize(PropertyInterface::class);
$titleProperty->getName()->willReturn('title');
$titleProperty->getValue()->willReturn('test-123');

$titleType = $this->prophesize(BlockPropertyType::class);
$titleType->getName()->willReturn('title');
$titleType->getChildProperties()->willReturn([$titleProperty->reveal()]);

$titleContentView = $this->prophesize(ContentView::class);
$titleContentView->getContent()->willReturn('test-123');
$titleContentView->getView()->willReturn([]);

$this->contentResolver->resolve(
'test-123',
$titleProperty->reveal(),
'en',
['webspaceKey' => 'sulu_io']
)->willReturn($titleContentView->reveal());

$mediaProperty = $this->prophesize(PropertyInterface::class);
$mediaProperty->getName()->willReturn('media');
$mediaProperty->getValue()->willReturn(['ids' => [1, 2, 3]]);

$mediaType = $this->prophesize(BlockPropertyType::class);
$mediaType->getName()->willReturn('media');
$mediaType->getChildProperties()->willReturn([$mediaProperty->reveal()]);

$mediaContentView = $this->prophesize(ContentView::class);
$mediaContentView->getContent()->willReturn(['media1', 'media2', 'media3']);
$mediaContentView->getView()->willReturn(['ids' => [1, 2, 3]]);

$this->contentResolver->resolve(
['ids' => [1, 2, 3]],
$mediaProperty->reveal(),
'en',
['webspaceKey' => 'sulu_io']
)->willReturn($mediaContentView->reveal());

$data = [
[
'type' => 'title',
'title' => 'test-123',
],
[
'type' => 'media',
'media' => ['ids' => [1, 2, 3]],
],
];

$blockProperty = $this->prophesize(BlockPropertyInterface::class);
$blockProperty->getValue()->willReturn($data);
$blockProperty->getLength()->willReturn(2);

$blockProperty->getProperties(0)->willReturn($titleType->reveal());
$this->blockVisitor1->visit($titleType->reveal())->willReturn(null);
$this->blockVisitor2->visit($titleType->reveal())->willReturn($titleType->reveal());

$blockProperty->getProperties(1)->willReturn($mediaType->reveal());
$this->blockVisitor1->visit($mediaType->reveal())->willReturn($mediaType->reveal());
$this->blockVisitor2->visit($mediaType->reveal())->willReturn(null);

$result = $this->blockResolver->resolve($data, $blockProperty->reveal(), 'en', ['webspaceKey' => 'sulu_io']);

$this->assertInstanceOf(ContentView::class, $result);
$this->assertSame(
[],
$result->getContent()
);
$this->assertSame(
[],
$result->getView()
);
}
}

0 comments on commit 91a57e1

Please sign in to comment.