mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
Refactor Template Events to use a standalone ComponentBlock with a bc manner
This commit is contained in:
parent
a1b7cd5c2d
commit
77af62ec7d
47 changed files with 1375 additions and 494 deletions
|
|
@ -233,7 +233,7 @@
|
||||||
"symfony/runtime": "^6.3.2",
|
"symfony/runtime": "^6.3.2",
|
||||||
"symfony/web-profiler-bundle": "^6.3.2",
|
"symfony/web-profiler-bundle": "^6.3.2",
|
||||||
"symplify/monorepo-builder": "^11.0",
|
"symplify/monorepo-builder": "^11.0",
|
||||||
"vimeo/psalm": "5.15.*",
|
"vimeo/psalm": "5.14.*",
|
||||||
"weirdan/doctrine-psalm-plugin": "^2.8"
|
"weirdan/doctrine-psalm-plugin": "^2.8"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@
|
||||||
<DeprecatedInterface>
|
<DeprecatedInterface>
|
||||||
<errorLevel type="info">
|
<errorLevel type="info">
|
||||||
<referencedClass name="ApiPlatform\Core\Api\IriConverterInterface" /> <!-- deprecated in ApiPlatform 2.7 -->
|
<referencedClass name="ApiPlatform\Core\Api\IriConverterInterface" /> <!-- deprecated in ApiPlatform 2.7 -->
|
||||||
|
<referencedClass name="Sylius\Bundle\ShopBundle\Calculator\OrderItemsSubtotalCalculatorInterface" />
|
||||||
<referencedClass name="Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface" />
|
<referencedClass name="Sylius\Component\Core\Calculator\ProductVariantPriceCalculatorInterface" />
|
||||||
<referencedClass name="Sylius\Component\Core\Provider\ProductVariantsPricesProviderInterface" />
|
<referencedClass name="Sylius\Component\Core\Provider\ProductVariantsPricesProviderInterface" />
|
||||||
<referencedClass name="Sylius\Component\User\Security\UserPasswordEncoderInterface" />
|
<referencedClass name="Sylius\Component\User\Security\UserPasswordEncoderInterface" />
|
||||||
|
|
@ -135,7 +136,7 @@
|
||||||
|
|
||||||
<InvalidPropertyAssignmentValue>
|
<InvalidPropertyAssignmentValue>
|
||||||
<errorLevel type="info">
|
<errorLevel type="info">
|
||||||
<file name="src/Sylius/Bundle/UiBundle/DataCollector/TemplateBlockRenderingHistory.php" />
|
<file name="src/Sylius/Bundle/UiBundle/DataCollector/BlockRenderingHistory.php" />
|
||||||
</errorLevel>
|
</errorLevel>
|
||||||
</InvalidPropertyAssignmentValue>
|
</InvalidPropertyAssignmentValue>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Command;
|
namespace Sylius\Bundle\UiBundle\Command;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
|
@ -25,7 +25,7 @@ final class DebugTemplateEventCommand extends Command
|
||||||
{
|
{
|
||||||
protected static $defaultName = 'sylius:debug:template-event';
|
protected static $defaultName = 'sylius:debug:template-event';
|
||||||
|
|
||||||
public function __construct(private TemplateBlockRegistryInterface $templateBlockRegistry)
|
public function __construct(private BlockRegistryInterface $templateBlockRegistry)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +53,9 @@ final class DebugTemplateEventCommand extends Command
|
||||||
|
|
||||||
$io->title(sprintf('Blocks registered for the template event "%s"', $eventName));
|
$io->title(sprintf('Blocks registered for the template event "%s"', $eventName));
|
||||||
|
|
||||||
|
/** @var array<TemplateBlock> $templateBlocksForEvent */
|
||||||
|
$templateBlocksForEvent = $this->templateBlockRegistry->all()[$eventName] ?? [];
|
||||||
|
|
||||||
$io->table(
|
$io->table(
|
||||||
['Block name', 'Template', 'Priority', 'Enabled'],
|
['Block name', 'Template', 'Priority', 'Enabled'],
|
||||||
array_map(
|
array_map(
|
||||||
|
|
@ -62,7 +65,7 @@ final class DebugTemplateEventCommand extends Command
|
||||||
$templateBlock->getPriority(),
|
$templateBlock->getPriority(),
|
||||||
$templateBlock->isEnabled() ? 'TRUE' : 'FALSE',
|
$templateBlock->isEnabled() ? 'TRUE' : 'FALSE',
|
||||||
],
|
],
|
||||||
$this->templateBlockRegistry->all()[$eventName] ?? [],
|
$templateBlocksForEvent,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\ContextProvider;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\ContextProvider\Exception\NoSupportedContextProvider;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Webmozart\Assert\Assert;
|
||||||
|
|
||||||
|
final class CompositeContextProvider implements ContextProviderInterface
|
||||||
|
{
|
||||||
|
/** @var array<ContextProviderInterface> */
|
||||||
|
private array $contextProviders;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iterable<ContextProviderInterface> $contextProviders
|
||||||
|
*/
|
||||||
|
public function __construct(iterable $contextProviders)
|
||||||
|
{
|
||||||
|
Assert::allIsInstanceOf($contextProviders, ContextProviderInterface::class);
|
||||||
|
$this->contextProviders = $contextProviders instanceof \Traversable ? iterator_to_array($contextProviders) : $contextProviders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $templateContext
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function provide(array $templateContext, Block $templateBlock): array
|
||||||
|
{
|
||||||
|
foreach ($this->contextProviders as $contextProvider) {
|
||||||
|
if (!$contextProvider->supports($templateBlock)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $contextProvider->provide($templateContext, $templateBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NoSupportedContextProvider(sprintf('No supported context provider found for block "%s".', $templateBlock->getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports(Block $templateBlock): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,11 +13,11 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\ContextProvider;
|
namespace Sylius\Bundle\UiBundle\ContextProvider;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
interface ContextProviderInterface
|
interface ContextProviderInterface
|
||||||
{
|
{
|
||||||
public function provide(array $templateContext, TemplateBlock $templateBlock): array;
|
public function provide(array $templateContext, Block $templateBlock): array;
|
||||||
|
|
||||||
public function supports(TemplateBlock $templateBlock): bool;
|
public function supports(Block $templateBlock): bool;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,16 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\ContextProvider;
|
namespace Sylius\Bundle\UiBundle\ContextProvider;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
final class DefaultContextProvider implements ContextProviderInterface
|
final class DefaultContextProvider implements ContextProviderInterface
|
||||||
{
|
{
|
||||||
public function provide(array $templateContext, TemplateBlock $templateBlock): array
|
public function provide(array $templateContext, Block $templateBlock): array
|
||||||
{
|
{
|
||||||
return array_replace($templateBlock->getContext(), $templateContext);
|
return array_replace($templateBlock->getContext(), $templateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supports(TemplateBlock $templateBlock): bool
|
public function supports(Block $templateBlock): bool
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\ContextProvider\Exception;
|
||||||
|
|
||||||
|
class NoSupportedContextProvider extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -13,31 +13,41 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\DataCollector;
|
namespace Sylius\Bundle\UiBundle\DataCollector;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
final class TemplateBlockRenderingHistory
|
final class BlockRenderingHistory
|
||||||
{
|
{
|
||||||
/** @psalm-var list<array{name: string, start: float, stop: float, time: float, blocks: list<array{definition: TemplateBlock, start: float, stop: float, time: float}>}> */
|
/** @psalm-var list<array{name: string, start: float, stop: float, time: float, blocks: list<array{definition: Block, start: float, stop: float, time: float}>}> */
|
||||||
private $renderedEvents = [];
|
private $renderedEvents = [];
|
||||||
|
|
||||||
/** @psalm-var list<array{name: string, start: float, stop?: float, time?: float, blocks: list<array{definition: TemplateBlock, start: float, stop: float, time: float}>}> */
|
/** @psalm-var list<array{name: string, start: float, stop?: float, time?: float, blocks: list<array{definition: Block, start: float, stop: float, time: float}>}> */
|
||||||
private array $currentlyRenderedEvents = [];
|
private array $currentlyRenderedEvents = [];
|
||||||
|
|
||||||
/** @psalm-var list<array{definition: TemplateBlock, start: float, stop?: float, time?: float}> */
|
/** @psalm-var list<array{definition: Block, start: float, stop?: float, time?: float}> */
|
||||||
private array $currentlyRenderedBlocks = [];
|
private array $currentlyRenderedBlocks = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string> $eventNames
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public function startRenderingEvent(array $eventNames, array $context): void
|
public function startRenderingEvent(array $eventNames, array $context): void
|
||||||
{
|
{
|
||||||
$this->currentlyRenderedEvents[] = ['names' => $eventNames, 'start' => microtime(true), 'blocks' => []];
|
$this->currentlyRenderedEvents[] = ['names' => $eventNames, 'start' => microtime(true), 'blocks' => []];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startRenderingBlock(TemplateBlock $templateBlock, array $context): void
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
|
public function startRenderingBlock(Block $templateBlock, array $context): void
|
||||||
{
|
{
|
||||||
$this->currentlyRenderedBlocks[] = ['definition' => $templateBlock, 'start' => microtime(true)];
|
$this->currentlyRenderedBlocks[] = ['definition' => $templateBlock, 'start' => microtime(true)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stopRenderingBlock(TemplateBlock $templateBlock, array $context): void
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
|
public function stopRenderingBlock(Block $templateBlock, array $context): void
|
||||||
{
|
{
|
||||||
$currentlyRenderedBlock = array_pop($this->currentlyRenderedBlocks);
|
$currentlyRenderedBlock = array_pop($this->currentlyRenderedBlocks);
|
||||||
$currentlyRenderedBlock['stop'] = microtime(true);
|
$currentlyRenderedBlock['stop'] = microtime(true);
|
||||||
|
|
@ -48,6 +58,10 @@ final class TemplateBlockRenderingHistory
|
||||||
$this->currentlyRenderedEvents[] = $currentlyRenderedEvent;
|
$this->currentlyRenderedEvents[] = $currentlyRenderedEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string> $eventNames
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public function stopRenderingEvent(array $eventNames, array $context): void
|
public function stopRenderingEvent(array $eventNames, array $context): void
|
||||||
{
|
{
|
||||||
$currentlyRenderedEvent = array_pop($this->currentlyRenderedEvents);
|
$currentlyRenderedEvent = array_pop($this->currentlyRenderedEvents);
|
||||||
|
|
@ -56,6 +70,9 @@ final class TemplateBlockRenderingHistory
|
||||||
$this->renderedEvents[] = $currentlyRenderedEvent;
|
$this->renderedEvents[] = $currentlyRenderedEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<array{name: string, start: float, stop: float, time: float, blocks: list<array{definition: Block, start: float, stop: float, time: float}>}>
|
||||||
|
*/
|
||||||
public function getRenderedEvents(): array
|
public function getRenderedEvents(): array
|
||||||
{
|
{
|
||||||
return $this->renderedEvents;
|
return $this->renderedEvents;
|
||||||
|
|
@ -20,7 +20,7 @@ use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||||
/** @internal */
|
/** @internal */
|
||||||
final class TemplateBlockDataCollector extends DataCollector
|
final class TemplateBlockDataCollector extends DataCollector
|
||||||
{
|
{
|
||||||
public function __construct(private TemplateBlockRenderingHistory $templateBlockRenderingHistory)
|
public function __construct(private BlockRenderingHistory $templateBlockRenderingHistory)
|
||||||
{
|
{
|
||||||
$this->reset();
|
$this->reset();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\DataCollector;
|
namespace Sylius\Bundle\UiBundle\DataCollector;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface;
|
use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
final class TraceableTemplateBlockRenderer implements TemplateBlockRendererInterface
|
final class TraceableBlockRenderer implements BlockRendererInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TemplateBlockRendererInterface $templateBlockRenderer,
|
private BlockRendererInterface $templateBlockRenderer,
|
||||||
private TemplateBlockRenderingHistory $templateBlockRenderingHistory,
|
private BlockRenderingHistory $templateBlockRenderingHistory,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(TemplateBlock $templateBlock, array $context = []): string
|
public function render(Block $templateBlock, array $context = []): string
|
||||||
{
|
{
|
||||||
$this->templateBlockRenderingHistory->startRenderingBlock($templateBlock, $context);
|
$this->templateBlockRenderingHistory->startRenderingBlock($templateBlock, $context);
|
||||||
|
|
||||||
|
|
@ -13,14 +13,14 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\DataCollector;
|
namespace Sylius\Bundle\UiBundle\DataCollector;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface;
|
use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
final class TraceableTemplateEventRenderer implements TemplateEventRendererInterface
|
final class TraceableTwigEventRenderer implements TwigEventRendererInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TemplateEventRendererInterface $templateEventRenderer,
|
private TwigEventRendererInterface $templateEventRenderer,
|
||||||
private TemplateBlockRenderingHistory $templateBlockRenderingHistory,
|
private BlockRenderingHistory $templateBlockRenderingHistory,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,11 +42,32 @@ final class Configuration implements ConfigurationInterface
|
||||||
->ifString()
|
->ifString()
|
||||||
->then(static fn (?string $template): array => ['template' => $template])
|
->then(static fn (?string $template): array => ['template' => $template])
|
||||||
->end()
|
->end()
|
||||||
|
->validate()
|
||||||
|
->ifTrue(static function (array $block): bool {
|
||||||
|
if (!array_key_exists('template', $block) || !array_key_exists('component', $block)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null !== $block['template'] && [] !== $block['component'];
|
||||||
|
})
|
||||||
|
->thenInvalid('You cannot use both "template" and "component" for a block.')
|
||||||
|
->end()
|
||||||
->children()
|
->children()
|
||||||
->booleanNode('enabled')->defaultNull()->end()
|
->booleanNode('enabled')->defaultNull()->end()
|
||||||
->arrayNode('context')->addDefaultsIfNotSet()->ignoreExtraKeys(false)->end()
|
->arrayNode('context')->addDefaultsIfNotSet()->ignoreExtraKeys(false)->end()
|
||||||
->scalarNode('template')->defaultNull()->end()
|
->scalarNode('template')->defaultNull()->end()
|
||||||
->scalarNode('component')->defaultNull()->end()
|
->arrayNode('component')
|
||||||
|
->beforeNormalization()
|
||||||
|
->ifString()
|
||||||
|
->then(static fn (?string $component): array => ['name' => $component])
|
||||||
|
->end()
|
||||||
|
->treatNullLike([])
|
||||||
|
->addDefaultsIfNotSet()
|
||||||
|
->children()
|
||||||
|
->scalarNode('name')->isRequired()->end()
|
||||||
|
->arrayNode('inputs')->ignoreExtraKeys(false)->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
->integerNode('priority')->defaultNull()->end()
|
->integerNode('priority')->defaultNull()->end()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,9 @@ declare(strict_types=1);
|
||||||
namespace Sylius\Bundle\UiBundle\DependencyInjection;
|
namespace Sylius\Bundle\UiBundle\DependencyInjection;
|
||||||
|
|
||||||
use Laminas\Stdlib\SplPriorityQueue;
|
use Laminas\Stdlib\SplPriorityQueue;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
|
@ -44,7 +45,7 @@ final class SyliusUiExtension extends Extension
|
||||||
*/
|
*/
|
||||||
private function loadEvents(array $eventsConfig, ContainerBuilder $container): void
|
private function loadEvents(array $eventsConfig, ContainerBuilder $container): void
|
||||||
{
|
{
|
||||||
$templateBlockRegistryDefinition = $container->findDefinition(TemplateBlockRegistryInterface::class);
|
$templateBlockRegistryDefinition = $container->findDefinition(BlockRegistryInterface::class);
|
||||||
|
|
||||||
$blocksForEvents = [];
|
$blocksForEvents = [];
|
||||||
foreach ($eventsConfig as $eventName => $eventConfiguration) {
|
foreach ($eventsConfig as $eventName => $eventConfiguration) {
|
||||||
|
|
@ -57,20 +58,53 @@ final class SyliusUiExtension extends Extension
|
||||||
$blocksPriorityQueue->insert($details, $details['priority'] ?? 0);
|
$blocksPriorityQueue->insert($details, $details['priority'] ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @psalm-var array{name: string, eventName: string, template: string, component: string|null, context: array, priority: int, enabled: bool} $details */
|
/** @psalm-var array{name: string, eventName: string, template: string, component: array{name?: string, inputs?: array<string, mixed>}, context: array, priority: int, enabled: bool} $details */
|
||||||
foreach ($blocksPriorityQueue->toArray() as $details) {
|
foreach ($blocksPriorityQueue->toArray() as $details) {
|
||||||
$blocksForEvents[$eventName][$details['name']] = new Definition(TemplateBlock::class, [
|
$blockType = [] !== $details['component'] ? 'component' : 'template';
|
||||||
$details['name'],
|
$blocksForEvents[$eventName][$details['name']] = match ($blockType) {
|
||||||
$details['eventName'],
|
'template' => $this->createTemplateBlockDefinition($details),
|
||||||
$details['template'],
|
'component' => $this->createComponentBlockDefinition($details),
|
||||||
$details['context'],
|
};
|
||||||
$details['priority'],
|
|
||||||
$details['enabled'],
|
|
||||||
$details['component'],
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$templateBlockRegistryDefinition->setArgument(0, $blocksForEvents);
|
$templateBlockRegistryDefinition->setArgument(0, $blocksForEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $details
|
||||||
|
*/
|
||||||
|
private function createTemplateBlockDefinition(array $details): Definition
|
||||||
|
{
|
||||||
|
return new Definition(
|
||||||
|
TemplateBlock::class,
|
||||||
|
[
|
||||||
|
$details['name'],
|
||||||
|
$details['eventName'],
|
||||||
|
$details['template'],
|
||||||
|
$details['context'],
|
||||||
|
$details['priority'],
|
||||||
|
$details['enabled'],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $details
|
||||||
|
*/
|
||||||
|
private function createComponentBlockDefinition(array $details): Definition
|
||||||
|
{
|
||||||
|
return new Definition(
|
||||||
|
ComponentBlock::class,
|
||||||
|
[
|
||||||
|
$details['name'],
|
||||||
|
$details['eventName'],
|
||||||
|
$details['component']['name'],
|
||||||
|
$details['component']['inputs'] ?? [],
|
||||||
|
$details['context'],
|
||||||
|
$details['priority'],
|
||||||
|
$details['enabled'],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
59
src/Sylius/Bundle/UiBundle/Registry/Block.php
Normal file
59
src/Sylius/Bundle/UiBundle/Registry/Block.php
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
|
abstract class Block
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed>|null $context
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
protected string $name,
|
||||||
|
protected string $eventName,
|
||||||
|
protected ?array $context,
|
||||||
|
protected ?int $priority,
|
||||||
|
protected ?bool $enabled,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEventName(): string
|
||||||
|
{
|
||||||
|
return $this->eventName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function getContext(): array
|
||||||
|
{
|
||||||
|
return $this->context ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority(): int
|
||||||
|
{
|
||||||
|
return $this->priority ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEnabled(): bool
|
||||||
|
{
|
||||||
|
return $this->enabled ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function overwriteWith(self $block): self;
|
||||||
|
}
|
||||||
90
src/Sylius/Bundle/UiBundle/Registry/BlockRegistry.php
Normal file
90
src/Sylius/Bundle/UiBundle/Registry/BlockRegistry.php
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
|
use Laminas\Stdlib\SplPriorityQueue;
|
||||||
|
|
||||||
|
final class BlockRegistry implements BlockRegistryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Blocks within an event should be sorted by their priority descending.
|
||||||
|
*
|
||||||
|
* @var array<string, array<string, Block>>
|
||||||
|
*/
|
||||||
|
private array $eventsToBlocks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, array<string, Block>> $eventsToTemplateBlocks
|
||||||
|
*/
|
||||||
|
public function __construct(array $eventsToTemplateBlocks)
|
||||||
|
{
|
||||||
|
$this->eventsToBlocks = $eventsToTemplateBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all(): array
|
||||||
|
{
|
||||||
|
return $this->eventsToBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findEnabledForEvents(array $eventNames): array
|
||||||
|
{
|
||||||
|
// No need to sort blocks again if there's only one event because we have them sorted already
|
||||||
|
if (count($eventNames) === 1) {
|
||||||
|
$eventName = reset($eventNames);
|
||||||
|
|
||||||
|
return array_values(array_filter(
|
||||||
|
$this->eventsToBlocks[$eventName] ?? [],
|
||||||
|
static fn (Block $block): bool => $block->isEnabled(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$enabledFinalizedBlocks = array_filter(
|
||||||
|
$this->findFinalizedForEvents($eventNames),
|
||||||
|
static fn (Block $block): bool => $block->isEnabled(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$blocksPriorityQueue = new SplPriorityQueue();
|
||||||
|
foreach ($enabledFinalizedBlocks as $block) {
|
||||||
|
$blocksPriorityQueue->insert($block, $block->getPriority());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $blocksPriorityQueue->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $eventNames
|
||||||
|
*
|
||||||
|
* @return Block[]
|
||||||
|
*/
|
||||||
|
private function findFinalizedForEvents(array $eventNames): array
|
||||||
|
{
|
||||||
|
/** @var array<string, Block> $finalizedBlocks */
|
||||||
|
$finalizedBlocks = [];
|
||||||
|
$reversedEventNames = array_reverse($eventNames);
|
||||||
|
foreach ($reversedEventNames as $eventName) {
|
||||||
|
$blocks = $this->eventsToBlocks[$eventName] ?? [];
|
||||||
|
foreach ($blocks as $blockName => $block) {
|
||||||
|
if (array_key_exists($blockName, $finalizedBlocks)) {
|
||||||
|
$block = $finalizedBlocks[$blockName]->overwriteWith($block);
|
||||||
|
}
|
||||||
|
|
||||||
|
$finalizedBlocks[$blockName] = $block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $finalizedBlocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_alias(BlockRegistry::class, '\Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistry');
|
||||||
|
|
@ -13,23 +13,19 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Registry;
|
namespace Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
interface TemplateBlockRegistryInterface
|
interface BlockRegistryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return TemplateBlock[][]
|
* @return array<string, array<string, Block>>
|
||||||
*
|
|
||||||
* @psalm-return array<string, array<string, TemplateBlock>>
|
|
||||||
*/
|
*/
|
||||||
public function all(): array;
|
public function all(): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string[] $eventNames
|
* @param string[] $eventNames
|
||||||
*
|
*
|
||||||
* @psalm-param non-empty-list<string> $eventNames
|
* @return Block[]
|
||||||
*
|
|
||||||
* @return TemplateBlock[]
|
|
||||||
*
|
|
||||||
* @psalm-return list<TemplateBlock>
|
|
||||||
*/
|
*/
|
||||||
public function findEnabledForEvents(array $eventNames): array;
|
public function findEnabledForEvents(array $eventNames): array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class_alias(BlockRegistryInterface::class, '\Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface');
|
||||||
73
src/Sylius/Bundle/UiBundle/Registry/ComponentBlock.php
Normal file
73
src/Sylius/Bundle/UiBundle/Registry/ComponentBlock.php
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
|
final class ComponentBlock extends Block
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $componentInputs
|
||||||
|
* @param array<string, mixed>|null $context
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
string $name,
|
||||||
|
string $eventName,
|
||||||
|
private string $componentName,
|
||||||
|
private array $componentInputs,
|
||||||
|
?array $context,
|
||||||
|
?int $priority,
|
||||||
|
?bool $enabled,
|
||||||
|
) {
|
||||||
|
parent::__construct($name, $eventName, $context, $priority, $enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getComponentName(): string
|
||||||
|
{
|
||||||
|
return $this->componentName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return array<string> */
|
||||||
|
public function getComponentInputs(): array
|
||||||
|
{
|
||||||
|
return $this->componentInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function overwriteWith(Block $block): self
|
||||||
|
{
|
||||||
|
if (!$block instanceof ComponentBlock) {
|
||||||
|
throw new \DomainException(sprintf(
|
||||||
|
'Trying to overwrite component block "%s" with block of different type "%s".',
|
||||||
|
$this->name,
|
||||||
|
get_class($block),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->name !== $block->name) {
|
||||||
|
throw new \DomainException(sprintf(
|
||||||
|
'Trying to overwrite block "%s" with block "%s".',
|
||||||
|
$this->name,
|
||||||
|
$block->name,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
$this->name,
|
||||||
|
$block->eventName,
|
||||||
|
$block->getComponentName(),
|
||||||
|
$block->getComponentInputs(),
|
||||||
|
$block->context ?? $this->context,
|
||||||
|
$block->priority ?? $this->priority,
|
||||||
|
$block->enabled ?? $this->enabled,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,27 +13,17 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Registry;
|
namespace Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
final class TemplateBlock
|
final class TemplateBlock extends Block
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private string $name,
|
string $name,
|
||||||
private string $eventName,
|
string $eventName,
|
||||||
private ?string $template,
|
private ?string $template,
|
||||||
private ?array $context,
|
?array $context,
|
||||||
private ?int $priority,
|
?int $priority,
|
||||||
private ?bool $enabled,
|
?bool $enabled,
|
||||||
private ?string $component = null,
|
|
||||||
) {
|
) {
|
||||||
}
|
parent::__construct($name, $eventName, $context, $priority, $enabled);
|
||||||
|
|
||||||
public function getName(): string
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEventName(): string
|
|
||||||
{
|
|
||||||
return $this->eventName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTemplate(): string
|
public function getTemplate(): string
|
||||||
|
|
@ -49,28 +39,16 @@ final class TemplateBlock
|
||||||
return $this->template;
|
return $this->template;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getComponent(): ?string
|
public function overwriteWith(Block $block): self
|
||||||
{
|
{
|
||||||
return $this->component;
|
if (!$block instanceof self) {
|
||||||
}
|
throw new \DomainException(sprintf(
|
||||||
|
'Trying to overwrite template block "%s" with block of different type "%s".',
|
||||||
|
$this->name,
|
||||||
|
get_class($block),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public function getContext(): array
|
|
||||||
{
|
|
||||||
return $this->context ?? [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPriority(): int
|
|
||||||
{
|
|
||||||
return $this->priority ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isEnabled(): bool
|
|
||||||
{
|
|
||||||
return $this->enabled ?? true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function overwriteWith(self $block): self
|
|
||||||
{
|
|
||||||
if ($this->name !== $block->name) {
|
if ($this->name !== $block->name) {
|
||||||
throw new \DomainException(sprintf(
|
throw new \DomainException(sprintf(
|
||||||
'Trying to overwrite block "%s" with block "%s".',
|
'Trying to overwrite block "%s" with block "%s".',
|
||||||
|
|
@ -86,7 +64,6 @@ final class TemplateBlock
|
||||||
$block->context ?? $this->context,
|
$block->context ?? $this->context,
|
||||||
$block->priority ?? $this->priority,
|
$block->priority ?? $this->priority,
|
||||||
$block->enabled ?? $this->enabled,
|
$block->enabled ?? $this->enabled,
|
||||||
$block->component ?? $this->component,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Sylius package.
|
|
||||||
*
|
|
||||||
* (c) Sylius Sp. z o.o.
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Registry;
|
|
||||||
|
|
||||||
use Laminas\Stdlib\SplPriorityQueue;
|
|
||||||
|
|
||||||
final class TemplateBlockRegistry implements TemplateBlockRegistryInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Blocks within an event should be sorted by their priority descending.
|
|
||||||
*
|
|
||||||
* @var TemplateBlock[][]
|
|
||||||
*
|
|
||||||
* @psalm-var array<string, array<string, TemplateBlock>>
|
|
||||||
*/
|
|
||||||
private $eventsToTemplateBlocks;
|
|
||||||
|
|
||||||
public function __construct(array $eventsToTemplateBlocks)
|
|
||||||
{
|
|
||||||
$this->eventsToTemplateBlocks = $eventsToTemplateBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function all(): array
|
|
||||||
{
|
|
||||||
return $this->eventsToTemplateBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function findEnabledForEvents(array $eventNames): array
|
|
||||||
{
|
|
||||||
// No need to sort blocks again if there's only one event because we have them sorted already
|
|
||||||
if (count($eventNames) === 1) {
|
|
||||||
$eventName = reset($eventNames);
|
|
||||||
|
|
||||||
return array_values(array_filter(
|
|
||||||
$this->eventsToTemplateBlocks[$eventName] ?? [],
|
|
||||||
static fn (TemplateBlock $templateBlock): bool => $templateBlock->isEnabled(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$enabledFinalizedTemplateBlocks = array_filter(
|
|
||||||
$this->findFinalizedForEvents($eventNames),
|
|
||||||
static fn (TemplateBlock $templateBlock): bool => $templateBlock->isEnabled(),
|
|
||||||
);
|
|
||||||
|
|
||||||
$templateBlocksPriorityQueue = new SplPriorityQueue();
|
|
||||||
foreach ($enabledFinalizedTemplateBlocks as $templateBlock) {
|
|
||||||
$templateBlocksPriorityQueue->insert($templateBlock, $templateBlock->getPriority());
|
|
||||||
}
|
|
||||||
|
|
||||||
return $templateBlocksPriorityQueue->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string[] $eventNames
|
|
||||||
*
|
|
||||||
* @psalm-param non-empty-list<string> $eventNames
|
|
||||||
*
|
|
||||||
* @return TemplateBlock[]
|
|
||||||
*/
|
|
||||||
private function findFinalizedForEvents(array $eventNames): array
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var TemplateBlock[] $finalizedTemplateBlocks
|
|
||||||
*
|
|
||||||
* @psalm-var array<string, TemplateBlock> $finalizedTemplateBlocks
|
|
||||||
*/
|
|
||||||
$finalizedTemplateBlocks = [];
|
|
||||||
$reversedEventNames = array_reverse($eventNames);
|
|
||||||
foreach ($reversedEventNames as $eventName) {
|
|
||||||
$templateBlocks = $this->eventsToTemplateBlocks[$eventName] ?? [];
|
|
||||||
foreach ($templateBlocks as $blockName => $templateBlock) {
|
|
||||||
if (array_key_exists($blockName, $finalizedTemplateBlocks)) {
|
|
||||||
$templateBlock = $finalizedTemplateBlocks[$blockName]->overwriteWith($templateBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
$finalizedTemplateBlocks[$blockName] = $templateBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $finalizedTemplateBlocks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
|
interface BlockRendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
|
public function render(Block $templateBlock, array $context = []): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_alias(BlockRendererInterface::class, '\Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface');
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Sylius\Bundle\UiBundle\Renderer\Exception\NoSupportedBlockRenderer;
|
||||||
|
use Webmozart\Assert\Assert;
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
final class CompositeBlockRenderer implements BlockRendererInterface
|
||||||
|
{
|
||||||
|
/** @var array<SupportableBlockRendererInterface> */
|
||||||
|
private array $blockRenderers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iterable<SupportableBlockRendererInterface> $blockRenderers
|
||||||
|
*/
|
||||||
|
public function __construct(iterable $blockRenderers)
|
||||||
|
{
|
||||||
|
Assert::allIsInstanceOf($blockRenderers, SupportableBlockRendererInterface::class);
|
||||||
|
$this->blockRenderers = $blockRenderers instanceof \Traversable ? iterator_to_array($blockRenderers) : $blockRenderers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(Block $templateBlock, array $context = []): string
|
||||||
|
{
|
||||||
|
foreach ($this->blockRenderers as $blockRenderer) {
|
||||||
|
if (!$blockRenderer->supports($templateBlock)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $blockRenderer->render($templateBlock, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NoSupportedBlockRenderer(sprintf('No supported block renderer found for "%s" block.', $templateBlock->getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,14 +13,18 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
|
||||||
final class DelegatingTemplateEventRenderer implements TemplateEventRendererInterface
|
final class DelegatingTwigEventRenderer implements TwigEventRendererInterface
|
||||||
{
|
{
|
||||||
public function __construct(private TemplateBlockRegistryInterface $templateBlockRegistry, private TemplateBlockRendererInterface $templateBlockRenderer)
|
public function __construct(private BlockRegistryInterface $templateBlockRegistry, private BlockRendererInterface $templateBlockRenderer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string> $eventNames
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public function render(array $eventNames, array $context = []): string
|
public function render(array $eventNames, array $context = []): string
|
||||||
{
|
{
|
||||||
$templateBlocks = $this->templateBlockRegistry->findEnabledForEvents($eventNames);
|
$templateBlocks = $this->templateBlockRegistry->findEnabledForEvents($eventNames);
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Renderer\Exception;
|
||||||
|
|
||||||
|
class NoSupportedBlockRenderer extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
100
src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugBlockRenderer.php
Normal file
100
src/Sylius/Bundle/UiBundle/Renderer/HtmlDebugBlockRenderer.php
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
|
|
||||||
|
final class HtmlDebugBlockRenderer implements BlockRendererInterface
|
||||||
|
{
|
||||||
|
public function __construct(private BlockRendererInterface $blockRenderer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(Block $templateBlock, array $context = []): string
|
||||||
|
{
|
||||||
|
if (!$this->shouldRenderHtmlDebug($templateBlock)) {
|
||||||
|
return $this->blockRenderer->render($templateBlock, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderedParts = [];
|
||||||
|
|
||||||
|
switch (get_class($templateBlock)) {
|
||||||
|
case TemplateBlock::class:
|
||||||
|
$renderedParts[] = $this->getBeginBlockForTemplate($templateBlock);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ComponentBlock::class:
|
||||||
|
$renderedParts[] = $this->getBeginBlockForComponent($templateBlock);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$renderedParts[] = $this->blockRenderer->render($templateBlock, $context);
|
||||||
|
$renderedParts[] = $this->getEndBlock($templateBlock);
|
||||||
|
|
||||||
|
return implode("\n", $renderedParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldRenderHtmlDebug(Block $block): bool
|
||||||
|
{
|
||||||
|
return match (get_class($block)) {
|
||||||
|
TemplateBlock::class => strrpos($block->getTemplate(), '.html.twig') !== false,
|
||||||
|
ComponentBlock::class => true,
|
||||||
|
default => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getBeginBlockForTemplate(Block $block): string
|
||||||
|
{
|
||||||
|
if (!$block instanceof TemplateBlock) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Block must be instance of "%s"', TemplateBlock::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<!-- BEGIN BLOCK | event name: "%s", block name: "%s", template: "%s", priority: %d -->',
|
||||||
|
$block->getEventName(),
|
||||||
|
$block->getName(),
|
||||||
|
$block->getTemplate(),
|
||||||
|
$block->getPriority(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getBeginBlockForComponent(Block $block): string
|
||||||
|
{
|
||||||
|
if (!$block instanceof ComponentBlock) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Block must be instance of "%s"', ComponentBlock::class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<!-- BEGIN BLOCK | event name: "%s", block name: "%s", component: "%s", priority: %d -->',
|
||||||
|
$block->getEventName(),
|
||||||
|
$block->getName(),
|
||||||
|
$block->getComponentName(),
|
||||||
|
$block->getPriority(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getEndBlock(Block $templateBlock): string
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'<!-- END BLOCK | event name: "%s", block name: "%s" -->',
|
||||||
|
$templateBlock->getEventName(),
|
||||||
|
$templateBlock->getName(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_alias(HtmlDebugBlockRenderer::class, '\Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateBlockRenderer');
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Sylius package.
|
|
||||||
*
|
|
||||||
* (c) Sylius Sp. z o.o.
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
|
||||||
|
|
||||||
final class HtmlDebugTemplateBlockRenderer implements TemplateBlockRendererInterface
|
|
||||||
{
|
|
||||||
public function __construct(private TemplateBlockRendererInterface $templateBlockRenderer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render(TemplateBlock $templateBlock, array $context = []): string
|
|
||||||
{
|
|
||||||
$isTemplateBlockComponent = null !== $templateBlock->getComponent();
|
|
||||||
$shouldRenderHtmlDebug = $isTemplateBlockComponent || strrpos($templateBlock->getTemplate(), '.html.twig') !== false;
|
|
||||||
|
|
||||||
if (!$shouldRenderHtmlDebug) {
|
|
||||||
return $this->templateBlockRenderer->render($templateBlock, $context);
|
|
||||||
}
|
|
||||||
|
|
||||||
$renderedParts = [];
|
|
||||||
|
|
||||||
if ($isTemplateBlockComponent) {
|
|
||||||
$renderedParts[] = $this->getBeginBlockForComponent($templateBlock);
|
|
||||||
} else {
|
|
||||||
$renderedParts[] = $this->getBeginBlockForTemplate($templateBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
$renderedParts[] = $this->templateBlockRenderer->render($templateBlock, $context);
|
|
||||||
$renderedParts[] = $this->getEndBlock($templateBlock);
|
|
||||||
|
|
||||||
return implode("\n", $renderedParts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getBeginBlockForTemplate(TemplateBlock $templateBlock): string
|
|
||||||
{
|
|
||||||
return sprintf(
|
|
||||||
'<!-- BEGIN BLOCK | event name: "%s", block name: "%s", template: "%s", priority: %d -->',
|
|
||||||
$templateBlock->getEventName(),
|
|
||||||
$templateBlock->getName(),
|
|
||||||
$templateBlock->getTemplate(),
|
|
||||||
$templateBlock->getPriority(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getBeginBlockForComponent(TemplateBlock $templateBlock): string
|
|
||||||
{
|
|
||||||
return sprintf(
|
|
||||||
'<!-- BEGIN BLOCK | event name: "%s", block name: "%s", component: "%s", priority: %d -->',
|
|
||||||
$templateBlock->getEventName(),
|
|
||||||
$templateBlock->getName(),
|
|
||||||
$templateBlock->getComponent(),
|
|
||||||
$templateBlock->getPriority(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getEndBlock(TemplateBlock $templateBlock): string
|
|
||||||
{
|
|
||||||
return sprintf(
|
|
||||||
'<!-- END BLOCK | event name: "%s", block name: "%s" -->',
|
|
||||||
$templateBlock->getEventName(),
|
|
||||||
$templateBlock->getName(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -13,20 +13,26 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
|
||||||
|
|
||||||
final class HtmlDebugTemplateEventRenderer implements TemplateEventRendererInterface
|
final class HtmlDebugTwigEventRenderer implements TwigEventRendererInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TemplateEventRendererInterface $templateEventRenderer,
|
private TwigEventRendererInterface $templateEventRenderer,
|
||||||
private TemplateBlockRegistryInterface $templateBlockRegistry,
|
private BlockRegistryInterface $blockRegistry,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string> $eventNames
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public function render(array $eventNames, array $context = []): string
|
public function render(array $eventNames, array $context = []): string
|
||||||
{
|
{
|
||||||
$shouldRenderHtmlDebug = $this->shouldRenderHtmlDebug($this->templateBlockRegistry->findEnabledForEvents($eventNames));
|
$shouldRenderHtmlDebug = $this->shouldRenderHtmlDebug($this->blockRegistry->findEnabledForEvents($eventNames));
|
||||||
|
|
||||||
$renderedParts = [];
|
$renderedParts = [];
|
||||||
|
|
||||||
|
|
@ -50,24 +56,24 @@ final class HtmlDebugTemplateEventRenderer implements TemplateEventRendererInter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TemplateBlock[] $templateBlocks
|
* @param Block[] $blocks
|
||||||
*/
|
*/
|
||||||
private function shouldRenderHtmlDebug(array $templateBlocks): bool
|
private function shouldRenderHtmlDebug(array $blocks): bool
|
||||||
{
|
{
|
||||||
return count($templateBlocks) === 0 || $this->hasAnyBlockWithComponentOrTemplate($templateBlocks);
|
if (0 === count($blocks)) {
|
||||||
}
|
return true;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<TemplateBlock> $templateBlocks
|
|
||||||
*/
|
|
||||||
private function hasAnyBlockWithComponentOrTemplate(array $templateBlocks): bool
|
|
||||||
{
|
|
||||||
foreach ($templateBlocks as $templateBlock) {
|
|
||||||
if (null !== $templateBlock->getComponent() || strrpos($templateBlock->getTemplate(), '.html.twig') !== false) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0 !== count(
|
||||||
|
array_filter($blocks, function (Block $block): bool {
|
||||||
|
return match (get_class($block)) {
|
||||||
|
TemplateBlock::class => strrpos($block->getTemplate(), '.html.twig') !== false,
|
||||||
|
ComponentBlock::class => true,
|
||||||
|
default => false,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class_alias(HtmlDebugTwigEventRenderer::class, '\Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateEventRenderer');
|
||||||
|
|
@ -13,9 +13,9 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
interface TemplateBlockRendererInterface
|
interface SupportableBlockRendererInterface extends BlockRendererInterface
|
||||||
{
|
{
|
||||||
public function render(TemplateBlock $templateBlock, array $context = []): string;
|
public function supports(Block $block): bool;
|
||||||
}
|
}
|
||||||
|
|
@ -13,27 +13,71 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use Symfony\UX\TwigComponent\ComponentRendererInterface;
|
use Symfony\UX\TwigComponent\ComponentRendererInterface;
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
final class TwigComponentBlockRenderer implements TemplateBlockRendererInterface
|
final class TwigComponentBlockRenderer implements SupportableBlockRendererInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TemplateBlockRendererInterface $decoratedRenderer,
|
|
||||||
private ComponentRendererInterface $componentRenderer,
|
private ComponentRendererInterface $componentRenderer,
|
||||||
|
private ContextProviderInterface $contextProvider,
|
||||||
|
private ExpressionLanguage $expressionLanguage,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param ComponentBlock $templateBlock
|
||||||
* @param array<string, mixed> $context
|
* @param array<string, mixed> $context
|
||||||
*/
|
*/
|
||||||
public function render(TemplateBlock $templateBlock, array $context = []): string
|
public function render(Block $templateBlock, array $context = []): string
|
||||||
{
|
{
|
||||||
if (null === $templateBlock->getComponent()) {
|
if (!$this->supports($templateBlock)) {
|
||||||
return $this->decoratedRenderer->render($templateBlock, $context);
|
throw new \InvalidArgumentException(sprintf(
|
||||||
|
'Block "%s" is not supported by "%s".',
|
||||||
|
$templateBlock->getName(),
|
||||||
|
self::class,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->componentRenderer->createAndRender($templateBlock->getComponent(), ['context' => $templateBlock->getContext() + $context]);
|
$context = $this->contextProvider->provide($context, $templateBlock);
|
||||||
|
|
||||||
|
$inputs = $this->mapArrayRecursively(function (mixed $value) use ($context) {
|
||||||
|
if (!is_string($value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str_starts_with($value, 'expr:')) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->expressionLanguage->evaluate(substr($value, 5), $context);
|
||||||
|
}, $templateBlock->getComponentInputs());
|
||||||
|
|
||||||
|
return $this->componentRenderer->createAndRender($templateBlock->getComponentName(), $inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<array-key, mixed> $array
|
||||||
|
* @return array<array-key, mixed>
|
||||||
|
*/
|
||||||
|
private function mapArrayRecursively(callable $callback, array $array): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
$result[$key] = is_array($value)
|
||||||
|
? $this->mapArrayRecursively($callback, $value)
|
||||||
|
: $callback($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supports(Block $block): bool
|
||||||
|
{
|
||||||
|
return is_a($block, ComponentBlock::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
interface TemplateEventRendererInterface
|
interface TwigEventRendererInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string[] $eventNames
|
* @param string[] $eventNames
|
||||||
*
|
* @param array<string, mixed> $context
|
||||||
* @psalm-param non-empty-list<string> $eventNames
|
|
||||||
*/
|
*/
|
||||||
public function render(array $eventNames, array $context = []): string;
|
public function render(array $eventNames, array $context = []): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class_alias(TwigEventRendererInterface::class, '\Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface');
|
||||||
|
|
@ -14,17 +14,32 @@ declare(strict_types=1);
|
||||||
namespace Sylius\Bundle\UiBundle\Renderer;
|
namespace Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
|
||||||
final class TwigTemplateBlockRenderer implements TemplateBlockRendererInterface
|
final class TwigTemplateBlockRenderer implements SupportableBlockRendererInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param iterable<ContextProviderInterface> $contextProviders
|
||||||
|
*/
|
||||||
public function __construct(private Environment $twig, private iterable $contextProviders)
|
public function __construct(private Environment $twig, private iterable $contextProviders)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render(TemplateBlock $templateBlock, array $context = []): string
|
/**
|
||||||
|
* @param TemplateBlock $templateBlock
|
||||||
|
*/
|
||||||
|
public function render(Block $templateBlock, array $context = []): string
|
||||||
{
|
{
|
||||||
|
if (!$this->supports($templateBlock)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf(
|
||||||
|
'Block "%s" is not supported by "%s".',
|
||||||
|
$templateBlock->getName(),
|
||||||
|
self::class,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->contextProviders as $contextProvider) {
|
foreach ($this->contextProviders as $contextProvider) {
|
||||||
if (!$contextProvider instanceof ContextProviderInterface || !$contextProvider->supports($templateBlock)) {
|
if (!$contextProvider instanceof ContextProviderInterface || !$contextProvider->supports($templateBlock)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -35,4 +50,9 @@ final class TwigTemplateBlockRenderer implements TemplateBlockRendererInterface
|
||||||
|
|
||||||
return $this->twig->render($templateBlock->getTemplate(), $context);
|
return $this->twig->render($templateBlock->getTemplate(), $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function supports(Block $block): bool
|
||||||
|
{
|
||||||
|
return is_a($block, TemplateBlock::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,30 +13,33 @@
|
||||||
|
|
||||||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
<services>
|
<services>
|
||||||
<service id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockRenderingHistory" />
|
<service id="Sylius\Bundle\UiBundle\DataCollector\BlockRenderingHistory" />
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockDataCollector">
|
<service id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockDataCollector">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockRenderingHistory" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\BlockRenderingHistory" />
|
||||||
<tag name="data_collector" template="@SyliusUi/DataCollector/templateBlock.html.twig" id="sylius_ui.template_block" />
|
<tag name="data_collector" template="@SyliusUi/DataCollector/templateBlock.html.twig" id="sylius_ui.template_block" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\DataCollector\TraceableTemplateBlockRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface">
|
<service id="Sylius\Bundle\UiBundle\DataCollector\TraceableBlockRenderer" decorates="sylius.ui.block_renderer.composite">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TraceableTemplateBlockRenderer.inner" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TraceableBlockRenderer.inner" />
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockRenderingHistory" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\BlockRenderingHistory" />
|
||||||
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\DataCollector\TraceableTemplateBlockRenderer" alias="Sylius\Bundle\UiBundle\DataCollector\TraceableBlockRenderer" />
|
||||||
|
|
||||||
|
<service id="Sylius\Bundle\UiBundle\DataCollector\TraceableTwigEventRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface">
|
||||||
|
<argument type="service" id=".inner" />
|
||||||
|
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\BlockRenderingHistory" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\DataCollector\TraceableTemplateEventRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface">
|
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugBlockRenderer" decorates="sylius.ui.block_renderer.composite">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TraceableTemplateEventRenderer.inner" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugBlockRenderer.inner" />
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\DataCollector\TemplateBlockRenderingHistory" />
|
|
||||||
</service>
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateBlockRenderer" alias="Sylius\Bundle\UiBundle\Renderer\HtmlDebugBlockRenderer" />
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateBlockRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface">
|
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTwigEventRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateBlockRenderer.inner" />
|
<argument type="service" id=".inner" />
|
||||||
</service>
|
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateEventRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface">
|
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateEventRenderer.inner" />
|
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTemplateEventRenderer" alias="Sylius\Bundle\UiBundle\Renderer\HtmlDebugTwigEventRenderer" />
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
|
|
||||||
|
|
@ -13,24 +13,34 @@
|
||||||
|
|
||||||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||||
<services>
|
<services>
|
||||||
<service id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" class="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistry">
|
<service id="sylius.ui.block_renderer.composite" class="Sylius\Bundle\UiBundle\Renderer\CompositeBlockRenderer">
|
||||||
|
<argument type="tagged_iterator" tag="sylius.ui.block_renderer" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface" class="Sylius\Bundle\UiBundle\Registry\BlockRegistry">
|
||||||
<argument type="collection" />
|
<argument type="collection" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" alias="Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface" />
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface" class="Sylius\Bundle\UiBundle\Renderer\TwigTemplateBlockRenderer">
|
<service id="Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface" class="Sylius\Bundle\UiBundle\Renderer\TwigTemplateBlockRenderer">
|
||||||
<argument type="service" id="twig" />
|
<argument type="service" id="twig" />
|
||||||
<argument type="tagged_iterator" tag="sylius.ui.template_event.context_provider" />
|
<argument type="tagged_iterator" tag="sylius.ui.template_event.context_provider" />
|
||||||
|
<tag name="sylius.ui.block_renderer" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface" alias="Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface" />
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Renderer\TwigComponentBlockRenderer" decorates="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface" decoration-priority="1024">
|
<service id="Sylius\Bundle\UiBundle\Renderer\TwigComponentBlockRenderer">
|
||||||
<argument type="service" id=".inner" />
|
|
||||||
<argument type="service" id="ux.twig_component.component_renderer" />
|
<argument type="service" id="ux.twig_component.component_renderer" />
|
||||||
|
<argument type="service" id="Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface" />
|
||||||
|
<argument type="service" id="sylius.expression_language" />
|
||||||
|
<tag name="sylius.ui.block_renderer" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface" class="Sylius\Bundle\UiBundle\Renderer\DelegatingTemplateEventRenderer">
|
<service id="Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface" class="Sylius\Bundle\UiBundle\Renderer\DelegatingTwigEventRenderer">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface" />
|
<argument type="service" id="sylius.ui.block_renderer.composite" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface" alias="Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface" />
|
||||||
|
|
||||||
<service id="Sylius\Bundle\UiBundle\Command\DebugTemplateEventCommand">
|
<service id="Sylius\Bundle\UiBundle\Command\DebugTemplateEventCommand">
|
||||||
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
<argument type="service" id="Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface" />
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,108 @@ final class ConfigurationTest extends TestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function component_block_configuration_can_be_shortened_to_template_string_only(): void
|
||||||
|
{
|
||||||
|
$this->assertProcessedConfigurationEquals(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'events' => [
|
||||||
|
'event_name' => [
|
||||||
|
'blocks' => [
|
||||||
|
'block_name' => [
|
||||||
|
'component' => 'component_name',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'events' => [
|
||||||
|
'event_name' => [
|
||||||
|
'blocks' => [
|
||||||
|
'block_name' => [
|
||||||
|
'component' => [
|
||||||
|
'name' => 'component_name',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'events.*.blocks.*.component',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function component_block_configuration_can_be_defined_with_inputs(): void
|
||||||
|
{
|
||||||
|
$this->assertProcessedConfigurationEquals(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'events' => [
|
||||||
|
'event_name' => [
|
||||||
|
'blocks' => [
|
||||||
|
'block_name' => [
|
||||||
|
'component' => [
|
||||||
|
'name' => 'component_name',
|
||||||
|
'inputs' => [
|
||||||
|
'foo' => 'bar',
|
||||||
|
'bar' => 'baz',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'events' => [
|
||||||
|
'event_name' => [
|
||||||
|
'blocks' => [
|
||||||
|
'block_name' => [
|
||||||
|
'component' => [
|
||||||
|
'name' => 'component_name',
|
||||||
|
'inputs' => [
|
||||||
|
'foo' => 'bar',
|
||||||
|
'bar' => 'baz',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'events.*.blocks.*.component',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @test */
|
||||||
|
public function template_and_component_cannot_be_defined_at_the_same_time(): void
|
||||||
|
{
|
||||||
|
$this->assertPartialConfigurationIsInvalid(
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'events' => [
|
||||||
|
'event_name' => [
|
||||||
|
'blocks' => [
|
||||||
|
'block_name' => [
|
||||||
|
'template' => 'template.html.twig',
|
||||||
|
'component' => [
|
||||||
|
'name' => 'component_name',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'events.*.blocks.*.template',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getConfiguration(): ConfigurationInterface
|
protected function getConfiguration(): ConfigurationInterface
|
||||||
{
|
{
|
||||||
return new Configuration();
|
return new Configuration();
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,9 @@ namespace Sylius\Bundle\UiBundle\Tests\DependencyInjection;
|
||||||
|
|
||||||
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
|
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
|
||||||
use Sylius\Bundle\UiBundle\DependencyInjection\SyliusUiExtension;
|
use Sylius\Bundle\UiBundle\DependencyInjection\SyliusUiExtension;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\Definition;
|
use Symfony\Component\DependencyInjection\Definition;
|
||||||
|
|
||||||
final class SyliusUiExtensionTest extends AbstractExtensionTestCase
|
final class SyliusUiExtensionTest extends AbstractExtensionTestCase
|
||||||
|
|
@ -30,6 +31,7 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase
|
||||||
'first_event' => ['blocks' => [
|
'first_event' => ['blocks' => [
|
||||||
'first_block' => ['template' => 'first.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0],
|
'first_block' => ['template' => 'first.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0],
|
||||||
'second_block' => ['template' => 'second.html.twig', 'context' => ['foo' => 'bar'], 'enabled' => true, 'priority' => 0],
|
'second_block' => ['template' => 'second.html.twig', 'context' => ['foo' => 'bar'], 'enabled' => true, 'priority' => 0],
|
||||||
|
'third_block' => ['component' => 'component_name', 'context' => [], 'enabled' => true, 'priority' => 0],
|
||||||
]],
|
]],
|
||||||
'second_event' => ['blocks' => [
|
'second_event' => ['blocks' => [
|
||||||
'another_block' => ['template' => 'another.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0],
|
'another_block' => ['template' => 'another.html.twig', 'context' => [], 'enabled' => true, 'priority' => 0],
|
||||||
|
|
@ -37,15 +39,16 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase
|
||||||
]]);
|
]]);
|
||||||
|
|
||||||
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
|
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
|
||||||
TemplateBlockRegistryInterface::class,
|
BlockRegistryInterface::class,
|
||||||
0,
|
0,
|
||||||
[
|
[
|
||||||
'first_event' => [
|
'first_event' => [
|
||||||
'first_block' => new Definition(TemplateBlock::class, ['first_block', 'first_event', 'first.html.twig', [], 0, true, null]),
|
'first_block' => new Definition(TemplateBlock::class, ['first_block', 'first_event', 'first.html.twig', [], 0, true]),
|
||||||
'second_block' => new Definition(TemplateBlock::class, ['second_block', 'first_event', 'second.html.twig', ['foo' => 'bar'], 0, true, null]),
|
'second_block' => new Definition(TemplateBlock::class, ['second_block', 'first_event', 'second.html.twig', ['foo' => 'bar'], 0, true]),
|
||||||
|
'third_block' => new Definition(ComponentBlock::class, ['third_block', 'first_event', 'component_name', [], [], 0, true]),
|
||||||
],
|
],
|
||||||
'second_event' => [
|
'second_event' => [
|
||||||
'another_block' => new Definition(TemplateBlock::class, ['another_block', 'second_event', 'another.html.twig', [], 0, true, null]),
|
'another_block' => new Definition(TemplateBlock::class, ['another_block', 'second_event', 'another.html.twig', [], 0, true]),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
@ -66,13 +69,13 @@ final class SyliusUiExtensionTest extends AbstractExtensionTestCase
|
||||||
]]);
|
]]);
|
||||||
|
|
||||||
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
|
$this->assertContainerBuilderHasServiceDefinitionWithArgument(
|
||||||
TemplateBlockRegistryInterface::class,
|
BlockRegistryInterface::class,
|
||||||
0,
|
0,
|
||||||
['event_name' => [
|
['event_name' => [
|
||||||
'first_block' => new Definition(TemplateBlock::class, ['first_block', 'event_name', 'first.html.twig', [], 5, true, null]),
|
'first_block' => new Definition(TemplateBlock::class, ['first_block', 'event_name', 'first.html.twig', [], 5, true]),
|
||||||
'second_block' => new Definition(TemplateBlock::class, ['second_block', 'event_name', 'second.html.twig', [], 0, true, null]),
|
'second_block' => new Definition(TemplateBlock::class, ['second_block', 'event_name', 'second.html.twig', [], 0, true]),
|
||||||
'third_block' => new Definition(TemplateBlock::class, ['third_block', 'event_name', 'third.html.twig', [], 0, true, null]),
|
'third_block' => new Definition(TemplateBlock::class, ['third_block', 'event_name', 'third.html.twig', [], 0, true]),
|
||||||
'fourth_block' => new Definition(TemplateBlock::class, ['fourth_block', 'event_name', 'fourth.html.twig', [], -5, true, null]),
|
'fourth_block' => new Definition(TemplateBlock::class, ['fourth_block', 'event_name', 'fourth.html.twig', [], -5, true]),
|
||||||
]],
|
]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,16 @@ declare(strict_types=1);
|
||||||
namespace Sylius\Bundle\UiBundle\Tests\Functional\src;
|
namespace Sylius\Bundle\UiBundle\Tests\Functional\src;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
|
||||||
final class CustomContextProvider implements ContextProviderInterface
|
final class CustomContextProvider implements ContextProviderInterface
|
||||||
{
|
{
|
||||||
public function provide(array $templateContext, TemplateBlock $templateBlock): array
|
public function provide(array $templateContext, Block $templateBlock): array
|
||||||
{
|
{
|
||||||
return $templateContext + ['custom' => 'yolo'];
|
return $templateContext + ['custom' => 'yolo'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function supports(TemplateBlock $templateBlock): bool
|
public function supports(Block $templateBlock): bool
|
||||||
{
|
{
|
||||||
return 'custom_context_provider' === $templateBlock->getEventName();
|
return 'custom_context_provider' === $templateBlock->getEventName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Sylius\Bundle\UiBundle\Twig;
|
namespace Sylius\Bundle\UiBundle\Twig;
|
||||||
|
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface;
|
use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface;
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
use Twig\TwigFunction;
|
use Twig\TwigFunction;
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
|
|
||||||
final class TemplateEventExtension extends AbstractExtension
|
final class TemplateEventExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
public function __construct(private TemplateEventRendererInterface $templateEventRenderer)
|
public function __construct(private TwigEventRendererInterface $templateEventRenderer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace spec\Sylius\Bundle\UiBundle\ContextProvider;
|
||||||
|
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\ContextProvider\Exception\NoSupportedContextProvider;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Webmozart\Assert\InvalidArgumentException;
|
||||||
|
|
||||||
|
final class CompositeContextProviderSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
function it_is_a_context_provider(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith([]);
|
||||||
|
|
||||||
|
$this->shouldImplement(ContextProviderInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_any_of_passed_context_providers_is_not_a_context_provider(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith([new \stdClass()]);
|
||||||
|
|
||||||
|
$this->shouldThrow(InvalidArgumentException::class)->duringInstantiation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_no_context_provider_supports_a_given_block(
|
||||||
|
ContextProviderInterface $someContextProvider,
|
||||||
|
Block $someBlock,
|
||||||
|
): void {
|
||||||
|
$someBlock->getName()->willReturn('some_block');
|
||||||
|
|
||||||
|
$someContextProvider->supports($someBlock)->willReturn(false);
|
||||||
|
|
||||||
|
$this->beConstructedWith([$someContextProvider]);
|
||||||
|
|
||||||
|
$this->shouldThrow(new NoSupportedContextProvider('No supported context provider found for block "some_block".'))->during('provide', [[], $someBlock]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_returns_always_true_for_supports(Block $someBlock): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith([]);
|
||||||
|
|
||||||
|
$this->supports($someBlock)->shouldReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_returns_a_context_for_a_first_supported_context_provider(
|
||||||
|
ContextProviderInterface $someContextProvider,
|
||||||
|
ContextProviderInterface $anotherContextProvider,
|
||||||
|
ContextProviderInterface $yetAnotherContextProvider,
|
||||||
|
Block $someBlock,
|
||||||
|
): void {
|
||||||
|
$someBlock->getName()->willReturn('some_block');
|
||||||
|
|
||||||
|
$someContextProvider->supports($someBlock)->willReturn(false);
|
||||||
|
|
||||||
|
$anotherContextProvider->supports($someBlock)->willReturn(true);
|
||||||
|
$anotherContextProvider->provide(['foo' => 'bar'], $someBlock)->willReturn(['foo' => 'qux']);
|
||||||
|
|
||||||
|
$yetAnotherContextProvider->supports($someBlock)->shouldNotBeCalled();
|
||||||
|
|
||||||
|
$this->beConstructedWith([$someContextProvider, $anotherContextProvider]);
|
||||||
|
|
||||||
|
$this->provide(['foo' => 'bar'], $someBlock)->shouldReturn(['foo' => 'qux']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,19 +14,20 @@ declare(strict_types=1);
|
||||||
namespace spec\Sylius\Bundle\UiBundle\Registry;
|
namespace spec\Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
|
||||||
|
|
||||||
final class TemplateBlockRegistrySpec extends ObjectBehavior
|
final class BlockRegistrySpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function let(): void
|
function let(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith([]);
|
$this->beConstructedWith([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_is_a_template_block_registry(): void
|
function it_is_a_block_registry(): void
|
||||||
{
|
{
|
||||||
$this->shouldImplement(TemplateBlockRegistryInterface::class);
|
$this->shouldImplement(BlockRegistryInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_returns_all_template_blocks(): void
|
function it_returns_all_template_blocks(): void
|
||||||
|
|
@ -38,26 +39,28 @@ final class TemplateBlockRegistrySpec extends ObjectBehavior
|
||||||
$this->all()->shouldReturn(['event' => ['block_name' => $templateBlock]]);
|
$this->all()->shouldReturn(['event' => ['block_name' => $templateBlock]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_returns_enabled_template_blocks_for_a_given_event(): void
|
function it_returns_enabled_blocks_for_a_given_event(): void
|
||||||
{
|
{
|
||||||
$firstTemplateBlock = new TemplateBlock('first_block', 'event', 'first.html.twig', [], 0, true, null);
|
$firstBlock = new TemplateBlock('first_block', 'event', 'first.html.twig', [], 0, true, null);
|
||||||
$secondTemplateBlock = new TemplateBlock('second_block', 'event', 'second.html.twig', [], 10, false, null);
|
$secondBlock = new TemplateBlock('second_block', 'event', 'second.html.twig', [], 10, false, null);
|
||||||
$thirdTemplateBlock = new TemplateBlock('third_block', 'event', 'third.html.twig', [], 50, true, null);
|
$thirdBlock = new TemplateBlock('third_block', 'event', 'third.html.twig', [], 50, true, null);
|
||||||
|
$fourthBlock = new ComponentBlock('fourth_block', 'event', 'fourth.html.twig', [], [], 0, null);
|
||||||
|
|
||||||
$this->beConstructedWith([
|
$this->beConstructedWith([
|
||||||
'event' => [
|
'event' => [
|
||||||
'first_block' => $firstTemplateBlock,
|
'first_block' => $firstBlock,
|
||||||
'second_block' => $secondTemplateBlock,
|
'second_block' => $secondBlock,
|
||||||
],
|
],
|
||||||
'another_event' => [
|
'another_event' => [
|
||||||
'third_block' => $thirdTemplateBlock,
|
'third_block' => $thirdBlock,
|
||||||
|
'fourth_block' => $fourthBlock,
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->findEnabledForEvents(['event'])->shouldReturn([$firstTemplateBlock]);
|
$this->findEnabledForEvents(['event'])->shouldReturn([$firstBlock]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_returns_enabled_template_blocks_for_multiple_events(): void
|
function it_returns_enabled_blocks_for_multiple_events(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith([
|
$this->beConstructedWith([
|
||||||
'generic_event' => ['block' => new TemplateBlock('block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, true)],
|
'generic_event' => ['block' => new TemplateBlock('block', 'generic_event', 'generic.html.twig', ['foo' => 'bar'], 0, true)],
|
||||||
|
|
@ -82,7 +85,7 @@ final class TemplateBlockRegistrySpec extends ObjectBehavior
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_returns_enabled_template_blocks_sorted_by_priority_for_multiple_events(): void
|
function it_returns_enabled_blocks_sorted_by_priority_for_multiple_events(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith([
|
$this->beConstructedWith([
|
||||||
'generic_event' => [
|
'generic_event' => [
|
||||||
100
src/Sylius/Bundle/UiBundle/spec/Registry/ComponentBlockSpec.php
Normal file
100
src/Sylius/Bundle/UiBundle/spec/Registry/ComponentBlockSpec.php
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace spec\Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
|
|
||||||
|
final class ComponentBlockSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
function it_represents_a_component_block(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false);
|
||||||
|
|
||||||
|
$this->getName()->shouldReturn('block_name');
|
||||||
|
$this->getEventName()->shouldReturn('event_name');
|
||||||
|
$this->getComponentName()->shouldReturn('MyComponent');
|
||||||
|
$this->getComponentInputs()->shouldReturn(['my' => 'input']);
|
||||||
|
$this->getContext()->shouldReturn(['my' => 'context']);
|
||||||
|
$this->getPriority()->shouldReturn(10);
|
||||||
|
$this->isEnabled()->shouldReturn(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_overwrites_a_component_block_with_an_another_component_block(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->overwriteWith(
|
||||||
|
new ComponentBlock(
|
||||||
|
'block_name',
|
||||||
|
'specific_event_name',
|
||||||
|
'MyAnotherComponent',
|
||||||
|
['my' => 'another_input'],
|
||||||
|
['my' => 'another_context'],
|
||||||
|
20,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
->shouldBeLike(
|
||||||
|
new ComponentBlock(
|
||||||
|
'block_name',
|
||||||
|
'specific_event_name',
|
||||||
|
'MyAnotherComponent',
|
||||||
|
['my' => 'another_input'],
|
||||||
|
['my' => 'another_context'],
|
||||||
|
20,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_if_trying_to_overwrite_with_a_differently_named_block(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false);
|
||||||
|
|
||||||
|
$this->shouldThrow(\DomainException::class)->during(
|
||||||
|
'overwriteWith',
|
||||||
|
[
|
||||||
|
new ComponentBlock(
|
||||||
|
'another_block_name',
|
||||||
|
'specific_event_name',
|
||||||
|
'MyComponent',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_trying_to_override_template_block_with_template_block(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith('block_name', 'event_name', 'MyComponent', ['my' => 'input'], ['my' => 'context'], 10, false);
|
||||||
|
|
||||||
|
$exceptionMessage = sprintf(
|
||||||
|
'Trying to overwrite component block "%s" with block of different type "%s".',
|
||||||
|
'block_name',
|
||||||
|
'Sylius\Bundle\UiBundle\Registry\TemplateBlock',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->shouldThrow(new \DomainException($exceptionMessage))
|
||||||
|
->during('overwriteWith', [new TemplateBlock('block_name', 'specific_event_name', null, null, null, true)])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,18 +14,18 @@ declare(strict_types=1);
|
||||||
namespace spec\Sylius\Bundle\UiBundle\Registry;
|
namespace spec\Sylius\Bundle\UiBundle\Registry;
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
|
|
||||||
final class TemplateBlockSpec extends ObjectBehavior
|
final class TemplateBlockSpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function it_represents_a_template_block(): void
|
function it_represents_a_template_block(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false, null);
|
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false);
|
||||||
|
|
||||||
$this->getName()->shouldReturn('block_name');
|
$this->getName()->shouldReturn('block_name');
|
||||||
$this->getEventName()->shouldReturn('event_name');
|
$this->getEventName()->shouldReturn('event_name');
|
||||||
$this->getTemplate()->shouldReturn('block.html.twig');
|
$this->getTemplate()->shouldReturn('block.html.twig');
|
||||||
$this->getComponent()->shouldReturn(null);
|
|
||||||
$this->getContext()->shouldReturn(['foo' => 'bar']);
|
$this->getContext()->shouldReturn(['foo' => 'bar']);
|
||||||
$this->getPriority()->shouldReturn(10);
|
$this->getPriority()->shouldReturn(10);
|
||||||
$this->isEnabled()->shouldReturn(false);
|
$this->isEnabled()->shouldReturn(false);
|
||||||
|
|
@ -33,43 +33,59 @@ final class TemplateBlockSpec extends ObjectBehavior
|
||||||
|
|
||||||
function it_overwrites_a_template_block_with_an_another_template_block(): void
|
function it_overwrites_a_template_block_with_an_another_template_block(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false, null);
|
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false);
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', 'another.html.twig', null, null, null, 'some_component'))
|
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', 'another.html.twig', null, null, null))
|
||||||
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'another.html.twig', ['foo' => 'bar'], 10, false, 'some_component'))
|
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'another.html.twig', ['foo' => 'bar'], 10, false))
|
||||||
;
|
;
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, [], null, null, null))
|
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, [], null, null))
|
||||||
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', [], 10, false, null))
|
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', [], 10, false))
|
||||||
;
|
;
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, null, -5, null, null))
|
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, null, -5, null))
|
||||||
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', ['foo' => 'bar'], -5, false, null))
|
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', ['foo' => 'bar'], -5, false))
|
||||||
;
|
;
|
||||||
|
|
||||||
$this
|
$this
|
||||||
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, null, null, true, null))
|
->overwriteWith(new TemplateBlock('block_name', 'specific_event_name', null, null, null, true))
|
||||||
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', ['foo' => 'bar'], 10, true, null))
|
->shouldBeLike(new TemplateBlock('block_name', 'specific_event_name', 'block.html.twig', ['foo' => 'bar'], 10, true))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_throws_an_exception_if_trying_to_overwrite_with_a_differently_named_block(): void
|
function it_throws_an_exception_if_trying_to_overwrite_with_a_differently_named_block(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false, null);
|
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false);
|
||||||
|
|
||||||
$this->shouldThrow(\DomainException::class)->during('overwriteWith', [new TemplateBlock('different_name', 'specific_event_name', null, null, null, null, null)]);
|
$this->shouldThrow(\DomainException::class)->during('overwriteWith', [new TemplateBlock('different_name', 'specific_event_name', null, null, null, null)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_has_sensible_defaults(): void
|
function it_has_sensible_defaults(): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith('block_name', 'event_name', null, null, null, null, null);
|
$this->beConstructedWith('block_name', 'event_name', null, null, null, null);
|
||||||
|
|
||||||
$this->shouldThrow(\DomainException::class)->during('getTemplate');
|
$this->shouldThrow(\DomainException::class)->during('getTemplate');
|
||||||
$this->getContext()->shouldReturn([]);
|
$this->getContext()->shouldReturn([]);
|
||||||
$this->getPriority()->shouldReturn(0);
|
$this->getPriority()->shouldReturn(0);
|
||||||
$this->isEnabled()->shouldReturn(true);
|
$this->isEnabled()->shouldReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_trying_to_override_template_block_with_component_block(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith('block_name', 'event_name', 'block.html.twig', ['foo' => 'bar'], 10, false);
|
||||||
|
|
||||||
|
$exceptionMessage = sprintf(
|
||||||
|
'Trying to overwrite template block "%s" with block of different type "%s".',
|
||||||
|
'block_name',
|
||||||
|
'Sylius\Bundle\UiBundle\Registry\ComponentBlock',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->shouldThrow(new \DomainException($exceptionMessage))
|
||||||
|
->during('overwriteWith', [new ComponentBlock('block_name', 'specific_event_name', 'MyComponent', [], [], 0, false)])
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\Block;
|
||||||
|
use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Renderer\Exception\NoSupportedBlockRenderer;
|
||||||
|
use Sylius\Bundle\UiBundle\Renderer\SupportableBlockRendererInterface;
|
||||||
|
|
||||||
|
final class CompositeBlockRendererSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
function it_is_a_block_renderer(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith([]);
|
||||||
|
|
||||||
|
$this->shouldImplement(BlockRendererInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_any_of_passed_block_renderers_is_not_a_block_renderer(): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith([new \stdClass()]);
|
||||||
|
|
||||||
|
$this->shouldThrow(InvalidArgumentException::class)->duringInstantiation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_no_block_renderers_supports_a_given_block(
|
||||||
|
SupportableBlockRendererInterface $someBlockRenderer,
|
||||||
|
Block $someBlock,
|
||||||
|
): void {
|
||||||
|
$someBlock->getName()->willReturn('some_block');
|
||||||
|
|
||||||
|
$someBlockRenderer->supports($someBlock)->willReturn(false);
|
||||||
|
|
||||||
|
$this->beConstructedWith([$someBlockRenderer]);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->shouldThrow(new NoSupportedBlockRenderer('No supported block renderer found for "some_block" block.'))
|
||||||
|
->during('render', [$someBlock, []])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_renders_a_block_using_a_first_supported_block_renderer(
|
||||||
|
SupportableBlockRendererInterface $someBlockRenderer,
|
||||||
|
SupportableBlockRendererInterface $anotherBlockRenderer,
|
||||||
|
SupportableBlockRendererInterface $yetAnotherBlockRenderer,
|
||||||
|
Block $someBlock,
|
||||||
|
): void {
|
||||||
|
$someBlock->getName()->willReturn('some_block');
|
||||||
|
|
||||||
|
$someBlockRenderer->supports($someBlock)->willReturn(false);
|
||||||
|
|
||||||
|
$anotherBlockRenderer->supports($someBlock)->willReturn(true);
|
||||||
|
$anotherBlockRenderer->render($someBlock, [])->willReturn('Rendered block');
|
||||||
|
|
||||||
|
$yetAnotherBlockRenderer->supports($someBlock)->shouldNotBeCalled();
|
||||||
|
|
||||||
|
$this->beConstructedWith([$someBlockRenderer, $anotherBlockRenderer, $yetAnotherBlockRenderer]);
|
||||||
|
|
||||||
|
$this->render($someBlock, [])->shouldReturn('Rendered block');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,26 +15,26 @@ namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface;
|
use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface;
|
|
||||||
|
|
||||||
final class DelegatingTemplateEventRendererSpec extends ObjectBehavior
|
final class DelegatingTwigEventRendererSpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function let(TemplateBlockRegistryInterface $templateBlockRegistry, TemplateBlockRendererInterface $templateBlockRenderer): void
|
function let(BlockRegistryInterface $templateBlockRegistry, BlockRendererInterface $templateBlockRenderer): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith($templateBlockRegistry, $templateBlockRenderer);
|
$this->beConstructedWith($templateBlockRegistry, $templateBlockRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_is_a_template_event_renderer(): void
|
function it_is_a_twig_event_renderer(): void
|
||||||
{
|
{
|
||||||
$this->shouldImplement(TemplateEventRendererInterface::class);
|
$this->shouldImplement(TwigEventRendererInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_renders_template_events(
|
function it_renders_blocks_for_a_given_template(
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry,
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
TemplateBlockRendererInterface $templateBlockRenderer,
|
BlockRendererInterface $templateBlockRenderer,
|
||||||
): void {
|
): void {
|
||||||
$firstTemplateBlock = new TemplateBlock('first_block', 'best_event_ever', 'firstBlock.txt.twig', [], 0, true, null);
|
$firstTemplateBlock = new TemplateBlock('first_block', 'best_event_ever', 'firstBlock.txt.twig', [], 0, true, null);
|
||||||
$secondTemplateBlock = new TemplateBlock('second_block', 'best_event_ever', 'secondBlock.txt.twig', [], 0, true, null);
|
$secondTemplateBlock = new TemplateBlock('second_block', 'best_event_ever', 'secondBlock.txt.twig', [], 0, true, null);
|
||||||
|
|
@ -48,8 +48,8 @@ final class DelegatingTemplateEventRendererSpec extends ObjectBehavior
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_returns_an_empty_string_if_no_blocks_are_found_for_an_event(
|
function it_returns_an_empty_string_if_no_blocks_are_found_for_an_event(
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry,
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
TemplateBlockRendererInterface $templateBlockRenderer,
|
BlockRendererInterface $templateBlockRenderer,
|
||||||
): void {
|
): void {
|
||||||
$templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([]);
|
$templateBlockRegistry->findEnabledForEvents(['best_event_ever'])->willReturn([]);
|
||||||
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Sylius package.
|
||||||
|
*
|
||||||
|
* (c) Sylius Sp. z o.o.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
|
use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface;
|
||||||
|
|
||||||
|
final class HtmlDebugBlockRendererSpec extends ObjectBehavior
|
||||||
|
{
|
||||||
|
function let(BlockRendererInterface $templateBlockRenderer): void
|
||||||
|
{
|
||||||
|
$this->beConstructedWith($templateBlockRenderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_is_a_block_renderer(): void
|
||||||
|
{
|
||||||
|
$this->shouldImplement(BlockRendererInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_does_not_render_html_debug_comment_if_template_block_is_not_an_html_twig_file_path(
|
||||||
|
BlockRendererInterface $templateBlockRenderer,
|
||||||
|
): void {
|
||||||
|
$templateBlock = new TemplateBlock('block_name', 'event_name', 'template', [], 0, true);
|
||||||
|
|
||||||
|
$templateBlockRenderer->render($templateBlock, [])->willReturn('template');
|
||||||
|
|
||||||
|
$this->render($templateBlock)->shouldReturn('template');
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_renders_html_debug_comment_if_template_block_is_an_html_twig_file_path(
|
||||||
|
BlockRendererInterface $templateBlockRenderer,
|
||||||
|
): void {
|
||||||
|
$templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true);
|
||||||
|
|
||||||
|
$templateBlockRenderer->render($templateBlock, [])->willReturn('template');
|
||||||
|
|
||||||
|
$this->render($templateBlock)->shouldReturn(
|
||||||
|
'<!-- BEGIN BLOCK | event name: "event_name", block name: "block_name", template: "template.html.twig", priority: 0 -->' . "\n" .
|
||||||
|
'template' . "\n" .
|
||||||
|
'<!-- END BLOCK | event name: "event_name", block name: "block_name" -->',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_renders_html_debug_comment_if_the_block_is_a_component(
|
||||||
|
BlockRendererInterface $templateBlockRenderer,
|
||||||
|
): void {
|
||||||
|
$componentBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true);
|
||||||
|
|
||||||
|
$templateBlockRenderer->render($componentBlock, ['some' => 'context'])->willReturn('template');
|
||||||
|
|
||||||
|
$this->render($componentBlock, ['some' => 'context'])->shouldReturn(
|
||||||
|
'<!-- BEGIN BLOCK | event name: "event_name", block name: "block_name", component: "Component", priority: 0 -->' . "\n" .
|
||||||
|
'template' . "\n" .
|
||||||
|
'<!-- END BLOCK | event name: "event_name", block name: "block_name" -->',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Sylius package.
|
|
||||||
*
|
|
||||||
* (c) Sylius Sp. z o.o.
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface;
|
|
||||||
|
|
||||||
final class HtmlDebugTemplateBlockRendererSpec extends ObjectBehavior
|
|
||||||
{
|
|
||||||
function let(TemplateBlockRendererInterface $templateBlockRenderer): void
|
|
||||||
{
|
|
||||||
$this->beConstructedWith($templateBlockRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_is_a_template_block_renderer(): void
|
|
||||||
{
|
|
||||||
$this->shouldImplement(TemplateBlockRendererInterface::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_does_not_render_a_debug_html_comment_if_the_template_block_is_not_a_component_nor_a_twig_template(
|
|
||||||
TemplateBlockRendererInterface $templateBlockRenderer,
|
|
||||||
): void {
|
|
||||||
$templateBlock = new TemplateBlock('block_name', 'event_name', 'some_content', null, null, true, null);
|
|
||||||
|
|
||||||
$templateBlockRenderer->render($templateBlock, [])->willReturn('Rendered template');
|
|
||||||
|
|
||||||
$this->render($templateBlock, [])->shouldReturn('Rendered template');
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_renders_a_debug_html_comment_if_the_template_block_has_a_configured_component(
|
|
||||||
TemplateBlockRendererInterface $templateBlockRenderer,
|
|
||||||
): void {
|
|
||||||
$templateBlock = new TemplateBlock('block_name', 'event_name', 'some_content', null, null, true, 'component_name');
|
|
||||||
|
|
||||||
$templateBlockRenderer->render($templateBlock, [])->willReturn('Rendered template');
|
|
||||||
|
|
||||||
$this->render($templateBlock, [])->shouldReturn(
|
|
||||||
'<!-- BEGIN BLOCK | event name: "event_name", block name: "block_name", component: "component_name", priority: 0 -->' . "\n" .
|
|
||||||
'Rendered template' . "\n" .
|
|
||||||
'<!-- END BLOCK | event name: "event_name", block name: "block_name" -->'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_renders_a_debug_html_comment_if_the_template_block_has_a_configured_twig_template(
|
|
||||||
TemplateBlockRendererInterface $templateBlockRenderer,
|
|
||||||
): void {
|
|
||||||
$templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], null, true, null);
|
|
||||||
|
|
||||||
$templateBlockRenderer->render($templateBlock, [])->willReturn('Rendered template');
|
|
||||||
|
|
||||||
$this->render($templateBlock, [])->shouldReturn(
|
|
||||||
'<!-- BEGIN BLOCK | event name: "event_name", block name: "block_name", template: "template.html.twig", priority: 0 -->' . "\n" .
|
|
||||||
'Rendered template' . "\n" .
|
|
||||||
'<!-- END BLOCK | event name: "event_name", block name: "block_name" -->'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,25 +14,26 @@ declare(strict_types=1);
|
||||||
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\BlockRegistryInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlockRegistryInterface;
|
use Sylius\Bundle\UiBundle\Renderer\TwigEventRendererInterface;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateEventRendererInterface;
|
|
||||||
|
|
||||||
final class HtmlDebugTemplateEventRendererSpec extends ObjectBehavior
|
final class HtmlDebugTwigEventRendererSpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function let(TemplateEventRendererInterface $templateEventRenderer, TemplateBlockRegistryInterface $templateBlockRegistry): void
|
function let(TwigEventRendererInterface $templateEventRenderer, BlockRegistryInterface $templateBlockRegistry): void
|
||||||
{
|
{
|
||||||
$this->beConstructedWith($templateEventRenderer, $templateBlockRegistry);
|
$this->beConstructedWith($templateEventRenderer, $templateBlockRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_is_a_template_event_renderer(): void
|
function it_is_a_template_event_renderer(): void
|
||||||
{
|
{
|
||||||
$this->shouldImplement(TemplateEventRendererInterface::class);
|
$this->shouldImplement(TwigEventRendererInterface::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_does_not_render_html_debug_comments_when_there_are_no_template_blocks_with_a_defined_component_nor_template(
|
function it_does_not_render_html_debug_comments_when_there_are_no_template_blocks_with_a_defined_component_nor_template(
|
||||||
TemplateEventRendererInterface $templateEventRenderer,
|
TwigEventRendererInterface $templateEventRenderer,
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
): void {
|
): void {
|
||||||
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
||||||
new TemplateBlock('some_block_one', 'some_event', 'some content', null, null, true, null),
|
new TemplateBlock('some_block_one', 'some_event', 'some content', null, null, true, null),
|
||||||
|
|
@ -44,8 +45,8 @@ final class HtmlDebugTemplateEventRendererSpec extends ObjectBehavior
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_renders_html_debug_comment_when_no_template_block_passed(
|
function it_renders_html_debug_comment_when_no_template_block_passed(
|
||||||
TemplateEventRendererInterface $templateEventRenderer,
|
TwigEventRendererInterface $templateEventRenderer,
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
): void {
|
): void {
|
||||||
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([]);
|
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([]);
|
||||||
|
|
||||||
|
|
@ -54,16 +55,16 @@ final class HtmlDebugTemplateEventRendererSpec extends ObjectBehavior
|
||||||
$this->render(['event_name'])->shouldReturn(
|
$this->render(['event_name'])->shouldReturn(
|
||||||
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
||||||
'rendered_content' . "\n" .
|
'rendered_content' . "\n" .
|
||||||
'<!-- END EVENT | event name: "event_name" -->'
|
'<!-- END EVENT | event name: "event_name" -->',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_component(
|
function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_component(
|
||||||
TemplateEventRendererInterface $templateEventRenderer,
|
TwigEventRendererInterface $templateEventRenderer,
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
): void {
|
): void {
|
||||||
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
||||||
new TemplateBlock('some_block_one', 'some_event', 'some content', null, null, true, 'SomeComponent'),
|
new ComponentBlock('some_block_one', 'some_event', 'Component', [], [], 0, true),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content');
|
$templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content');
|
||||||
|
|
@ -71,16 +72,16 @@ final class HtmlDebugTemplateEventRendererSpec extends ObjectBehavior
|
||||||
$this->render(['event_name'])->shouldReturn(
|
$this->render(['event_name'])->shouldReturn(
|
||||||
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
||||||
'rendered_content' . "\n" .
|
'rendered_content' . "\n" .
|
||||||
'<!-- END EVENT | event name: "event_name" -->'
|
'<!-- END EVENT | event name: "event_name" -->',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_twig_template(
|
function it_renders_html_debug_comment_when_at_least_one_block_has_a_configured_twig_template(
|
||||||
TemplateEventRendererInterface $templateEventRenderer,
|
TwigEventRendererInterface $templateEventRenderer,
|
||||||
TemplateBlockRegistryInterface $templateBlockRegistry
|
BlockRegistryInterface $templateBlockRegistry,
|
||||||
): void {
|
): void {
|
||||||
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
$templateBlockRegistry->findEnabledForEvents(['event_name'])->willReturn([
|
||||||
new TemplateBlock('some_block_one', 'some_event', 'some_template.html.twig', null, null, true, null),
|
new TemplateBlock('some_block_one', 'some_event', 'template.html.twig', null, null, true),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content');
|
$templateEventRenderer->render(['event_name'], [])->willReturn('rendered_content');
|
||||||
|
|
@ -88,7 +89,7 @@ final class HtmlDebugTemplateEventRendererSpec extends ObjectBehavior
|
||||||
$this->render(['event_name'])->shouldReturn(
|
$this->render(['event_name'])->shouldReturn(
|
||||||
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
'<!-- BEGIN EVENT | event name: "event_name" -->' . "\n" .
|
||||||
'rendered_content' . "\n" .
|
'rendered_content' . "\n" .
|
||||||
'<!-- END EVENT | event name: "event_name" -->'
|
'<!-- END EVENT | event name: "event_name" -->',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,51 +14,91 @@ declare(strict_types=1);
|
||||||
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
|
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface;
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
use Symfony\UX\TwigComponent\ComponentRendererInterface;
|
use Symfony\UX\TwigComponent\ComponentRendererInterface;
|
||||||
|
|
||||||
final class TwigComponentBlockRendererSpec extends ObjectBehavior
|
final class TwigComponentBlockRendererSpec extends ObjectBehavior
|
||||||
{
|
{
|
||||||
function let(TemplateBlockRendererInterface $decoratedRenderer, ComponentRendererInterface $componentRenderer): void
|
function let(
|
||||||
{
|
|
||||||
$this->beConstructedWith($decoratedRenderer, $componentRenderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_invokes_decorated_renderer_when_no_component_is_set(
|
|
||||||
TemplateBlockRendererInterface $decoratedRenderer,
|
|
||||||
): void {
|
|
||||||
$someTemplateBlock = new TemplateBlock(
|
|
||||||
'some_name',
|
|
||||||
'some_event_name',
|
|
||||||
'some_template',
|
|
||||||
['some' => 'context'],
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
$decoratedRenderer->render($someTemplateBlock, ['some' => 'context'])->shouldBeCalled();
|
|
||||||
|
|
||||||
$this->render($someTemplateBlock, ['some' => 'context']);
|
|
||||||
}
|
|
||||||
|
|
||||||
function it_renders_a_component_when_component_is_set(
|
|
||||||
ComponentRendererInterface $componentRenderer,
|
ComponentRendererInterface $componentRenderer,
|
||||||
|
ContextProviderInterface $contextProvider,
|
||||||
|
ExpressionLanguage $expressionLanguage,
|
||||||
): void {
|
): void {
|
||||||
$someTemplateBlock = new TemplateBlock(
|
$this->beConstructedWith(
|
||||||
'some_name',
|
$componentRenderer,
|
||||||
'some_event_name',
|
$contextProvider,
|
||||||
'some_template',
|
$expressionLanguage,
|
||||||
['another' => 'value'],
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_returns_true_if_block_is_supported(): void
|
||||||
|
{
|
||||||
|
$templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true);
|
||||||
|
$componentBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true);
|
||||||
|
|
||||||
|
$this->supports($templateBlock)->shouldReturn(false);
|
||||||
|
$this->supports($componentBlock)->shouldReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_trying_to_render_unsupported_block(): void
|
||||||
|
{
|
||||||
|
$templateBlock = new TemplateBlock('block_name', 'event_name', 'template.html.twig', [], 0, true);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->shouldThrow(\InvalidArgumentException::class)
|
||||||
|
->during('render', [$templateBlock])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_renders_component_block(
|
||||||
|
ComponentRendererInterface $componentRenderer,
|
||||||
|
ContextProviderInterface $contextProvider,
|
||||||
|
ExpressionLanguage $expressionLanguage,
|
||||||
|
): void {
|
||||||
|
$componentBlock = new ComponentBlock(
|
||||||
|
'block_name',
|
||||||
|
'event_name',
|
||||||
|
'Component',
|
||||||
|
[
|
||||||
|
'foo' => 'bar',
|
||||||
|
'bar' => 'expr:foo',
|
||||||
|
'nested' => [
|
||||||
|
'foo' => 'expr:bar',
|
||||||
|
'bar' => 'expr:baz',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[],
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
'some_component',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$context = [
|
||||||
|
'foo' => 'bar',
|
||||||
|
'bar' => 'baz',
|
||||||
|
'baz' => 'qux',
|
||||||
|
];
|
||||||
|
|
||||||
|
$contextProvider->provide([], $componentBlock)->willReturn($context);
|
||||||
|
|
||||||
|
$expressionLanguage->evaluate('foo', $context)->willReturn('bar');
|
||||||
|
$expressionLanguage->evaluate('bar', $context)->willReturn('baz');
|
||||||
|
$expressionLanguage->evaluate('baz', $context)->willReturn('qux');
|
||||||
|
|
||||||
$componentRenderer
|
$componentRenderer
|
||||||
->createAndRender('some_component', ['context' => ['another' => 'value', 'some' => 'value']])
|
->createAndRender('Component', [
|
||||||
->willReturn('some_rendered_component')
|
'foo' => 'bar',
|
||||||
|
'bar' => 'bar',
|
||||||
|
'nested' => [
|
||||||
|
'foo' => 'baz',
|
||||||
|
'bar' => 'qux',
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->willReturn('rendered_component')
|
||||||
;
|
;
|
||||||
|
|
||||||
$this->render($someTemplateBlock, ['some' => 'value'])->shouldReturn('some_rendered_component');
|
$this->render($componentBlock)->shouldReturn('rendered_component');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,9 @@ namespace spec\Sylius\Bundle\UiBundle\Renderer;
|
||||||
use PhpSpec\ObjectBehavior;
|
use PhpSpec\ObjectBehavior;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
||||||
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
use Sylius\Bundle\UiBundle\ContextProvider\ContextProviderInterface;
|
||||||
|
use Sylius\Bundle\UiBundle\Registry\ComponentBlock;
|
||||||
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
use Sylius\Bundle\UiBundle\Registry\TemplateBlock;
|
||||||
use Sylius\Bundle\UiBundle\Renderer\TemplateBlockRendererInterface;
|
use Sylius\Bundle\UiBundle\Renderer\BlockRendererInterface;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
|
||||||
final class TwigTemplateBlockRendererSpec extends ObjectBehavior
|
final class TwigTemplateBlockRendererSpec extends ObjectBehavior
|
||||||
|
|
@ -35,7 +36,17 @@ final class TwigTemplateBlockRendererSpec extends ObjectBehavior
|
||||||
|
|
||||||
function it_is_a_template_block_renderer(): void
|
function it_is_a_template_block_renderer(): void
|
||||||
{
|
{
|
||||||
$this->shouldImplement(TemplateBlockRendererInterface::class);
|
$this->shouldImplement(BlockRendererInterface::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
function it_throws_an_exception_when_trying_to_render_unsupported_block(): void
|
||||||
|
{
|
||||||
|
$templateBlock = new ComponentBlock('block_name', 'event_name', 'Component', [], [], 0, true);
|
||||||
|
|
||||||
|
$this
|
||||||
|
->shouldThrow(\InvalidArgumentException::class)
|
||||||
|
->during('render', [$templateBlock])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
function it_renders_a_template_block(
|
function it_renders_a_template_block(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue