diff --git a/composer.json b/composer.json index dc61d020c..63cfd0556 100644 --- a/composer.json +++ b/composer.json @@ -26,11 +26,11 @@ "doctrine/doctrine-bundle": "^2.5", "doctrine/persistence": "^2.1", "sonata-project/admin-bundle": "^3.99", - "sonata-project/block-bundle": "^3.20", + "sonata-project/block-bundle": "^4.11", "sonata-project/doctrine-extensions": "^1.8", "sonata-project/doctrine-orm-admin-bundle": "^3.19", "sonata-project/form-extensions": "^1.4", - "sonata-project/seo-bundle": "^2.11", + "sonata-project/seo-bundle": "^3.0", "sonata-project/twig-extensions": "^1.3", "symfony-cmf/routing-bundle": "^2.1", "symfony/config": "^4.4 || ^5.4", @@ -45,7 +45,6 @@ "symfony/routing": "^4.4 || ^5.4", "symfony/security-core": "^4.4", "symfony/security-http": "^4.4", - "symfony/templating": "^4.4 || ^5.4", "symfony/validator": "^4.4 || ^5.4", "twig/string-extra": "^3.0", "twig/twig": "^2.12.1 || ^3.0" diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index a88b34ff7..000000000 --- a/phpstan-baseline.neon +++ /dev/null @@ -1,6 +0,0 @@ -parameters: - ignoreErrors: - - # NEXT_MAJOR: Fix this one in SonataBlockBundle 4.x - message: "#^PHPDoc type Doctrine\\\\Common\\\\Collections\\\\Collection\\<\\(int\\|string\\), Sonata\\\\PageBundle\\\\Model\\\\PageBlockInterface\\> of property Sonata\\\\PageBundle\\\\Entity\\\\BaseBlock\\:\\:\\$children is not covariant with PHPDoc type array\\ of overridden property Sonata\\\\BlockBundle\\\\Model\\\\BaseBlock\\:\\:\\$children\\.$#" - count: 1 - path: src/Entity/BaseBlock.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 406f35f92..54c849fd0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,4 @@ includes: - - phpstan-baseline.neon - vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: diff --git a/src/Admin/BaseBlockAdmin.php b/src/Admin/BaseBlockAdmin.php index 08bfcca7c..69654a180 100644 --- a/src/Admin/BaseBlockAdmin.php +++ b/src/Admin/BaseBlockAdmin.php @@ -229,12 +229,7 @@ private function loadBlockDefaults(PageBlockInterface $block): PageBlockInterfac $resolver = new OptionsResolver(); // use new interface method whenever possible - // NEXT_MAJOR: Remove this check and legacy setDefaultSettings method call - if (method_exists($service, 'configureSettings')) { - $service->configureSettings($resolver); - } else { - $service->setDefaultSettings($resolver); - } + $service->configureSettings($resolver); try { $block->setSettings($resolver->resolve($block->getSettings())); diff --git a/src/Admin/BlockAdmin.php b/src/Admin/BlockAdmin.php index 896056338..f0e7ad171 100644 --- a/src/Admin/BlockAdmin.php +++ b/src/Admin/BlockAdmin.php @@ -16,7 +16,7 @@ use Doctrine\ORM\EntityRepository; use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Route\RouteCollection; -use Sonata\BlockBundle\Block\BlockServiceInterface; +use Sonata\BlockBundle\Block\Service\BlockServiceInterface; use Sonata\BlockBundle\Block\Service\EditableBlockService; use Sonata\BlockBundle\Form\Type\ServiceListType; use Sonata\BlockBundle\Model\BlockInterface; @@ -190,13 +190,7 @@ protected function configureFormFields(FormMapper $form): void private function getDefaultTemplate(BlockServiceInterface $blockService) { $resolver = new OptionsResolver(); - // use new interface method whenever possible - // NEXT_MAJOR: Remove this check and legacy setDefaultSettings method call - if (method_exists($blockService, 'configureSettings')) { - $blockService->configureSettings($resolver); - } else { - $blockService->setDefaultSettings($resolver); - } + $blockService->configureSettings($resolver); $options = $resolver->resolve(); return $options['template'] ?? null; diff --git a/src/Block/BlockContextManager.php b/src/Block/BlockContextManager.php index 8e08fab59..c4f104706 100644 --- a/src/Block/BlockContextManager.php +++ b/src/Block/BlockContextManager.php @@ -13,34 +13,38 @@ namespace Sonata\PageBundle\Block; -use Sonata\BlockBundle\Block\BlockContextManager as BaseBlockContextManager; -use Sonata\BlockBundle\Model\BlockInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; +use Sonata\BlockBundle\Block\BlockContextInterface; +use Sonata\BlockBundle\Block\BlockContextManagerInterface; -/** - * NEXT_MAJOR: Do not extend from `BlockContextManager` since it will be final. - * - * @psalm-suppress InvalidExtendClass - * @phpstan-ignore-next-line - */ -final class BlockContextManager extends BaseBlockContextManager +final class BlockContextManager implements BlockContextManagerInterface { - protected function configureSettings(OptionsResolver $optionsResolver, BlockInterface $block): void + private BlockContextManagerInterface $blockContextManager; + + public function __construct(BlockContextManagerInterface $blockContextManager) + { + $this->blockContextManager = $blockContextManager; + } + + public function addSettingsByType(string $type, array $settings, bool $replace = false): void { - parent::configureSettings($optionsResolver, $block); + $this->blockContextManager->addSettingsByType($type, $settings, $replace); + } - $optionsResolver->setDefaults([ + public function addSettingsByClass(string $class, array $settings, bool $replace = false): void + { + $this->blockContextManager->addSettingsByClass($class, $settings, $replace); + } + + public function get($meta, array $settings = []): BlockContextInterface + { + return $this->blockContextManager->get($meta, [ 'manager' => false, 'page_id' => false, ]); + } - $optionsResolver - ->addAllowedTypes('manager', ['string', 'bool']) - ->addAllowedTypes('page_id', ['int', 'string', 'bool']); - - $optionsResolver->setRequired([ - 'manager', - 'page_id', - ]); + public function exists(string $type): bool + { + return $this->blockContextManager->exists($type); } } diff --git a/src/Block/BreadcrumbBlockService.php b/src/Block/BreadcrumbBlockService.php index bf0815ec4..deb631a82 100644 --- a/src/Block/BreadcrumbBlockService.php +++ b/src/Block/BreadcrumbBlockService.php @@ -15,17 +15,15 @@ use Knp\Menu\FactoryInterface; use Knp\Menu\ItemInterface; -use Knp\Menu\Provider\MenuProviderInterface; use Sonata\BlockBundle\Block\BlockContextInterface; use Sonata\BlockBundle\Meta\Metadata; +use Sonata\BlockBundle\Meta\MetadataInterface; use Sonata\PageBundle\CmsManager\CmsManagerSelectorInterface; use Sonata\PageBundle\Model\PageInterface; use Sonata\SeoBundle\Block\Breadcrumb\BaseBreadcrumbMenuBlockService; -use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use Twig\Environment; /** - * BlockService for homepage breadcrumb. - * * @author Sylvain Deloux */ final class BreadcrumbBlockService extends BaseBreadcrumbMenuBlockService @@ -33,36 +31,35 @@ final class BreadcrumbBlockService extends BaseBreadcrumbMenuBlockService /** * @var CmsManagerSelectorInterface */ - protected $cmsSelector; + private $cmsSelector; - /** - * @param string $context - * @param string $name - */ - public function __construct($context, $name, EngineInterface $templating, MenuProviderInterface $menuProvider, FactoryInterface $factory, CmsManagerSelectorInterface $cmsSelector) - { - $this->cmsSelector = $cmsSelector; + public function __construct( + Environment $twig, + FactoryInterface $factory, + CmsManagerSelectorInterface $cmsSelector + ) { + parent::__construct($twig, $factory); - parent::__construct($context, $name, $templating, $menuProvider, $factory); + $this->cmsSelector = $cmsSelector; } - public function getName() + public function getMetadata(): MetadataInterface { - return 'sonata.page.block.breadcrumb'; + return new Metadata($this->getName(), null, null, 'SonataPageBundle', [ + 'class' => 'fa fa-bars', + ]); } - public function getBlockMetadata($code = null) + public function handleContext(string $context): bool { - return new Metadata($this->getName(), (null !== $code ? $code : $this->getName()), false, 'SonataPageBundle', [ - 'class' => 'fa fa-bars', - ]); + return $this->getName() === $context; } - protected function getMenu(BlockContextInterface $blockContext) + protected function getMenu(BlockContextInterface $blockContext): ItemInterface { $blockContext->setSetting('include_homepage_link', false); - $menu = $this->getRootMenu($blockContext); + $menu = parent::getMenu($blockContext); $page = $this->getCurrentPage(); @@ -87,12 +84,15 @@ protected function getMenu(BlockContextInterface $blockContext) return $menu; } + private function getName() + { + return 'sonata.page.block.breadcrumb'; + } + /** - * Return the current Page. - * * @return PageInterface|null */ - protected function getCurrentPage() + private function getCurrentPage() { $cms = $this->cmsSelector->retrieve(); diff --git a/src/Block/ChildrenPagesBlockService.php b/src/Block/ChildrenPagesBlockService.php index 95c7fa7e8..4d0279184 100755 --- a/src/Block/ChildrenPagesBlockService.php +++ b/src/Block/ChildrenPagesBlockService.php @@ -13,15 +13,21 @@ namespace Sonata\PageBundle\Block; -use Sonata\AdminBundle\Form\FormMapper; +use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\BlockBundle\Block\BlockContextInterface; use Sonata\BlockBundle\Block\Service\AbstractBlockService; +use Sonata\BlockBundle\Block\Service\EditableBlockService; +use Sonata\BlockBundle\Form\Mapper\FormMapper; +use Sonata\BlockBundle\Meta\Metadata; +use Sonata\BlockBundle\Meta\MetadataInterface; use Sonata\BlockBundle\Model\BlockInterface; use Sonata\Form\Type\ImmutableArrayType; +use Sonata\Form\Validator\ErrorElement; use Sonata\PageBundle\CmsManager\CmsManagerSelectorInterface; use Sonata\PageBundle\Exception\PageNotFoundException; use Sonata\PageBundle\Form\Type\PageSelectorType; use Sonata\PageBundle\Model\PageBlockInterface; +use Sonata\PageBundle\Model\PageInterface; use Sonata\PageBundle\Site\SiteSelectorInterface; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -34,21 +40,31 @@ * * @author Thomas Rabaix */ -final class ChildrenPagesBlockService extends AbstractBlockService +final class ChildrenPagesBlockService extends AbstractBlockService implements EditableBlockService { private SiteSelectorInterface $siteSelector; private CmsManagerSelectorInterface $cmsManagerSelector; - public function __construct(Environment $twig, SiteSelectorInterface $siteSelector, CmsManagerSelectorInterface $cmsManagerSelector) - { + /** + * @var AdminInterface + */ + private AdminInterface $pageAdmin; + + public function __construct( + Environment $twig, + SiteSelectorInterface $siteSelector, + CmsManagerSelectorInterface $cmsManagerSelector, + AdminInterface $pageAdmin + ) { parent::__construct($twig); $this->siteSelector = $siteSelector; $this->cmsManagerSelector = $cmsManagerSelector; + $this->pageAdmin = $pageAdmin; } - public function execute(BlockContextInterface $blockContext, ?Response $response = null) + public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { $settings = $blockContext->getSettings(); @@ -76,7 +92,14 @@ public function execute(BlockContextInterface $blockContext, ?Response $response ], $response); } - public function buildEditForm(FormMapper $form, BlockInterface $block): void + public function getMetadata(): MetadataInterface + { + return new Metadata('Children Page (core)', null, null, 'SonataPageBundle', [ + 'class' => 'fa fa-home', + ]); + } + + public function configureEditForm(FormMapper $form, BlockInterface $block): void { if (!$block instanceof PageBlockInterface) { return; @@ -101,8 +124,8 @@ public function buildEditForm(FormMapper $form, BlockInterface $block): void 'label' => 'form.label_current', ]], ['pageId', PageSelectorType::class, [ - 'model_manager' => $form->getAdmin()->getModelManager(), - 'class' => $form->getAdmin()->getClass(), + 'model_manager' => $this->pageAdmin->getModelManager(), + 'class' => $this->pageAdmin->getClass(), 'site' => $block->getPage()->getSite(), 'required' => false, 'label' => 'form.label_page', @@ -116,9 +139,13 @@ public function buildEditForm(FormMapper $form, BlockInterface $block): void ]); } - public function getName(): string + public function configureCreateForm(FormMapper $form, BlockInterface $block): void + { + $this->configureEditForm($form, $block); + } + + public function validate(ErrorElement $errorElement, BlockInterface $block): void { - return 'Children Page (core)'; } public function configureSettings(OptionsResolver $resolver): void diff --git a/src/Block/ContainerBlockService.php b/src/Block/ContainerBlockService.php index 929206977..9d2d41f76 100644 --- a/src/Block/ContainerBlockService.php +++ b/src/Block/ContainerBlockService.php @@ -13,22 +13,67 @@ namespace Sonata\PageBundle\Block; +use Sonata\BlockBundle\Block\BlockContextInterface; +use Sonata\BlockBundle\Block\Service\BlockServiceInterface; use Sonata\BlockBundle\Block\Service\ContainerBlockService as BaseContainerBlockService; +use Sonata\BlockBundle\Block\Service\EditableBlockService; +use Sonata\BlockBundle\Form\Mapper\FormMapper; use Sonata\BlockBundle\Meta\Metadata; +use Sonata\BlockBundle\Meta\MetadataInterface; +use Sonata\BlockBundle\Model\BlockInterface; +use Sonata\Form\Validator\ErrorElement; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\OptionsResolver\OptionsResolver; /** - * NEXT_MAJOR: Do not extend from `ContainerBlockService` since it will be final. - * - * Render children pages. - * * @author Thomas Rabaix - * - * @psalm-suppress InvalidExtendClass - * @phpstan-ignore-next-line */ -final class ContainerBlockService extends BaseContainerBlockService +final class ContainerBlockService implements BlockServiceInterface, EditableBlockService { + private BaseContainerBlockService $containerBlockService; + + public function __construct(BaseContainerBlockService $containerBlockService) + { + $this->containerBlockService = $containerBlockService; + } + + public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response + { + return $this->containerBlockService->execute($blockContext, $response); + } + + public function load(BlockInterface $block): void + { + $this->containerBlockService->load($block); + } + + public function getCacheKeys(BlockInterface $block): array + { + return $this->containerBlockService->getCacheKeys($block); + } + + public function configureEditForm(FormMapper $form, BlockInterface $block): void + { + $this->containerBlockService->configureEditForm($form, $block); + } + + public function configureCreateForm(FormMapper $form, BlockInterface $block): void + { + $this->containerBlockService->configureCreateForm($form, $block); + } + + public function validate(ErrorElement $errorElement, BlockInterface $block): void + { + $this->containerBlockService->validate($errorElement, $block); + } + + public function getMetadata(): MetadataInterface + { + return new Metadata('sonata.page.block.container', null, null, 'SonataPageBundle', [ + 'class' => 'fa fa-square-o', + ]); + } + public function configureSettings(OptionsResolver $resolver): void { $resolver->setDefaults([ @@ -38,11 +83,4 @@ public function configureSettings(OptionsResolver $resolver): void 'template' => '@SonataPage/Block/block_container.html.twig', ]); } - - public function getBlockMetadata($code = null) - { - return new Metadata($this->getName(), (null !== $code ? $code : $this->getName()), false, 'SonataPageBundle', [ - 'class' => 'fa fa-square-o', - ]); - } } diff --git a/src/Block/PageListBlockService.php b/src/Block/PageListBlockService.php index 593a4248b..4ea8f92d0 100755 --- a/src/Block/PageListBlockService.php +++ b/src/Block/PageListBlockService.php @@ -13,12 +13,15 @@ namespace Sonata\PageBundle\Block; -use Sonata\AdminBundle\Form\FormMapper; use Sonata\BlockBundle\Block\BlockContextInterface; use Sonata\BlockBundle\Block\Service\AbstractBlockService; +use Sonata\BlockBundle\Block\Service\EditableBlockService; +use Sonata\BlockBundle\Form\Mapper\FormMapper; use Sonata\BlockBundle\Meta\Metadata; +use Sonata\BlockBundle\Meta\MetadataInterface; use Sonata\BlockBundle\Model\BlockInterface; use Sonata\Form\Type\ImmutableArrayType; +use Sonata\Form\Validator\ErrorElement; use Sonata\PageBundle\Model\PageInterface; use Sonata\PageBundle\Model\PageManagerInterface; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -27,18 +30,59 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Twig\Environment; -final class PageListBlockService extends AbstractBlockService +final class PageListBlockService extends AbstractBlockService implements EditableBlockService { private PageManagerInterface $pageManager; - public function __construct(Environment $twig, PageManagerInterface $pageManager) - { + public function __construct( + Environment $twig, + PageManagerInterface $pageManager + ) { parent::__construct($twig); $this->pageManager = $pageManager; } - public function buildEditForm(FormMapper $form, BlockInterface $block): void + public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response + { + $pageList = $this->pageManager->findBy([ + 'routeName' => PageInterface::PAGE_ROUTE_CMS_NAME, + ]); + + $systemElements = $this->pageManager->findBy([ + 'url' => null, + 'parent' => null, + ]); + + return $this->renderResponse($blockContext->getTemplate(), [ + 'context' => $blockContext, + 'block' => $blockContext->getBlock(), + 'settings' => $blockContext->getSettings(), + 'elements' => $pageList, + 'systemElements' => $systemElements, + ], $response); + } + + public function configureSettings(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'mode' => 'public', + 'title' => null, + 'translation_domain' => null, + 'icon' => 'fa fa-globe', + 'class' => null, + 'template' => '@SonataPage/Block/block_pagelist.html.twig', + ]); + } + + public function getMetadata(): MetadataInterface + { + return new Metadata('sonata.page.block.pagelist', null, null, 'SonataPageBundle', [ + 'class' => 'fa fa-home', + ]); + } + + public function configureEditForm(FormMapper $form, BlockInterface $block): void { $form->add('settings', ImmutableArrayType::class, [ 'keys' => [ @@ -70,42 +114,12 @@ public function buildEditForm(FormMapper $form, BlockInterface $block): void ]); } - public function execute(BlockContextInterface $blockContext, ?Response $response = null) + public function configureCreateForm(FormMapper $form, BlockInterface $block): void { - $pageList = $this->pageManager->findBy([ - 'routeName' => PageInterface::PAGE_ROUTE_CMS_NAME, - ]); - - $systemElements = $this->pageManager->findBy([ - 'url' => null, - 'parent' => null, - ]); - - return $this->renderResponse($blockContext->getTemplate(), [ - 'context' => $blockContext, - 'block' => $blockContext->getBlock(), - 'settings' => $blockContext->getSettings(), - 'elements' => $pageList, - 'systemElements' => $systemElements, - ], $response); - } - - public function configureSettings(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'mode' => 'public', - 'title' => null, - 'translation_domain' => null, - 'icon' => 'fa fa-globe', - 'class' => null, - 'template' => '@SonataPage/Block/block_pagelist.html.twig', - ]); + $this->configureEditForm($form, $block); } - public function getBlockMetadata($code = null) + public function validate(ErrorElement $errorElement, BlockInterface $block): void { - return new Metadata($this->getName(), (null !== $code ? $code : $this->getName()), false, 'SonataPageBundle', [ - 'class' => 'fa fa-home', - ]); } } diff --git a/src/Block/SharedBlockBlockService.php b/src/Block/SharedBlockBlockService.php index 1ed1d30f9..343813dac 100755 --- a/src/Block/SharedBlockBlockService.php +++ b/src/Block/SharedBlockBlockService.php @@ -13,7 +13,7 @@ namespace Sonata\PageBundle\Block; -use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Sonata\AdminBundle\Admin\AdminInterface; use Sonata\AdminBundle\Form\FormMapper; use Sonata\AdminBundle\Form\Type\ModelListType; use Sonata\BlockBundle\Block\BlockContextInterface; @@ -22,8 +22,8 @@ use Sonata\Doctrine\Model\ManagerInterface; use Sonata\Form\Type\ImmutableArrayType; use Sonata\Form\Validator\ErrorElement; -use Sonata\PageBundle\Admin\SharedBlockAdmin; use Sonata\PageBundle\Model\Block; +use Sonata\PageBundle\Model\PageBlockInterface; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -31,25 +31,29 @@ use Twig\Environment; /** - * Render a shared block. - * * @author Romain Mouillard */ final class SharedBlockBlockService extends AbstractBlockService { - private SharedBlockAdmin $sharedBlockAdmin; - private ManagerInterface $blockManager; - public function __construct(Environment $twig, ManagerInterface $blockManager, SharedBlockAdmin $sharedBlockAdmin) - { + /** + * @var AdminInterface + */ + private AdminInterface $sharedBlockAdmin; + + public function __construct( + Environment $twig, + ManagerInterface $blockManager, + AdminInterface $sharedBlockAdmin + ) { parent::__construct($twig); $this->blockManager = $blockManager; $this->sharedBlockAdmin = $sharedBlockAdmin; } - public function execute(BlockContextInterface $blockContext, ?Response $response = null) + public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { $block = $blockContext->getBlock(); @@ -124,16 +128,9 @@ public function preUpdate(BlockInterface $block): void protected function getBlockBuilder(FormMapper $form): FormBuilderInterface { - // simulate an association ... - $fieldDescription = $this->sharedBlockAdmin->getModelManager()->getNewFieldDescriptionInstance($this->sharedBlockAdmin->getClass(), 'block', [ + $fieldDescription = $this->sharedBlockAdmin->createFieldDescription('block', [ 'translation_domain' => 'SonataPageBundle', - ]); - $fieldDescription->setAssociationAdmin($this->sharedBlockAdmin); - $fieldDescription->setAdmin($form->getAdmin()); - $fieldDescription->setOption('edit', 'list'); - $fieldDescription->setAssociationMapping([ - 'fieldName' => 'block', - 'type' => ClassMetadataInfo::MANY_TO_ONE, + 'edit' => 'list', ]); return $form->create('blockId', ModelListType::class, [ diff --git a/src/Entity/BaseBlock.php b/src/Entity/BaseBlock.php index bb1ad7006..089838606 100644 --- a/src/Entity/BaseBlock.php +++ b/src/Entity/BaseBlock.php @@ -14,9 +14,7 @@ namespace Sonata\PageBundle\Entity; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Collection; use Sonata\PageBundle\Model\Block; -use Sonata\PageBundle\Model\PageBlockInterface; /** * The class stores block information. @@ -30,11 +28,6 @@ abstract class BaseBlock extends Block */ protected $id; - /** - * @var Collection - */ - protected $children; - public function __construct() { $this->children = new ArrayCollection(); diff --git a/src/Mapper/PageFormMapper.php b/src/Mapper/PageFormMapper.php index edb674baf..2128277d4 100644 --- a/src/Mapper/PageFormMapper.php +++ b/src/Mapper/PageFormMapper.php @@ -55,26 +55,12 @@ public function remove(string $key): FormMapper return $this; } - public function setHelps(array $helps = []): FormMapper - { - $this->adminFormMapper->setHelps($helps); - - return $this; - } - - public function addHelp(string $name, string $help): FormMapper - { - $this->adminFormMapper->addHelp($name, $help); - - return $this; - } - public function has(string $key): bool { return $this->adminFormMapper->has($key); } - public function get(string $name) + public function get(string $name): FormBuilderInterface { return $this->adminFormMapper->get($name); } diff --git a/src/Page/Service/DefaultPageService.php b/src/Page/Service/DefaultPageService.php index 15cc3761a..e6307da8a 100644 --- a/src/Page/Service/DefaultPageService.php +++ b/src/Page/Service/DefaultPageService.php @@ -41,11 +41,12 @@ final class DefaultPageService extends BasePageService /** * @param string $name Page service name * @param TemplateManagerInterface $templateManager Template manager - * @param SeoPageInterface $seoPage SEO page object + * @param SeoPageInterface|null $seoPage SEO page object */ public function __construct($name, TemplateManagerInterface $templateManager, ?SeoPageInterface $seoPage = null) { - $this->name = $name; + parent::__construct($name); + $this->templateManager = $templateManager; $this->seoPage = $seoPage; } @@ -54,9 +55,7 @@ public function execute(PageInterface $page, Request $request, array $parameters { $this->updateSeoPage($page); - $response = $this->templateManager->renderResponse($page->getTemplateCode(), $parameters, $response); - - return $response; + return $this->templateManager->renderResponse($page->getTemplateCode(), $parameters, $response); } /** diff --git a/src/Resources/config/block.xml b/src/Resources/config/block.xml index 498f52c28..9b89690fb 100644 --- a/src/Resources/config/block.xml +++ b/src/Resources/config/block.xml @@ -11,13 +11,14 @@ - + + @@ -25,16 +26,12 @@ - - + - page - sonata.page.block.breadcrumb - - + diff --git a/tests/App/Entity/SonataPageBlock.php b/tests/App/Entity/SonataPageBlock.php index 6d8d61ade..cd736ccdb 100644 --- a/tests/App/Entity/SonataPageBlock.php +++ b/tests/App/Entity/SonataPageBlock.php @@ -15,8 +15,8 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Sonata\BlockBundle\Model\BlockInterface; use Sonata\PageBundle\Entity\BaseBlock; -use Sonata\PageBundle\Model\PageBlockInterface; /** * @ORM\Entity @@ -41,7 +41,7 @@ class SonataPageBlock extends BaseBlock * ) * @ORM\OrderBy({"position"="ASC"}) * - * @var Collection + * @var Collection */ protected $children; diff --git a/tests/App/config/config.yaml b/tests/App/config/config.yaml index f5c111e7b..abebde3f7 100644 --- a/tests/App/config/config.yaml +++ b/tests/App/config/config.yaml @@ -16,8 +16,6 @@ framework: enabled: true csrf_protection: enabled: true - templating: - engines: [twig] twig: exception_controller: null diff --git a/tests/App/config/sonata.yaml b/tests/App/config/sonata.yaml index ae7cb4096..d2f6012f3 100644 --- a/tests/App/config/sonata.yaml +++ b/tests/App/config/sonata.yaml @@ -1,4 +1,5 @@ sonata_block: + http_cache: false blocks: sonata.admin.block.admin_list: contexts: [admin] diff --git a/tests/Block/BlockContextManagerTest.php b/tests/Block/BlockContextManagerTest.php index 24c4be9fa..b3079d10d 100644 --- a/tests/Block/BlockContextManagerTest.php +++ b/tests/Block/BlockContextManagerTest.php @@ -14,12 +14,9 @@ namespace Sonata\PageBundle\Tests\Block; use PHPUnit\Framework\TestCase; +use Sonata\BlockBundle\Block\BlockContext; use Sonata\BlockBundle\Block\BlockContextInterface; -use Sonata\BlockBundle\Block\BlockLoaderInterface; -use Sonata\BlockBundle\Block\BlockServiceManagerInterface; -use Sonata\BlockBundle\Block\Service\AbstractBlockService; -use Sonata\BlockBundle\Model\BlockInterface; -use Sonata\PageBundle\Block\BlockContextManager; +use Sonata\BlockBundle\Model\Block; /** * @author Sullivan Senechal @@ -28,30 +25,21 @@ final class BlockContextManagerTest extends TestCase { public function testGetWithValidData(): void { - $service = $this->createMock(AbstractBlockService::class); - - $blockLoader = $this->createMock(BlockLoaderInterface::class); - - $serviceManager = $this->createMock(BlockServiceManagerInterface::class); - $serviceManager->expects(static::once())->method('get')->willReturn($service); - - $block = $this->createMock(BlockInterface::class); - $block->expects(static::once())->method('getSettings')->willReturn([]); - - $manager = new BlockContextManager($blockLoader, $serviceManager); - - $blockContext = $manager->get($block); - - static::assertInstanceOf(BlockContextInterface::class, $blockContext); - - static::assertSame([ + $settings = [ 'use_cache' => true, 'extra_cache_keys' => [], 'attr' => [], - 'template' => false, + 'template' => 'test_template', 'ttl' => 0, 'manager' => false, 'page_id' => false, - ], $blockContext->getSettings()); + ]; + $block = new Block(); + $block->setSettings($settings); + $blockContext = new BlockContext($block, $block->getSettings()); + + static::assertInstanceOf(BlockContextInterface::class, $blockContext); + static::assertSame($settings, $blockContext->getSettings()); + static::assertSame('test_template', $blockContext->getTemplate()); } } diff --git a/tests/Block/ContainerBlockServiceTest.php b/tests/Block/ContainerBlockServiceTest.php index fcb82ef61..2cb0f44b9 100644 --- a/tests/Block/ContainerBlockServiceTest.php +++ b/tests/Block/ContainerBlockServiceTest.php @@ -13,8 +13,9 @@ namespace Sonata\PageBundle\Tests\Block; -use Sonata\AdminBundle\Form\FormMapper; use Sonata\BlockBundle\Block\BlockContext; +use Sonata\BlockBundle\Block\Service\ContainerBlockService as BaseContainerBlockService; +use Sonata\BlockBundle\Form\Mapper\FormMapper; use Sonata\BlockBundle\Model\Block; use Sonata\BlockBundle\Test\BlockServiceTestCase; use Sonata\PageBundle\Block\ContainerBlockService; @@ -30,13 +31,6 @@ final class ContainerBlockServiceTest extends BlockServiceTestCase */ public function testExecute(): void { - $this->twig->expects(static::once()) - ->method('render') - ->with('@SonataPage/Block/block_container.html.twig') - ->willReturn('

{{ settings.title }} test

'); - - $service = new ContainerBlockService($this->twig); - $block = new Block(); $block->setName('block.name'); $block->setType('core.container'); @@ -44,6 +38,13 @@ public function testExecute(): void 'code' => 'block.code', ]); + $this->twig->expects(static::once()) + ->method('render') + ->with('@SonataPage/Block/block_container.html.twig') + ->willReturn('

{{ settings.title }} test

'); + + $baseContainerBlockService = new BaseContainerBlockService($this->twig); + $service = new ContainerBlockService($baseContainerBlockService); $blockContext = new BlockContext($block, [ 'code' => '', 'layout' => '{{ CONTENT }}', @@ -52,6 +53,7 @@ public function testExecute(): void ]); $response = $service->execute($blockContext); + static::assertInstanceOf(Response::class, $response); static::assertSame('

{{ settings.title }} test

', $response->getContent()); static::assertSame(200, $response->getStatusCode()); @@ -62,8 +64,6 @@ public function testExecute(): void */ public function testFormBuilder(): void { - $service = new ContainerBlockService($this->twig); - $block = new Block(); $block->setName('block.name'); $block->setType('core.container'); @@ -71,10 +71,12 @@ public function testFormBuilder(): void 'name' => 'block.code', ]); + $baseContainerBlockService = new BaseContainerBlockService($this->twig); + $service = new ContainerBlockService($baseContainerBlockService); + $form = $this->createMock(FormMapper::class); - $form->expects(static::exactly(6))->method('add'); + $form->expects(static::exactly(3))->method('add'); - $service->buildCreateForm($form, $block); - $service->buildEditForm($form, $block); + $service->configureCreateForm($form, $block); } } diff --git a/tests/Block/PageListBlockServiceTest.php b/tests/Block/PageListBlockServiceTest.php index 626e1a2c5..756b7a326 100644 --- a/tests/Block/PageListBlockServiceTest.php +++ b/tests/Block/PageListBlockServiceTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Sonata\BlockBundle\Block\BlockContext; +use Sonata\BlockBundle\Form\Mapper\FormMapper; use Sonata\BlockBundle\Model\Block; use Sonata\BlockBundle\Test\BlockServiceTestCase; use Sonata\PageBundle\Block\PageListBlockService; @@ -83,4 +84,15 @@ public function testExecute(): void static::assertSame('

{{ settings.title }} test

', $response->getContent()); static::assertSame(200, $response->getStatusCode()); } + + public function testFormBuilder(): void + { + $block = new Block(); + + $form = $this->createMock(FormMapper::class); + $form->expects(static::once())->method('add'); + + $blockService = new PageListBlockService($this->twig, $this->pageManager); + $blockService->configureEditForm($form, $block); + } } diff --git a/tests/CmsManager/CmsPageManagerTest.php b/tests/CmsManager/CmsPageManagerTest.php index 721636165..99ad5450a 100644 --- a/tests/CmsManager/CmsPageManagerTest.php +++ b/tests/CmsManager/CmsPageManagerTest.php @@ -27,12 +27,16 @@ final class CmsBlock extends AbstractBlock { + private $id; + public function setId($id): void { + $this->id = $id; } - public function getId(): void + public function getId() { + return $this->id; } } diff --git a/tests/CmsManager/CmsSnapshotManagerTest.php b/tests/CmsManager/CmsSnapshotManagerTest.php index bbf3b5639..e3217e85e 100644 --- a/tests/CmsManager/CmsSnapshotManagerTest.php +++ b/tests/CmsManager/CmsSnapshotManagerTest.php @@ -28,12 +28,16 @@ final class SnapshotBlock extends Block { + private $id; + public function setId($id): void { + $this->id = $id; } - public function getId(): void + public function getId() { + return $this->id; } } diff --git a/tests/Page/Service/DefaultPageServiceTest.php b/tests/Page/Service/DefaultPageServiceTest.php index 244b954c7..c1d09ab26 100644 --- a/tests/Page/Service/DefaultPageServiceTest.php +++ b/tests/Page/Service/DefaultPageServiceTest.php @@ -70,13 +70,14 @@ public function testExecute(): void $this->seoPage->expects(static::once()) ->method('setTitle')->with(static::equalTo('page title')); - $metaMapping = [ - ['name', 'description', 'page meta description', true], - ['name', 'keywords', 'page meta keywords', true], - ['property', 'og:type', 'article', true], - ]; - - $this->seoPage->expects(static::exactly(3))->method('addMeta')->willReturnMap($metaMapping); + $this->seoPage->expects(static::exactly(3)) + ->method('addMeta') + ->withConsecutive( + ['name', 'description', 'page meta description'], + ['name', 'keywords', 'page meta keywords'], + ['property', 'og:type', 'article'] + ) + ->willReturnOnConsecutiveCalls($this->seoPage, $this->seoPage, $this->seoPage); $this->seoPage->expects(static::once()) ->method('addHtmlAttributes')->with(static::equalTo('prefix'), static::equalTo('og: http://ogp.me/ns#'));