From 986a0a221e21401c86f8d785d386ce79585e92d5 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Thu, 18 Jun 2020 08:48:25 +0200 Subject: [PATCH] [FrameworkBundle] Allow to leverage autoconfiguration for DataCollectors with template --- .../Bundle/FrameworkBundle/CHANGELOG.md | 1 + .../DataCollector/AbstractDataCollector.php | 38 +++++++++++ .../TemplateAwareDataCollectorInterface.php | 22 ++++++ .../Compiler/ProfilerPass.php | 10 ++- .../Compiler/ProfilerPassTest.php | 67 +++++++++++++++++++ 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/DataCollector/AbstractDataCollector.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/DataCollector/TemplateAwareDataCollectorInterface.php diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index d1511a991218d..354fd8da36636 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -8,6 +8,7 @@ CHANGELOG * Added `framework.trusted_proxies` and `framework.trusted_headers` configuration options * Deprecated the public `form.factory`, `form.type.file`, `translator`, `security.csrf.token_manager`, `serializer`, `cache_clearer`, `filesystem` and `validator` services to private. + * Added `TemplateAwareDataCollectorInterface` and `AbstractDataCollector` to simplify custom data collector creation and leverage autoconfiguration 5.1.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/DataCollector/AbstractDataCollector.php b/src/Symfony/Bundle/FrameworkBundle/DataCollector/AbstractDataCollector.php new file mode 100644 index 0000000000000..428919b963bbf --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DataCollector/AbstractDataCollector.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DataCollector; + +/** + * @author Laurent VOULLEMIER + */ +abstract class AbstractDataCollector implements TemplateAwareDataCollectorInterface +{ + /** + * @var array + */ + protected $data = []; + + public function getName(): string + { + return static::class; + } + + public function reset(): void + { + $this->data = []; + } + + public static function getTemplate(): ?string + { + return null; + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DataCollector/TemplateAwareDataCollectorInterface.php b/src/Symfony/Bundle/FrameworkBundle/DataCollector/TemplateAwareDataCollectorInterface.php new file mode 100644 index 0000000000000..5ef17abc54983 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DataCollector/TemplateAwareDataCollectorInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DataCollector; + +use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; + +/** + * @author Laurent VOULLEMIER + */ +interface TemplateAwareDataCollectorInterface extends DataCollectorInterface +{ + public static function getTemplate(): ?string; +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php index d6e61cc605521..493b0b6561ea3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ProfilerPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Bundle\FrameworkBundle\DataCollector\TemplateAwareDataCollectorInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; @@ -37,11 +38,14 @@ public function process(ContainerBuilder $container) $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; $template = null; - if (isset($attributes[0]['template'])) { - if (!isset($attributes[0]['id'])) { + $collectorClass = $container->findDefinition($id)->getClass(); + $isTemplateAware = is_subclass_of($collectorClass, TemplateAwareDataCollectorInterface::class); + if (isset($attributes[0]['template']) || $isTemplateAware) { + $idForTemplate = $attributes[0]['id'] ?? $collectorClass; + if (!$idForTemplate) { throw new InvalidArgumentException(sprintf('Data collector service "%s" must have an id attribute in order to specify a template.', $id)); } - $template = [$attributes[0]['id'], $attributes[0]['template']]; + $template = [$idForTemplate, $attributes[0]['template'] ?? $collectorClass::getTemplate()]; } $collectors->insert([$id, $template], [$priority, --$order]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php index 99299282aa06c..c9594b0b0896e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php @@ -12,8 +12,15 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector; +use Symfony\Bundle\FrameworkBundle\DataCollector\TemplateAwareDataCollectorInterface; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; class ProfilerPassTest extends TestCase { @@ -54,4 +61,64 @@ public function testValidCollector() $this->assertCount(1, $methodCalls); $this->assertEquals('add', $methodCalls[0][0]); // grab the method part of the first call } + + public function provideValidCollectorWithTemplateUsingAutoconfigure(): \Generator + { + yield [new class() implements TemplateAwareDataCollectorInterface { + public function collect(Request $request, Response $response, \Throwable $exception = null) + { + } + + public function getName(): string + { + return static::class; + } + + public function reset() + { + } + + public static function getTemplate(): string + { + return 'foo'; + } + }]; + + yield [new class() extends AbstractDataCollector { + public function collect(Request $request, Response $response, \Throwable $exception = null) + { + } + + public static function getTemplate(): string + { + return 'foo'; + } + }]; + } + + /** + * @dataProvider provideValidCollectorWithTemplateUsingAutoconfigure + */ + public function testValidCollectorWithTemplateUsingAutoconfigure(TemplateAwareDataCollectorInterface $dataCollector) + { + $container = new ContainerBuilder(); + $profilerDefinition = $container->register('profiler', 'ProfilerClass'); + + $container->registerForAutoconfiguration(DataCollectorInterface::class)->addTag('data_collector'); + $container->register('mydatacollector', \get_class($dataCollector))->setAutoconfigured(true); + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ProfilerPass())->process($container); + + $idForTemplate = \get_class($dataCollector); + $this->assertSame(['mydatacollector' => [$idForTemplate, 'foo']], $container->getParameter('data_collector.templates')); + + // grab the method calls off of the "profiler" definition + $methodCalls = $profilerDefinition->getMethodCalls(); + $this->assertCount(1, $methodCalls); + $this->assertEquals('add', $methodCalls[0][0]); // grab the method part of the first call + + (new ResolveChildDefinitionsPass())->process($container); + $this->assertSame($idForTemplate, $container->get('mydatacollector')->getName()); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy