diff --git a/CHANGELOG b/CHANGELOG index 9151439..50a3edc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +3.10.0 (unreleased): + * Feature: Allow complex types to be handled by symfony/serializer if available + * Feature: Leverage dependency injection for Serializers + * Fix: Profiler tab was broken in some case + * Enhancement: Better looking profiling tab + 3.9.0 (2025-01-17): * Feature: (SF6.2+) Supports automatic value resolving in controllers (with or without MapEntity), see [https://github.com/symfony/symfony/blob/7.2/src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php](Doctrine Bridge) * Feature: supports serializer options in attributes diff --git a/composer.json b/composer.json index 4012097..bd97aec 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "require": { "php": ">=8.1", - "ccmbenchmark/ting": "^3.10", + "ccmbenchmark/ting": "^3.11", "doctrine/cache": "^1.10", "symfony/validator": "^4.4 || ^5.0 || ^6.0 || ^7.0", "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0 || ^7.0", @@ -18,7 +18,9 @@ "atoum/stubs": "^2.2", "brick/geo": ">=0.5 <=1.0", "symfony/expression-language": "^6.3 || ^7.2", + "symfony/serializer": "^6.0 || ^7.0", "symfony/security-bundle": "^6.0 || ^7.0", + "symfony/security-core": "^6.0 || ^7.0", "symfony/uid": "^6.0 || ^7.0" }, "autoload": { diff --git a/src/TingBundle/DataCollector/TingCacheDataCollector.php b/src/TingBundle/DataCollector/TingCacheDataCollector.php index c78f2f5..b81d030 100644 --- a/src/TingBundle/DataCollector/TingCacheDataCollector.php +++ b/src/TingBundle/DataCollector/TingCacheDataCollector.php @@ -38,8 +38,6 @@ class TingCacheDataCollector extends DataCollector implements LateDataCollectorI */ protected $cacheLogger = null; - protected array|Data $data = []; - public function __construct() { $this->init(); @@ -57,7 +55,7 @@ public function __construct() public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if ($this->cacheLogger !== null) { - $this->data['cache']['operations'] = $this->cacheLogger->getOperations(); + $this->data['cache']['operations'] = $this->cloneVar($this->cacheLogger->getOperations()); $this->data['cache']['operationsCount'] = count($this->data['cache']['operations']); $this->data['cache']['time'] = $this->cacheLogger->getTotalTime(); $this->data['cache']['hits'] = $this->cacheLogger->getHits(); @@ -68,7 +66,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep public function lateCollect(): void { if ($this->cacheLogger !== null) { - $this->data['cache']['operations'] = $this->cacheLogger->getOperations(); + $this->data['cache']['operations'] = $this->cloneVar($this->cacheLogger->getOperations()); $this->data['cache']['operationsCount'] = count($this->data['cache']['operations']); $this->data['cache']['time'] = $this->cacheLogger->getTotalTime(); $this->data['cache']['hits'] = $this->cacheLogger->getHits(); diff --git a/src/TingBundle/DataCollector/TingDriverDataCollector.php b/src/TingBundle/DataCollector/TingDriverDataCollector.php index ae4f8f2..4bc978d 100644 --- a/src/TingBundle/DataCollector/TingDriverDataCollector.php +++ b/src/TingBundle/DataCollector/TingDriverDataCollector.php @@ -38,8 +38,6 @@ class TingDriverDataCollector extends DataCollector implements LateDataCollector */ protected $driverLogger = null; - protected array|Data $data = []; - public function __construct() { $this->init(); @@ -57,44 +55,24 @@ public function __construct() public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if ($this->driverLogger !== null) { - $this->data['driver']['queries'] = $this->driverLogger->getQueries(); - $this->data['driver']['execs'] = $this->driverLogger->getExecs(); + $this->data['driver']['queries'] = $this->cloneVar($this->driverLogger->getQueries()); + $this->data['driver']['execs'] = $this->cloneVar($this->driverLogger->getExecs()); $this->data['driver']['queryCount'] = count($this->data['driver']['queries']); $this->data['driver']['time'] = $this->driverLogger->getTotalTime(); - $this->data['driver']['connections'] = $this->driverLogger->getConnections(); - $this->data['driver']['connectionsHashToName'] = $this->driverLogger->getConnectionsHashToName(); - - // HttpKernel < 3.2 compatibility layer - // For >= 3.2 cloneVar is always present and MUST be used. - if (method_exists($this, 'cloneVar')) { - foreach ($this->data['driver']['queries'] as &$query) { - if (isset($query['params']) === true) { - $query['params'] = $this->cloneVar($query['params']); - } - } - } + $this->data['driver']['connections'] = $this->cloneVar($this->driverLogger->getConnections()); + $this->data['driver']['connectionsHashToName'] = $this->cloneVar($this->driverLogger->getConnectionsHashToName()); } } public function lateCollect(): void { if ($this->driverLogger !== null) { - $this->data['driver']['queries'] = $this->driverLogger->getQueries(); - $this->data['driver']['execs'] = $this->driverLogger->getExecs(); + $this->data['driver']['queries'] = $this->cloneVar($this->driverLogger->getQueries()); + $this->data['driver']['execs'] = $this->cloneVar($this->driverLogger->getExecs()); $this->data['driver']['queryCount'] = count($this->data['driver']['queries']); $this->data['driver']['time'] = $this->driverLogger->getTotalTime(); - $this->data['driver']['connections'] = $this->driverLogger->getConnections(); - $this->data['driver']['connectionsHashToName'] = $this->driverLogger->getConnectionsHashToName(); - - // HttpKernel < 3.2 compatibility layer - // For >= 3.2 cloneVar is always present and MUST be used. - if (method_exists($this, 'cloneVar')) { - foreach ($this->data['driver']['queries'] as &$query) { - if (isset($query['params']) === true) { - $query['params'] = $this->cloneVar($query['params']); - } - } - } + $this->data['driver']['connections'] = $this->cloneVar($this->driverLogger->getConnections()); + $this->data['driver']['connectionsHashToName'] = $this->cloneVar($this->driverLogger->getConnectionsHashToName()); } } diff --git a/src/TingBundle/DependencyInjection/TingExtension.php b/src/TingBundle/DependencyInjection/TingExtension.php index bb72c56..bcce466 100644 --- a/src/TingBundle/DependencyInjection/TingExtension.php +++ b/src/TingBundle/DependencyInjection/TingExtension.php @@ -28,6 +28,7 @@ use CCMBenchmark\TingBundle\ArgumentResolver\EntityValueResolver; use CCMBenchmark\TingBundle\Schema\Column; use CCMBenchmark\TingBundle\Schema\Table; +use CCMBenchmark\TingBundle\Serializer\SymfonySerializer; use Doctrine\Common\Cache\VoidCache; use Symfony\Component\DependencyInjection\ChildDefinition; use CCMBenchmark\TingBundle\TingBundle; @@ -43,6 +44,7 @@ use Symfony\Component\HttpKernel\Controller\ValueResolverInterface; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Config\FileLocator; +use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Uid\Uuid; use Symfony\Component\PropertyAccess\PropertyAccessor; @@ -152,6 +154,11 @@ public function load(array $configs, ContainerBuilder $container): void $container->setDefinition(EntityValueResolver::class, $definition); } + + $serializerFactoryDefinition = $container->getDefinition('ting.serializerfactory'); + foreach ($container->findTaggedServiceIds('ting.serializer') as $id => $tags) { + $serializerFactoryDefinition->addMethodCall('add', [new Reference($id)]); + } } /** @@ -205,15 +212,24 @@ function getMetadata(\ReflectionClass $reflector, Table $attribute): Definition \DateTime::class => 'datetime', \DateTimeZone::class => 'datetimezone', Uuid::class => 'uuid', - default => 'string' + default => (interface_exists(SerializerInterface::class) ? 'symfony_serializer' : 'string') }; } + $options = $mappingAttribute->getArguments()['serializerOptions'] ?? []; + if ($newField['type'] === 'symfony_serializer') { + $defaultOptions = [ + 'serialize' => ['context' => ['groups' => ['*']]], + 'unserialize' => ['context' => ['groups' => ['*']], 'type' => $property->getType()->getName()] + ]; + $options = array_merge_recursive($defaultOptions, $options); + $newField['serializer'] = SymfonySerializer::class; + } if ($mappingAttribute->getArguments()['serializer'] ?? false) { $newField['serializer'] = $mappingAttribute->getArguments()['serializer']; } - if ($mappingAttribute->getArguments()['serializerOptions'] ?? false) { - $newField['serializer_options'] = $mappingAttribute->getArguments()['serializerOptions']; + if ($options !== []) { + $newField['serializer_options'] = $options; } $newMetadata->addMethodCall('addField', [$newField]); diff --git a/src/TingBundle/Resources/config/services.xml b/src/TingBundle/Resources/config/services.xml index e4335e1..a0ebcf6 100644 --- a/src/TingBundle/Resources/config/services.xml +++ b/src/TingBundle/Resources/config/services.xml @@ -5,6 +5,11 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + + + + + @@ -28,7 +33,7 @@ - + @@ -118,5 +123,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/TingBundle/Resources/views/Collector/driverCollector.html.twig b/src/TingBundle/Resources/views/Collector/driverCollector.html.twig index 0311091..4ad659d 100644 --- a/src/TingBundle/Resources/views/Collector/driverCollector.html.twig +++ b/src/TingBundle/Resources/views/Collector/driverCollector.html.twig @@ -2,132 +2,321 @@ {% block toolbar %} {% set icon %} - Database - {{ collector.querycount }} - {% if collector.querycount > 0 %} - in {{ '%0.2f'|format(collector.time) }} ms - {% endif %} + Database + + {{ collector.querycount }} + + {% if collector.querycount > 0 %} + + + {{ '%0.2f'|format(collector.time) }} ms + + + {% endif %} {% endset %} + {% set text %} -
- DB Queries - {{ collector.querycount }} -
-
- Query time - {{ '%0.2f'|format(collector.time) }} ms -
+
+ Queries + + {{ collector.querycount }} + +
+
+ Execution time + + {{ '%0.2f'|format(collector.time) }} ms + +
{% endset %} {% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} {% block menu %} - - - Ting Queries - - {{ collector.querycount }} - {{ '%0.0f'|format(collector.time) }} ms + + + + + Ting Queries + + {{ collector.querycount }} + {{ '%0.0f'|format(collector.time) }} ms + - {% endblock %} {% block panel %} - {#{% if 'explain' == page %} - {{ render(controller('TingBundle:Profiler:explain', { - 'token': token, - 'panel': 'db', - 'connectionName': app.request.query.get('connection'), - 'query': app.request.query.get('query') - })) }} - {% else %} - {{ block('queries') }} - {% endif %}#} {{ block('queries') }} {% endblock %} {% block queries %} -

Queries

- - {% if collector.queries is empty %} -

- No queries. -

- {% else %} -