Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/TwigComponent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## 2.32

- Add option `profiler.collect_components` to control component data collection
in the profiler (enabled in debug mode by default)

## 2.30

- Ensure compatibility with PHP 8.5
Expand Down
2 changes: 2 additions & 0 deletions src/TwigComponent/config/debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Symfony\UX\TwigComponent\DataCollector\TwigComponentDataCollector;
use Symfony\UX\TwigComponent\EventListener\TwigComponentLoggerListener;

use function Symfony\Component\DependencyInjection\Loader\Configurator\abstract_arg;
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;

return static function (ContainerConfigurator $container) {
Expand All @@ -27,6 +28,7 @@
->args([
service('ux.twig_component.component_logger_listener'),
service('twig'),
abstract_arg('profiler collect components'),
])
->tag('data_collector', [
'template' => '@TwigComponent/Collector/twig_component.html.twig',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ final class TwigComponentDataCollector extends AbstractDataCollector implements
public function __construct(
private readonly TwigComponentLoggerListener $logger,
private readonly Environment $twig,
private readonly bool $collectComponents = true,
) {
$this->hasStub = class_exists(ClassStub::class);
}
Expand Down Expand Up @@ -130,12 +131,15 @@ private function collectDataFromLogger(): void
'input_props' => $mountedComponent->getInputProps(),
'attributes' => $mountedComponent->getAttributes()->all(),
'template_index' => $event->getTemplateIndex(),
'component' => $mountedComponent->getComponent(),
'depth' => \count($ongoingRenders),
'children' => [],
'render_start' => $profile[0],
];

if ($this->collectComponents) {
$renders[$renderId]['component'] = $mountedComponent->getComponent();
}

if ($parentId = end($ongoingRenders)) {
$renders[$parentId]['children'][] = $renderId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,11 @@ static function (ChildDefinition $definition, AsTwigComponent $attribute) {
$container->setAlias('console.command.stimulus_component_debug', 'ux.twig_component.command.debug')
->setDeprecated('symfony/ux-twig-component', '2.13', '%alias_id%');

if ($container->getParameter('kernel.debug') && $config['profiler']) {
if ($config['profiler']['enabled']) {
$loader->load('debug.php');

$container->getDefinition('ux.twig_component.data_collector')
->setArgument(2, $config['profiler']['collect_components']);
}

$loader->load('cache.php');
Expand Down Expand Up @@ -215,9 +218,13 @@ public function getConfigTreeBuilder(): TreeBuilder
->scalarNode('anonymous_template_directory')
->info('Defaults to `components`')
->end()
->booleanNode('profiler')
->info('Enables the profiler for Twig Component (in debug mode)')
->defaultValue('%kernel.debug%')
->arrayNode('profiler')
->info('Enables the profiler for Twig Component')
->canBeEnabled()
->children()
->booleanNode('enabled')->defaultValue('%kernel.debug%')->end()
->booleanNode('collect_components')->info('Collect components instances')->defaultTrue()->end()
->end()
->end()
->scalarNode('controllers_json')
->setDeprecated('symfony/ux-twig-component', '2.18', 'The "twig_component.controllers_json" config option is deprecated, and will be removed in 3.0.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,12 @@
<th scope="row">Attributes</th>
<td colspan="4">{{ profiler_dump(render.attributes) }}</td>
</tr>
{% if render.component is defined %}
<tr>
<th scope="row">Component</th>
<td colspan="4">{{ profiler_dump(render.component) }}</td>
</tr>
{% endif %}
</tbody>
</table>
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\UX\TwigComponent\ComponentAttributes;
use Symfony\UX\TwigComponent\ComponentMetadata;
use Symfony\UX\TwigComponent\DataCollector\TwigComponentDataCollector;
use Symfony\UX\TwigComponent\Event\PostRenderEvent;
use Symfony\UX\TwigComponent\Event\PreRenderEvent;
use Symfony\UX\TwigComponent\EventListener\TwigComponentLoggerListener;
use Symfony\UX\TwigComponent\MountedComponent;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Runtime\EscaperRuntime;

/**
* @author Simon André <[email protected]>
Expand All @@ -35,7 +42,7 @@ public function testCollectDoesNothing()
$this->assertSame([], $dataCollector->getData());
}

public function testLateCollect()
public function testLateCollectWithNoCollectedData()
{
$logger = new TwigComponentLoggerListener();
$twig = $this->createMock(Environment::class);
Expand All @@ -54,6 +61,44 @@ public function testLateCollect()
$this->assertEquals(0.0, $dataCollector->getRenderTime());
}

/**
* @testWith [true]
* [false]
*/
public function testLateCollectWithCollectedData(bool $collectComponents)
{
$logger = new TwigComponentLoggerListener();
$twig = new Environment(new ArrayLoader());
$dataCollector = new TwigComponentDataCollector($logger, $twig, $collectComponents);

// Trigger some events to be logged
$mounted = new MountedComponent('foo', new \stdClass(), new ComponentAttributes([], new EscaperRuntime()));
$eventA = new PreRenderEvent($mounted, new ComponentMetadata(['key' => 'foo', 'template' => 'bar']), []);
$logger->onPreRender($eventA);
$eventB = new PostRenderEvent($mounted);
$logger->onPostRender($eventB);

$dataCollector->lateCollect();

$this->assertSame(1, $dataCollector->getComponentCount());
$this->assertIsIterable($dataCollector->getComponents());
$this->assertNotEmpty($dataCollector->getComponents());

$this->assertSame(1, $dataCollector->getRenderCount());
$this->assertIsIterable($dataCollector->getRenders());
$this->assertNotEmpty($dataCollector->getRenders());

foreach ($dataCollector->getRenders() as $render) {
if ($collectComponents) {
$this->assertNotNull($render['component']);
} else {
$this->assertNull($render['component']);
}
}

$this->assertGreaterThan(0.0, $dataCollector->getRenderTime());
}

public function testReset()
{
$logger = new TwigComponentLoggerListener();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,36 @@ public function testDataCollectorWithDebugMode()
$this->compileContainer($container);

$this->assertTrue($container->hasDefinition('ux.twig_component.data_collector'));
$this->assertTrue($container->getDefinition('ux.twig_component.data_collector')->getArgument(2));
}

public function testDataCollectorWithDebugModeCanBeDisabled()
public function testDataCollectorWithCollectComponentsDisabled()
{
$container = $this->createContainer();
$container->setParameter('kernel.debug', true);
$container->registerExtension(new TwigComponentExtension());
$container->loadFromExtension('twig_component', [
'defaults' => [],
'anonymous_template_directory' => 'components/',
'profiler' => false,
'profiler' => [
'collect_components' => false,
],
]);
$this->compileContainer($container);

$this->assertFalse($container->hasDefinition('ux.twig_component.data_collector'));
$this->assertTrue($container->hasDefinition('ux.twig_component.data_collector'));
$this->assertFalse($container->getDefinition('ux.twig_component.data_collector')->getArgument(2));
}

public function testDataCollectorWithoutDebugMode()
public function testDataCollectorWithDebugModeCanBeDisabled()
{
$container = $this->createContainer();
$container->setParameter('kernel.debug', false);
$container->setParameter('kernel.debug', true);
$container->registerExtension(new TwigComponentExtension());
$container->loadFromExtension('twig_component', [
'defaults' => [],
'anonymous_template_directory' => 'components/',
'profiler' => true,
'profiler' => false,
]);
$this->compileContainer($container);

Expand Down
Loading