Skip to content

Commit

Permalink
Add Link resolver (#111)
Browse files Browse the repository at this point in the history
* Add Link resolver

* increase min requirement to sulu ^2.4
  • Loading branch information
Prokyonn authored May 24, 2022
1 parent 144e9e7 commit dbb306a
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 2 deletions.
106 changes: 106 additions & 0 deletions Content/ContentTypeResolver/LinkResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\HeadlessBundle\Content\ContentTypeResolver;

use Sulu\Bundle\HeadlessBundle\Content\ContentView;
use Sulu\Bundle\MarkupBundle\Markup\Link\LinkProviderPoolInterface;
use Sulu\Component\Content\Compat\PropertyInterface;
use Sulu\Component\Content\Types\Link;

class LinkResolver implements ContentTypeResolverInterface
{
/**
* @var LinkProviderPoolInterface
*/
private $linkProviderPool;

public static function getContentType(): string
{
return 'link';
}

public function __construct(
LinkProviderPoolInterface $linkProviderPool
) {
$this->linkProviderPool = $linkProviderPool;
}

public function resolve($data, PropertyInterface $property, string $locale, array $attributes = []): ContentView
{
$content = $this->getContentData($property);
$view = $this->getViewData($property);

return new ContentView($content, $view);
}

/**
* @return array{
* provider?: string,
* locale?: string,
* target?: string,
* title?: string
* }
*/
private function getViewData(PropertyInterface $property): array
{
$value = $property->getValue();

if (!$value) {
return [];
}

$result = [
'provider' => $value['provider'],
'locale' => $value['locale'],
];

if (isset($value['target'])) {
$result['target'] = $value['target'];
}

if (isset($value['title'])) {
$result['title'] = $value['title'];
}

return $result;
}

private function getContentData(PropertyInterface $property): ?string
{
$value = $property->getValue();

if (!$value || !isset($value['provider'])) {
return null;
}

if (Link::LINK_TYPE_EXTERNAL === $value['provider']) {
return $value['href'];
}

$provider = $this->linkProviderPool->getProvider($value['provider']);

$linkItems = $provider->preload([$value['href']], $value['locale']);

if (0 === \count($linkItems)) {
return null;
}

$url = reset($linkItems)->getUrl();
if (isset($value['anchor'])) {
$url = sprintf('%s#%s', $url, $value['anchor']);
}

return $url;
}
}
10 changes: 10 additions & 0 deletions Resources/config/content-type-resolvers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@
<tag name="sulu_headless.content_type_resolver"/>
</service>

<service
id="sulu_headless.content_resolver.link"
class="Sulu\Bundle\HeadlessBundle\Content\ContentTypeResolver\LinkResolver"
lazy="true"
>
<argument type="service" id="sulu_markup.link_tag.provider_pool"/>

<tag name="sulu_headless.content_type_resolver"/>
</service>

<service
id="sulu_headless.content_resolver.text_editor"
class="Sulu\Bundle\HeadlessBundle\Content\ContentTypeResolver\TextEditorResolver"
Expand Down
2 changes: 1 addition & 1 deletion Tests/Application/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function getProjectDir(): string
/**
* @return array<string, mixed>
*/
protected function getKernelParameters()
protected function getKernelParameters(): array
{
$parameters = parent::getKernelParameters();

Expand Down
116 changes: 116 additions & 0 deletions Tests/Unit/Content/ContentTypeResolver/LinkResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

declare(strict_types=1);

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\HeadlessBundle\Tests\Unit\Content\ContentTypeResolver;

use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Sulu\Bundle\HeadlessBundle\Content\ContentTypeResolver\LinkResolver;
use Sulu\Bundle\MarkupBundle\Markup\Link\LinkItem;
use Sulu\Bundle\MarkupBundle\Markup\Link\LinkProviderInterface;
use Sulu\Bundle\MarkupBundle\Markup\Link\LinkProviderPoolInterface;
use Sulu\Component\Content\Compat\PropertyInterface;

class LinkResolverTest extends TestCase
{
public function testGetContentType(): void
{
$linkProviderPool = $this->prophesize(LinkProviderPoolInterface::class);
$linkResolver = new LinkResolver($linkProviderPool->reveal());

self::assertSame('link', $linkResolver::getContentType());
}

public function testResolve(): void
{
$providerPool = $this->prophesize(LinkProviderPoolInterface::class);
$provider = $this->prophesize(LinkProviderInterface::class);
$linkResolver = new LinkResolver($providerPool->reveal());

$property = $this->prophesize(PropertyInterface::class);
$property->getValue()
->shouldBeCalled()
->willReturn([
'provider' => 'page',
'target' => '_self',
'anchor' => 'link',
'href' => '76fcf58e-0624-4cf0-85a5-170de9f14252',
'title' => 'Internal Link',
'locale' => 'en',
]);

$providerPool->getProvider(Argument::type('string'))
->shouldBeCalled()
->willReturn($provider->reveal());

$linkItem = new LinkItem(
'76fcf58e-0624-4cf0-85a5-170de9f14252',
'Internal Link',
'https://example.lo/link',
true
);

$provider->preload(['76fcf58e-0624-4cf0-85a5-170de9f14252'], 'en')
->shouldBeCalled()
->willReturn([$linkItem]);

$result = $linkResolver->resolve([], $property->reveal(), 'en');

$this->assertSame('https://example.lo/link#link', $result->getContent());
$this->assertSame([
'provider' => 'page',
'locale' => 'en',
'target' => '_self',
'title' => 'Internal Link',
], $result->getView());
}

public function testResolveMinimal(): void
{
$providerPool = $this->prophesize(LinkProviderPoolInterface::class);
$provider = $this->prophesize(LinkProviderInterface::class);
$linkResolver = new LinkResolver($providerPool->reveal());

$property = $this->prophesize(PropertyInterface::class);
$property->getValue()
->shouldBeCalled()
->willReturn([
'provider' => 'page',
'href' => '76fcf58e-0624-4cf0-85a5-170de9f14252',
'locale' => 'en',
]);

$providerPool->getProvider(Argument::type('string'))
->shouldBeCalled()
->willReturn($provider->reveal());

$linkItem = new LinkItem(
'76fcf58e-0624-4cf0-85a5-170de9f14252',
'Internal Link',
'https://example.lo/link',
true
);

$provider->preload(['76fcf58e-0624-4cf0-85a5-170de9f14252'], 'en')
->shouldBeCalled()
->willReturn([$linkItem]);

$result = $linkResolver->resolve([], $property->reveal(), 'en');

$this->assertSame('https://example.lo/link', $result->getContent());
$this->assertSame([
'provider' => 'page',
'locale' => 'en',
], $result->getView());
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"description": "Bundle that provides controllers and services for using Sulu as headless content management system",
"require": {
"php": "^7.3 || ^8.0",
"sulu/sulu": "^2.2 || ^2.3@dev",
"sulu/sulu": "^2.4",
"symfony/config": "^4.4 || ^5.0",
"symfony/dependency-injection": "^4.4 || ^5.0",
"symfony/framework-bundle": "^4.4 || ^5.0",
Expand Down

0 comments on commit dbb306a

Please sign in to comment.