From f2eecc2201359a503ae582a45ae54fdc9fcc72c8 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 7 Mar 2022 09:03:12 +0100 Subject: [PATCH] Bump phpstan to level 8 (#1027) --- phpstan.neon.dist | 2 +- src/Block/BlockContext.php | 2 +- src/Block/BlockContextManager.php | 22 ++++---- src/Block/BlockRenderer.php | 11 ++-- src/Block/BlockServiceManager.php | 21 ++++---- src/Block/Service/AbstractBlockService.php | 9 +++- src/Block/Service/ContainerBlockService.php | 5 +- src/Block/Service/MenuBlockService.php | 7 ++- src/Block/Service/RssBlockService.php | 20 ++++--- src/Block/Service/TemplateBlockService.php | 5 +- src/Block/Service/TextBlockService.php | 5 +- src/Command/DebugBlocksCommand.php | 5 +- .../Compiler/TweakCompilerPass.php | 19 ++++--- .../SonataBlockExtension.php | 3 +- src/Exception/Strategy/StrategyManager.php | 52 +++++++------------ src/Model/BaseBlock.php | 2 +- src/Model/Block.php | 2 +- src/Model/BlockInterface.php | 6 +-- src/Templating/Helper/BlockHelper.php | 51 +++++++++++------- tests/Block/BlockContextManagerTest.php | 4 +- tests/Block/BlockServiceManagerTest.php | 2 +- tests/Resources/XliffValidatorTestCase.php | 1 + tests/Templating/Helper/BlockHelperTest.php | 8 +-- tests/Twig/Extension/BlockExtensionTest.php | 5 +- 24 files changed, 157 insertions(+), 112 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index fa5457d3..ba4a021e 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,7 +2,7 @@ includes: - phpstan-baseline.neon parameters: - level: 6 + level: 8 paths: - src - tests diff --git a/src/Block/BlockContext.php b/src/Block/BlockContext.php index 1f4172b6..2964ab4a 100644 --- a/src/Block/BlockContext.php +++ b/src/Block/BlockContext.php @@ -69,7 +69,7 @@ public function getSettings(): array public function getSetting(string $name) { if (!\array_key_exists($name, $this->settings)) { - throw new \RuntimeException(sprintf('Unable to find the option `%s` (%s) - define the option in the related BlockServiceInterface', $name, $this->block->getType())); + throw new \RuntimeException(sprintf('Unable to find the option `%s` (%s) - define the option in the related BlockServiceInterface', $name, $this->block->getType() ?? '')); } return $this->settings[$name]; diff --git a/src/Block/BlockContextManager.php b/src/Block/BlockContextManager.php index 346c86be..5405336d 100644 --- a/src/Block/BlockContextManager.php +++ b/src/Block/BlockContextManager.php @@ -36,16 +36,16 @@ final class BlockContextManager implements BlockContextManagerInterface /** * @var array> */ - private $settingsByType; + private $settingsByType = []; /** * @var array> * @phpstan-var array> */ - private $settingsByClass; + private $settingsByClass = []; /** - * @var array{by_class?: array, by_type?: array} + * @var array{by_class: array, by_type: array} */ private $cacheBlocks; @@ -55,12 +55,12 @@ final class BlockContextManager implements BlockContextManagerInterface private $logger; /** - * @param array{by_class?: array, by_type?: array} $cacheBlocks + * @param array{by_class: array, by_type: array} $cacheBlocks */ public function __construct( BlockLoaderInterface $blockLoader, BlockServiceManagerInterface $blockService, - array $cacheBlocks = [], + array $cacheBlocks = ['by_class' => [], 'by_type' => []], ?LoggerInterface $logger = null ) { $this->blockLoader = $blockLoader; @@ -114,7 +114,7 @@ public function get($meta, array $settings = []): BlockContextInterface } catch (ExceptionInterface $e) { $this->logger->error(sprintf( '[cms::blockContext] block.id=%s - error while resolving options - %s', - $block->getId(), + $block->getId() ?? '', $e->getMessage() )); @@ -163,7 +163,7 @@ static function (Options $options, $value): string { // add type and class settings for block $class = ClassUtils::getClass($block); - $settingsByType = $this->settingsByType[$block->getType()] ?? []; + $settingsByType = $this->settingsByType[$block->getType() ?? ''] ?? []; $settingsByClass = $this->settingsByClass[$class] ?? []; $optionsResolver->setDefaults(array_merge($settingsByType, $settingsByClass)); } @@ -184,14 +184,14 @@ private function setDefaultExtraCacheKeys(BlockContextInterface $blockContext, a // type by block class $class = ClassUtils::getClass($block); - $cacheServiceId = $this->cacheBlocks['by_class'][$class] ?? false; + $cacheServiceId = $this->cacheBlocks['by_class'][$class] ?? null; // type by block service - if (!$cacheServiceId) { - $cacheServiceId = $this->cacheBlocks['by_type'][$block->getType()] ?? false; + if (null === $cacheServiceId) { + $cacheServiceId = $this->cacheBlocks['by_type'][$block->getType() ?? ''] ?? null; } - if (!$cacheServiceId) { + if (null === $cacheServiceId) { // no context cache needed return; } diff --git a/src/Block/BlockRenderer.php b/src/Block/BlockRenderer.php index bd431385..f42d2fe0 100644 --- a/src/Block/BlockRenderer.php +++ b/src/Block/BlockRenderer.php @@ -69,7 +69,9 @@ public function render(BlockContextInterface $blockContext, ?Response $response $block = $blockContext->getBlock(); if (null !== $this->logger) { - $this->logger->info(sprintf('[cms::renderBlock] block.id=%d, block.type=%s ', $block->getId(), $block->getType())); + $this->logger->info( + sprintf('[cms::renderBlock] block.id=%d, block.type=%s', $block->getId() ?? '', $block->getType() ?? '') + ); } try { @@ -83,7 +85,7 @@ public function render(BlockContextInterface $blockContext, ?Response $response if (null !== $this->logger) { $this->logger->error(sprintf( '[cms::renderBlock] block.id=%d - error while rendering block - %s', - $block->getId(), + $block->getId() ?? '', $exception->getMessage() ), compact('exception')); } @@ -118,8 +120,9 @@ private function addMetaInformation(Response $response, BlockContextInterface $b { // a response exists, use it if (null !== $this->lastResponse && $this->lastResponse->isCacheable()) { - if (null !== $this->lastResponse->getTtl()) { - $response->setTtl($this->lastResponse->getTtl()); + $lastResponseTtl = $this->lastResponse->getTtl(); + if (null !== $lastResponseTtl) { + $response->setTtl($lastResponseTtl); } $response->setPublic(); } elseif (null !== $this->lastResponse) { // not cacheable diff --git a/src/Block/BlockServiceManager.php b/src/Block/BlockServiceManager.php index a6556c0f..e2e8e511 100644 --- a/src/Block/BlockServiceManager.php +++ b/src/Block/BlockServiceManager.php @@ -34,7 +34,7 @@ final class BlockServiceManager implements BlockServiceManagerInterface /** * @var bool */ - private $inValidate; + private $inValidate = false; /** * @var array @@ -53,13 +53,14 @@ public function __construct(ContainerInterface $container) public function get(BlockInterface $block): BlockServiceInterface { - if (null === $block->getType()) { + $blockType = $block->getType(); + if (null === $blockType) { throw new \RuntimeException('The block service `` does not exist'); } - $this->load($block->getType()); + $this->load($blockType); - $service = $this->services[$block->getType()]; + $service = $this->services[$blockType]; \assert($service instanceof BlockServiceInterface); return $service; @@ -121,6 +122,7 @@ public function getServicesByContext(string $context, bool $includeContainers = $services = []; + /** @var string[] $containers */ $containers = $this->container->getParameter('sonata.block.container.types'); foreach ($this->contexts[$context] as $name) { @@ -147,7 +149,7 @@ public function validate(ErrorElement $errorElement, BlockInterface $block): voi return; } - // As block can be nested, we only need to validate the main block, no the children + // As block can be nested, we only need to validate the main block, not the children try { $this->inValidate = true; @@ -173,11 +175,12 @@ private function load(string $type): BlockServiceInterface } if (!$this->services[$type] instanceof BlockServiceInterface) { - $this->services[$type] = $this->container->get($type); - } + $blockService = $this->container->get($type); + if (!$blockService instanceof BlockServiceInterface) { + throw new \RuntimeException(sprintf('The service %s does not implement BlockServiceInterface', $type)); + } - if (!$this->services[$type] instanceof BlockServiceInterface) { - throw new \RuntimeException(sprintf('The service %s does not implement BlockServiceInterface', $type)); + $this->services[$type] = $blockService; } return $this->services[$type]; diff --git a/src/Block/Service/AbstractBlockService.php b/src/Block/Service/AbstractBlockService.php index 8e573cd1..6fe4fc9a 100644 --- a/src/Block/Service/AbstractBlockService.php +++ b/src/Block/Service/AbstractBlockService.php @@ -70,9 +70,11 @@ public function configureSettings(OptionsResolver $resolver): void public function getCacheKeys(BlockInterface $block): array { + $updatedAt = $block->getUpdatedAt(); + return [ 'block_id' => $block->getId(), - 'updated_at' => null !== $block->getUpdatedAt() ? $block->getUpdatedAt()->format('U') : null, + 'updated_at' => null !== $updatedAt ? $updatedAt->format('U') : null, ]; } @@ -82,7 +84,10 @@ public function load(BlockInterface $block): void public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { - return $this->renderResponse($blockContext->getTemplate(), [ + $template = $blockContext->getTemplate(); + \assert(null !== $template); + + return $this->renderResponse($template, [ 'block_context' => $blockContext, 'block' => $blockContext->getBlock(), ], $response); diff --git a/src/Block/Service/ContainerBlockService.php b/src/Block/Service/ContainerBlockService.php index 9e43b173..9e76b72b 100644 --- a/src/Block/Service/ContainerBlockService.php +++ b/src/Block/Service/ContainerBlockService.php @@ -68,7 +68,10 @@ public function configureEditForm(FormMapper $form, BlockInterface $block): void public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { - return $this->renderResponse($blockContext->getTemplate(), [ + $template = $blockContext->getTemplate(); + \assert(null !== $template); + + return $this->renderResponse($template, [ 'block' => $blockContext->getBlock(), 'decorator' => $this->getDecorator($blockContext->getSetting('layout')), 'settings' => $blockContext->getSettings(), diff --git a/src/Block/Service/MenuBlockService.php b/src/Block/Service/MenuBlockService.php index ca93a8de..505a65d4 100644 --- a/src/Block/Service/MenuBlockService.php +++ b/src/Block/Service/MenuBlockService.php @@ -59,6 +59,9 @@ public function __construct( public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { + $template = $blockContext->getTemplate(); + \assert(null !== $template); + $responseSettings = [ 'menu' => $this->getMenu($blockContext), 'menu_options' => $this->getMenuOptions($blockContext->getSettings()), @@ -67,10 +70,10 @@ public function execute(BlockContextInterface $blockContext, ?Response $response ]; if ('private' === $blockContext->getSetting('cache_policy')) { - return $this->renderPrivateResponse($blockContext->getTemplate(), $responseSettings, $response); + return $this->renderPrivateResponse($template, $responseSettings, $response); } - return $this->renderResponse($blockContext->getTemplate(), $responseSettings, $response); + return $this->renderResponse($template, $responseSettings, $response); } public function configureCreateForm(FormMapper $form, BlockInterface $block): void diff --git a/src/Block/Service/RssBlockService.php b/src/Block/Service/RssBlockService.php index 9df1225f..74089f46 100644 --- a/src/Block/Service/RssBlockService.php +++ b/src/Block/Service/RssBlockService.php @@ -24,6 +24,9 @@ use Symfony\Component\Form\Extension\Core\Type\UrlType; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; +use Symfony\Component\Validator\Constraints\NotNull; /** * @author Thomas Rabaix @@ -80,13 +83,13 @@ public function validate(ErrorElement $errorElement, BlockInterface $block): voi { $errorElement ->with('settings[url]') - ->assertNotNull([]) - ->assertNotBlank() + ->addConstraint(new NotNull()) + ->addConstraint(new NotBlank()) ->end() ->with('settings[title]') - ->assertNotNull([]) - ->assertNotBlank() - ->assertLength(['max' => 50]) + ->addConstraint(new NotNull()) + ->addConstraint(new NotBlank()) + ->addConstraint(new Length(['max' => 50])) ->end(); } @@ -107,7 +110,7 @@ public function execute(BlockContextInterface $blockContext, ?Response $response // retrieve contents with a specific stream context to avoid php errors $content = @file_get_contents($settings['url'], false, stream_context_create($options)); - if ($content) { + if (false !== $content && '' !== $content) { // generate a simple xml element try { $feeds = new \SimpleXMLElement($content); @@ -118,7 +121,10 @@ public function execute(BlockContextInterface $blockContext, ?Response $response } } - return $this->renderResponse($blockContext->getTemplate(), [ + $template = $blockContext->getTemplate(); + \assert(null !== $template); + + return $this->renderResponse($template, [ 'feeds' => $feeds, 'block' => $blockContext->getBlock(), 'settings' => $settings, diff --git a/src/Block/Service/TemplateBlockService.php b/src/Block/Service/TemplateBlockService.php index 9a9e9b99..a7f021f5 100644 --- a/src/Block/Service/TemplateBlockService.php +++ b/src/Block/Service/TemplateBlockService.php @@ -30,7 +30,10 @@ final class TemplateBlockService extends AbstractBlockService implements Editabl { public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { - return $this->renderResponse($blockContext->getTemplate(), [ + $template = $blockContext->getTemplate(); + \assert(null !== $template); + + return $this->renderResponse($template, [ 'block' => $blockContext->getBlock(), 'settings' => $blockContext->getSettings(), ], $response); diff --git a/src/Block/Service/TextBlockService.php b/src/Block/Service/TextBlockService.php index 775f45f0..f082c8ab 100644 --- a/src/Block/Service/TextBlockService.php +++ b/src/Block/Service/TextBlockService.php @@ -31,7 +31,10 @@ final class TextBlockService extends AbstractBlockService implements EditableBlo { public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response { - return $this->renderResponse($blockContext->getTemplate(), [ + $template = $blockContext->getTemplate(); + \assert(null !== $template); + + return $this->renderResponse($template, [ 'block' => $blockContext->getBlock(), 'settings' => $blockContext->getSettings(), ], $response); diff --git a/src/Command/DebugBlocksCommand.php b/src/Command/DebugBlocksCommand.php index 10f8333c..dc7621f8 100644 --- a/src/Command/DebugBlocksCommand.php +++ b/src/Command/DebugBlocksCommand.php @@ -47,8 +47,9 @@ public function configure(): void public function execute(InputInterface $input, OutputInterface $output): int { - if (null !== $input->getOption('context')) { - $services = $this->blockManager->getServicesByContext((string) $input->getOption('context')); + $context = $input->getOption('context'); + if (\is_string($context)) { + $services = $this->blockManager->getServicesByContext($context); } else { $services = $this->blockManager->getServices(); } diff --git a/src/DependencyInjection/Compiler/TweakCompilerPass.php b/src/DependencyInjection/Compiler/TweakCompilerPass.php index 5c63c9ad..99882861 100644 --- a/src/DependencyInjection/Compiler/TweakCompilerPass.php +++ b/src/DependencyInjection/Compiler/TweakCompilerPass.php @@ -35,16 +35,16 @@ public function process(ContainerBuilder $container): void $blockTypes = $container->getParameter('sonata_blocks.block_types'); /** @var array $cacheBlocks */ $cacheBlocks = $container->getParameter('sonata_block.cache_blocks'); - /** @var string[] $defaultContexs */ - $defaultContexs = $container->getParameter('sonata_blocks.default_contexts'); + /** @var string[] $defaultContexts */ + $defaultContexts = $container->getParameter('sonata_blocks.default_contexts'); foreach ($container->findTaggedServiceIds('sonata.block') as $id => $tags) { $container->getDefinition($id) ->setPublic(true); - $settings = $this->createBlockSettings($tags, $defaultContexs); + $settings = $this->createBlockSettings($tags, $defaultContexts); - // Register blocks dynamicaly + // Register blocks dynamically if (!\array_key_exists($id, $blocks)) { $blocks[$id] = $settings; } @@ -83,18 +83,25 @@ public function process(ContainerBuilder $container): void } /** + * NEXT_MAJOR: Change visibility to private. + * * Apply configurations to the context manager. */ public function applyContext(ContainerBuilder $container): void { $definition = $container->findDefinition('sonata.block.context_manager'); - foreach ($container->getParameter('sonata_block.blocks') as $service => $settings) { + /** @var array> $blocks */ + $blocks = $container->getParameter('sonata_block.blocks'); + foreach ($blocks as $service => $settings) { if (\count($settings['settings']) > 0) { $definition->addMethodCall('addSettingsByType', [$service, $settings['settings'], true]); } } - foreach ($container->getParameter('sonata_block.blocks_by_class') as $class => $settings) { + + /** @var array> $blocksByClass */ + $blocksByClass = $container->getParameter('sonata_block.blocks_by_class'); + foreach ($blocksByClass as $class => $settings) { if (\count($settings['settings']) > 0) { $definition->addMethodCall('addSettingsByClass', [$class, $settings['settings'], true]); } diff --git a/src/DependencyInjection/SonataBlockExtension.php b/src/DependencyInjection/SonataBlockExtension.php index 5940c370..48f19635 100644 --- a/src/DependencyInjection/SonataBlockExtension.php +++ b/src/DependencyInjection/SonataBlockExtension.php @@ -57,6 +57,7 @@ public function load(array $configs, ContainerBuilder $container): void $processor = new Processor(); $configuration = $this->getConfiguration($configs, $container); + \assert(null !== $configuration); $config = $processor->processConfiguration($configuration, $configs); $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); @@ -131,7 +132,7 @@ public function configureCache(ContainerBuilder $container, array $config): void ->addTag('kernel.event_listener', ['event' => 'kernel.response', 'method' => 'onKernelResponse']); } - $cacheBlocks = []; + $cacheBlocks = ['by_class' => [], 'by_type' => []]; foreach ($config['blocks'] as $service => $settings) { $cacheBlocks['by_type'][$service] = $settings['cache']; } diff --git a/src/Exception/Strategy/StrategyManager.php b/src/Exception/Strategy/StrategyManager.php index 166d297c..35002cef 100644 --- a/src/Exception/Strategy/StrategyManager.php +++ b/src/Exception/Strategy/StrategyManager.php @@ -53,12 +53,12 @@ final class StrategyManager implements StrategyManagerInterface private $blockRenderers; /** - * @var string + * @var string|null */ private $defaultFilter; /** - * @var string + * @var string|null */ private $defaultRenderer; @@ -143,8 +143,21 @@ public function getBlockRenderer(BlockInterface $block): RendererInterface { $type = $block->getType(); $name = $this->blockRenderers[$type] ?? $this->defaultRenderer; + if (null === $name) { + throw new \RuntimeException('No default renderer was set.'); + } + + if (!isset($this->renderers[$name])) { + throw new \RuntimeException('The renderer "%s" does not exist.'); + } - return $this->getRendererService($name); + $service = $this->container->get($this->renderers[$name]); + + if (!$service instanceof RendererInterface) { + throw new \InvalidArgumentException(sprintf('The service "%s" is not an exception renderer.', $name)); + } + + return $service; } /** @@ -156,17 +169,10 @@ public function getBlockFilter(BlockInterface $block): FilterInterface { $type = $block->getType(); $name = $this->blockFilters[$type] ?? $this->defaultFilter; + if (null === $name) { + throw new \RuntimeException('No default filter was set.'); + } - return $this->getFilterService($name); - } - - /** - * Returns the filter service for given filter name. - * - * @throws \RuntimeException|\InvalidArgumentException - */ - private function getFilterService(string $name): FilterInterface - { if (!isset($this->filters[$name])) { throw new \RuntimeException('The filter "%s" does not exist.'); } @@ -179,24 +185,4 @@ private function getFilterService(string $name): FilterInterface return $service; } - - /** - * Returns the renderer service for given renderer name. - * - * @throws \RuntimeException|\InvalidArgumentException - */ - private function getRendererService(string $name): RendererInterface - { - if (!isset($this->renderers[$name])) { - throw new \RuntimeException('The renderer "%s" does not exist.'); - } - - $service = $this->container->get($this->renderers[$name]); - - if (!$service instanceof RendererInterface) { - throw new \InvalidArgumentException(sprintf('The service "%s" is not an exception renderer.', $name)); - } - - return $service; - } } diff --git a/src/Model/BaseBlock.php b/src/Model/BaseBlock.php index e55b9e8b..39e2632d 100644 --- a/src/Model/BaseBlock.php +++ b/src/Model/BaseBlock.php @@ -83,7 +83,7 @@ public function __construct() #[\ReturnTypeWillChange] public function __toString() { - return sprintf('%s ~ #%s', $this->getName(), $this->getId()); + return sprintf('%s ~ #%s', $this->getName() ?? '', $this->getId() ?? ''); } public function setName(string $name): void diff --git a/src/Model/Block.php b/src/Model/Block.php index f3f9b180..18cb02e3 100644 --- a/src/Model/Block.php +++ b/src/Model/Block.php @@ -19,7 +19,7 @@ class Block extends BaseBlock { /** - * @var mixed + * @var string|int|null */ protected $id; diff --git a/src/Model/BlockInterface.php b/src/Model/BlockInterface.php index f337fb7b..d76cb637 100644 --- a/src/Model/BlockInterface.php +++ b/src/Model/BlockInterface.php @@ -19,16 +19,16 @@ interface BlockInterface { /** - * Sets the block Id. + * Sets the block id. * - * @param mixed $id + * @param string|int $id */ public function setId($id): void; /** * Returns the block id. * - * @return mixed void + * @return string|int|null */ public function getId(); diff --git a/src/Templating/Helper/BlockHelper.php b/src/Templating/Helper/BlockHelper.php index bb7b12b6..f65586f5 100644 --- a/src/Templating/Helper/BlockHelper.php +++ b/src/Templating/Helper/BlockHelper.php @@ -32,7 +32,7 @@ * @phpstan-type Trace = array{ * name: string, * type: string, - * duration: int|false, + * duration: int|float|false, * memory_start: int|false, * memory_end: int|false, * memory_peak: int|false, @@ -65,7 +65,7 @@ class BlockHelper private $cacheManager; /** - * @var array{by_class?: array, by_type?: array} + * @var array{by_class: array, by_type: array} */ private $cacheBlocks; @@ -98,8 +98,8 @@ class BlockHelper private $assets = ['css' => [], 'js' => []]; /** - * @var array> - * @phpstan-var array + * @var array> + * @phpstan-var array */ private $traces = []; @@ -114,7 +114,7 @@ class BlockHelper private $stopwatch; /** - * @param array{by_class?: array, by_type?: array} $cacheBlocks + * @param array{by_class: array, by_type: array} $cacheBlocks */ public function __construct( BlockServiceManagerInterface $blockServiceManager, @@ -284,7 +284,8 @@ public function render($block, array $options = []): string if (null !== $this->stopwatch) { // avoid \DateTime because of serialize/unserialize issue in PHP7.3 (https://bugs.php.net/bug.php?id=77302) - $stats['cache']['created_at'] = null === $response->getDate() ? null : $response->getDate()->getTimestamp(); + $responseDate = $response->getDate(); + $stats['cache']['created_at'] = null === $responseDate ? null : $responseDate->getTimestamp(); $stats['cache']['ttl'] = $response->getTtl() ?? 0; $stats['cache']['age'] = $response->getAge(); $stats['cache']['lifetime'] = $stats['cache']['age'] + $stats['cache']['ttl']; @@ -319,24 +320,31 @@ public function getTraces(): array */ private function stopTracing(BlockInterface $block, array $stats): void { - $e = $this->traces[$block->getId()]->stop(); + $event = $this->traces[$block->getId() ?? '']; + if (!$event instanceof StopwatchEvent) { + throw new \InvalidArgumentException( + sprintf('The block %s has no stopwatch event to stop.', $block->getId() ?? '') + ); + } + + $event->stop(); - $this->traces[$block->getId()] = array_merge($stats, [ - 'duration' => $e->getDuration(), + $this->traces[$block->getId() ?? ''] = [ + 'duration' => $event->getDuration(), 'memory_end' => memory_get_usage(true), 'memory_peak' => memory_get_peak_usage(true), - ]); + ] + $stats; } /** - * @return array + * @return array */ private function getEventBlocks(BlockEvent $event): array { $results = []; foreach ($event->getBlocks() as $block) { - $results[] = [$block->getId(), $block->getType()]; + $results[] = [$block->getId() ?? '', $block->getType() ?? '']; } return $results; @@ -356,9 +364,9 @@ private function getEventListeners(string $eventName): array foreach ($this->eventDispatcher->getListeners($eventName) as $listener) { if ($listener instanceof \Closure) { $results[] = '{closure}()'; - } elseif (\is_object($listener[0])) { + } elseif (\is_array($listener) && \is_object($listener[0])) { $results[] = \get_class($listener[0]); - } elseif (\is_string($listener[0])) { + } elseif (\is_array($listener) && \is_string($listener[0])) { $results[] = $listener[0]; } else { $results[] = 'Unknown type!'; @@ -385,7 +393,7 @@ private function getCacheService(BlockInterface $block, ?array &$stats = null): // type by block service if (null === $cacheServiceId) { - $cacheServiceId = $this->cacheBlocks['by_type'][$block->getType()] ?? null; + $cacheServiceId = $this->cacheBlocks['by_type'][$block->getType() ?? ''] ?? null; } if (null === $cacheServiceId) { @@ -407,14 +415,19 @@ private function getCacheService(BlockInterface $block, ?array &$stats = null): private function startTracing(BlockInterface $block): array { if (null !== $this->stopwatch) { - $this->traces[$block->getId()] = $this->stopwatch->start( - sprintf('%s (id: %s, type: %s)', $block->getName(), $block->getId(), $block->getType()) + $this->traces[$block->getId() ?? ''] = $this->stopwatch->start( + sprintf( + '%s (id: %s, type: %s)', + $block->getName() ?? '', + $block->getId() ?? '', + $block->getType() ?? '' + ) ); } return [ - 'name' => $block->getName(), - 'type' => $block->getType(), + 'name' => $block->getName() ?? '', + 'type' => $block->getType() ?? '', 'duration' => false, 'memory_start' => memory_get_usage(true), 'memory_end' => false, diff --git a/tests/Block/BlockContextManagerTest.php b/tests/Block/BlockContextManagerTest.php index a01a6dd7..936534a9 100644 --- a/tests/Block/BlockContextManagerTest.php +++ b/tests/Block/BlockContextManagerTest.php @@ -71,6 +71,7 @@ public function testGetWithSettings(): void $blocksCache = [ 'by_class' => [ClassUtils::getClass($block) => 'my_cache.service.id'], + 'by_type' => [], ]; $manager = new BlockContextManager($blockLoader, $serviceManager, $blocksCache); @@ -114,7 +115,8 @@ public function testWithInvalidSettings(): void ]); $block->expects(static::once())->method('getSetting')->with('template')->willReturn('custom.html.twig'); - $manager = new BlockContextManager($blockLoader, $serviceManager, [], $logger); + $cacheBlock = ['by_class' => [], 'by_type' => []]; + $manager = new BlockContextManager($blockLoader, $serviceManager, $cacheBlock, $logger); $blockContext = $manager->get($block); diff --git a/tests/Block/BlockServiceManagerTest.php b/tests/Block/BlockServiceManagerTest.php index c09cfe63..29a6e2b5 100644 --- a/tests/Block/BlockServiceManagerTest.php +++ b/tests/Block/BlockServiceManagerTest.php @@ -42,7 +42,7 @@ public function testInvalidServiceType(): void { $this->expectException(\RuntimeException::class); - $service = $this->createMock('stdClass'); + $service = $this->createMock(\stdClass::class); $container = $this->createMock(ContainerInterface::class); $container->expects(static::once())->method('get')->willReturn($service); diff --git a/tests/Resources/XliffValidatorTestCase.php b/tests/Resources/XliffValidatorTestCase.php index 26ba5c78..41514740 100644 --- a/tests/Resources/XliffValidatorTestCase.php +++ b/tests/Resources/XliffValidatorTestCase.php @@ -76,6 +76,7 @@ protected function validateXliff(string $file): void protected function validatePath(string $path): void { $files = glob(sprintf('%s/*.xliff', $path)); + static::assertNotFalse($files); foreach ($files as $file) { $this->validateXliff($file); diff --git a/tests/Templating/Helper/BlockHelperTest.php b/tests/Templating/Helper/BlockHelperTest.php index 556fbf1a..8d90ef38 100644 --- a/tests/Templating/Helper/BlockHelperTest.php +++ b/tests/Templating/Helper/BlockHelperTest.php @@ -34,11 +34,12 @@ public function testRenderEventWithNoListener(): void $blockRenderer = $this->createMock(BlockRendererInterface::class); $blockContextManager = $this->createMock(BlockContextManagerInterface::class); $eventDispatcher = $this->createMock(EventDispatcherInterface::class); - $eventDispatcher->expects(static::once())->method('dispatch')->willReturnCallback(static function ($event): BlockEvent { + $eventDispatcher->expects(static::once())->method('dispatch')->willReturnCallback(static function (BlockEvent $event): BlockEvent { return $event; }); - $helper = new BlockHelper($blockServiceManager, [], $blockRenderer, $blockContextManager, $eventDispatcher); + $cacheBlocks = ['by_class' => [], 'by_type' => []]; + $helper = new BlockHelper($blockServiceManager, $cacheBlocks, $blockRenderer, $blockContextManager, $eventDispatcher); static::assertSame('', $helper->renderEvent('my.event')); } @@ -77,7 +78,8 @@ static function (BlockInterface $block): BlockContext { return $event; }); - $helper = new BlockHelper($blockServiceManager, [], $blockRenderer, $blockContextManager, $eventDispatcher); + $cacheBlocks = ['by_class' => [], 'by_type' => []]; + $helper = new BlockHelper($blockServiceManager, $cacheBlocks, $blockRenderer, $blockContextManager, $eventDispatcher); static::assertSame('test', $helper->renderEvent('my.event')); } diff --git a/tests/Twig/Extension/BlockExtensionTest.php b/tests/Twig/Extension/BlockExtensionTest.php index beefd72a..c043ac2d 100644 --- a/tests/Twig/Extension/BlockExtensionTest.php +++ b/tests/Twig/Extension/BlockExtensionTest.php @@ -93,6 +93,9 @@ public function testFunction(string $name, array $args, string $expectedMethod): $func = $this->env->getFunction($name); static::assertInstanceOf(TwigFunction::class, $func); - \call_user_func_array([$this->env->getRuntime(BlockHelper::class), $expectedMethod], $args); + + $callable = [$this->env->getRuntime(BlockHelper::class), $expectedMethod]; + static::assertIsCallable($callable); + \call_user_func_array($callable, $args); } }