Skip to content

[FrameworkBundle][WebProfilerBundle] Move ProfilerPass to the WebProfiler bundle #21368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
3 changes: 3 additions & 0 deletions UPGRADE-3.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ FrameworkBundle
---------------

* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass` has been deprecated. Use `Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass` instead.

* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass` class has been deprecated and will be removed in 4.0, use the
`Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass` class instead.

HttpKernel
-----------
Expand Down
3 changes: 3 additions & 0 deletions UPGRADE-4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ FrameworkBundle

* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass` has been removed. Use `Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass` instead.

* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass` class has been removed, use the
`Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass` class instead.

SecurityBundle
--------------

Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CHANGELOG
is disabled.
* Added `GlobalVariables::getToken()`
* Deprecated `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass`. Use `Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass` instead.
* Deprecated `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass`. Use `Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass` instead.

3.2.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,17 @@

namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@trigger_error(sprintf('The %s class is deprecated since version 3.3 and will be removed in 4.0. Use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass instead.', ProfilerPass::class), E_USER_DEPRECATED);

use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass as BaseProfilerPass;

/**
* Adds tagged data_collector services to profiler service.
*
* @deprecated since version 3.3, to be removed in 4.0. Use {@link BaseProfilerPass} instead.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ProfilerPass implements CompilerPassInterface
class ProfilerPass extends BaseProfilerPass
{
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('profiler')) {
return;
}

$definition = $container->getDefinition('profiler');

$collectors = new \SplPriorityQueue();
$order = PHP_INT_MAX;
foreach ($container->findTaggedServiceIds('data_collector') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$template = null;

if (isset($attributes[0]['template'])) {
if (!isset($attributes[0]['id'])) {
throw new InvalidArgumentException(sprintf('Data collector service "%s" must have an id attribute in order to specify a template', $id));
}
$template = array($attributes[0]['id'], $attributes[0]['template']);
}

$collectors->insert(array($id, $template), array($priority, --$order));
}

$templates = array();
foreach ($collectors as $collector) {
$definition->addMethodCall('add', array(new Reference($collector[0])));
$templates[$collector[0]] = $collector[1];
}

$container->setParameter('data_collector.templates', $templates);
}
}
11 changes: 9 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass;
Expand All @@ -36,6 +35,7 @@
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ValidateWorkflowsPass;
use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -74,7 +74,7 @@ public function build(ContainerBuilder $container)
parent::build($container);

$container->addCompilerPass(new RoutingResolverPass());
$container->addCompilerPass(new ProfilerPass());
$this->addCompilerPassIfExists($container, ProfilerPass::class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to specify the FQCN of an alternative implementation (the already existing one) that will be used as a fallback to provide backwards compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're saying that I should write

if (class_exists(ProfilerPass::class)) {
    $container->addCompilerPass(new ProfilerPass());
}

and duplicate the code ?
or just say somewhere that I took this part of the code from #21283 which has already been reviewed ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or do I have to link to the old Implementation ?

or the last chance, make an if/else to import the new one or the old one ?

Copy link
Member

@chalasr chalasr Jan 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xabbuh In fact this doesn't expect a fallback. For the AddConsoleCommandPass, we just added a conflict to the frameworkbundle so that it is always available (it was your suggestion #19443 (comment)). I started to do the same for the FormPass (#21283) and SerializerPass(#21293), is it ok to do the same here or should we fallback to the deprecated one and mute deprecation instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Adding the conflict rule should be the solution here too.

// must be registered before removing private services as some might be listeners/subscribers
// but as late as possible to get resolved parameters
$container->addCompilerPass(new RegisterListenersPass(), PassConfig::TYPE_BEFORE_REMOVING);
Expand Down Expand Up @@ -109,4 +109,11 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new CacheCollectorPass());
}
}

private function addCompilerPassIfExists(ContainerBuilder $container, $class, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION, $priority = 0)
{
if (class_exists($class)) {
$container->addCompilerPass(new $class(), $type, $priority);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass;

/**
* @group legacy
*/
class ProfilerPassTest extends \PHPUnit_Framework_TestCase
{
private $profilerDefinition;
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@
"symfony/validator": "~3.2",
"symfony/yaml": "~3.2",
"symfony/property-info": "~2.8|~3.0",
"symfony/web-profiler-bundle": "~3.3",
"doctrine/annotations": "~1.0",
"phpdocumentor/reflection-docblock": "^3.0",
"twig/twig": "~1.26|~2.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0",
"phpdocumentor/type-resolver": "<0.2.0",
"symfony/console": "<3.3"
"symfony/console": "<3.3",
"symfony/web-profiler-bundle": "<3.3"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"symfony/web-profiler-bundle": "~3.3" must be added as dev requirement in addition of the conflict, that should make the build green.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I figured in your comment .
The fix is coming.

},
"suggest": {
"ext-apcu": "For best performance of the system caches",
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

3.3.0
-----

* added `ProfilerPass`

3.1.0
-----

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

/**
* Adds tagged data_collector services to profiler service.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ProfilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('profiler')) {
return;
}

$definition = $container->getDefinition('profiler');

$collectors = new \SplPriorityQueue();
$order = PHP_INT_MAX;
foreach ($container->findTaggedServiceIds('data_collector') as $id => $attributes) {
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
$template = null;

if (isset($attributes[0]['template'])) {
if (!isset($attributes[0]['id'])) {
throw new InvalidArgumentException(sprintf('Data collector service "%s" must have an id attribute in order to specify a template', $id));
}
$template = array($attributes[0]['id'], $attributes[0]['template']);
}

$collectors->insert(array($id, $template), array($priority, --$order));
}

$templates = array();
foreach ($collectors as $collector) {
$definition->addMethodCall('add', array(new Reference($collector[0])));
$templates[$collector[0]] = $collector[1];
}

$container->setParameter('data_collector.templates', $templates);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\WebProfilerBundle\Tests\DependencyInjection\Compiler;

use Symfony\Bundle\WebProfilerBundle\DependencyInjection\Compiler\ProfilerPass;
use Symfony\Component\DependencyInjection\Definition;

class ProfilerPassTest extends \PHPUnit_Framework_TestCase
{
private $profilerDefinition;

protected function setUp()
{
$this->profilerDefinition = new Definition('ProfilerClass');
}

/**
* Tests that collectors that specify a template but no "id" will throw
* an exception (both are needed if the template is specified).
*
* Thus, a fully-valid tag looks something like this:
*
* <tag name="data_collector" template="YourBundle:Collector:templatename" id="your_collector_name" />
*/
public function testTemplateNoIdThrowsException()
{
// one service, with a template key, but no id
$services = array(
'my_collector_service' => array(0 => array('template' => 'foo')),
);

$builder = $this->createContainerMock($services);

$this->setExpectedException('InvalidArgumentException');

$profilerPass = new ProfilerPass();
$profilerPass->process($builder);
}

public function testValidCollector()
{
// one service, with a template key, but no id
$services = array(
'my_collector_service' => array(0 => array('template' => 'foo', 'id' => 'my_collector')),
);

$container = $this->createContainerMock($services);

// fake the getDefinition() to return a Profiler definition
$container->expects($this->atLeastOnce())
->method('getDefinition');

// assert that the data_collector.templates parameter should be set
$container->expects($this->once())
->method('setParameter')
->with('data_collector.templates', array('my_collector_service' => array('my_collector', 'foo')));

$profilerPass = new ProfilerPass();
$profilerPass->process($container);

// grab the method calls off of the "profiler" definition
$methodCalls = $this->profilerDefinition->getMethodCalls();
$this->assertCount(1, $methodCalls);
$this->assertEquals('add', $methodCalls[0][0]); // grab the method part of the first call
}

private function createContainerMock($services)
{
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'setParameter'))->getMock();
$container->expects($this->any())
->method('hasDefinition')
->with($this->equalTo('profiler'))
->will($this->returnValue(true));
$container->expects($this->any())
->method('getDefinition')
->will($this->returnValue($this->profilerDefinition));
$container->expects($this->atLeastOnce())
->method('findTaggedServiceIds')
->will($this->returnValue($services));

return $container;
}
}