Skip to content

[FrameworkBundle] Add file links to named controllers in debug:router #36270

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

Merged
merged 1 commit into from
Apr 5, 2020
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
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
5.1.0
-----

* Added link to source for controllers registered as named services
* Added link to source on controller on `router:match`/`debug:router` (when `framework.ide` is configured)
* Added `Routing\Loader` and `Routing\Loader\Configurator` namespaces to ease defining routes with default controllers
* Added the `framework.router.context` configuration node to configure the `RequestContext`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?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\FrameworkBundle\Command;

use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;

/**
* @internal
*
* @author Robin Chalas <robin.chalas@gmail.com>
* @author Nicolas Grekas <p@tchwork.com>
*/
trait BuildDebugContainerTrait
{
protected $containerBuilder;

/**
* Loads the ContainerBuilder from the cache.
*
* @throws \LogicException
*/
protected function getContainerBuilder(): ContainerBuilder
{
if ($this->containerBuilder) {
return $this->containerBuilder;
}

$kernel = $this->getApplication()->getKernel();

if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
$container = $buildContainer();
$container->getCompilerPassConfig()->setRemovingPasses([]);
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
$container->compile();
} else {
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
$locatorPass = new ServiceLocatorTagPass();
$locatorPass->process($container);
}

return $this->containerBuilder = $container;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,15 @@
namespace Symfony\Bundle\FrameworkBundle\Command;

use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
Expand All @@ -36,12 +32,9 @@
*/
class ContainerDebugCommand extends Command
{
protected static $defaultName = 'debug:container';
use BuildDebugContainerTrait;

/**
* @var ContainerBuilder|null
*/
protected $containerBuilder;
protected static $defaultName = 'debug:container';

/**
* {@inheritdoc}
Expand Down Expand Up @@ -219,34 +212,6 @@ protected function validateInput(InputInterface $input)
}
}

/**
* Loads the ContainerBuilder from the cache.
*
* @throws \LogicException
*/
protected function getContainerBuilder(): ContainerBuilder
{
if ($this->containerBuilder) {
return $this->containerBuilder;
}

$kernel = $this->getApplication()->getKernel();

if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
$container = $buildContainer();
$container->getCompilerPassConfig()->setRemovingPasses([]);
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
$container->compile();
} else {
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
$locatorPass = new ServiceLocatorTagPass();
$locatorPass->process($container);
}

return $this->containerBuilder = $container;
}

private function findProperServiceName(InputInterface $input, SymfonyStyle $io, ContainerBuilder $builder, string $name, bool $showHidden): string
{
$name = ltrim($name, '\\');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
*/
class RouterDebugCommand extends Command
{
use BuildDebugContainerTrait;

protected static $defaultName = 'debug:router';
private $router;
private $fileLinkFormatter;
Expand Down Expand Up @@ -79,6 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$name = $input->getArgument('name');
$helper = new DescriptorHelper($this->fileLinkFormatter);
$routes = $this->router->getRouteCollection();
$container = $this->fileLinkFormatter ? \Closure::fromCallable([$this, 'getContainerBuilder']) : null;

if ($name) {
if (!($route = $routes->get($name)) && $matchingRoutes = $this->findRouteNameContaining($name, $routes)) {
Expand All @@ -96,13 +99,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
'raw_text' => $input->getOption('raw'),
'name' => $name,
'output' => $io,
'container' => $container,
]);
} else {
$helper->describe($io, $routes, [
'format' => $input->getOption('format'),
'raw_text' => $input->getOption('raw'),
'show_controllers' => $input->getOption('show-controllers'),
'output' => $io,
'container' => $container,
]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ protected function describeRouteCollection(RouteCollection $routes, array $optio
$route->getMethods() ? implode('|', $route->getMethods()) : 'ANY',
$route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY',
'' !== $route->getHost() ? $route->getHost() : 'ANY',
$this->formatControllerLink($controller, $route->getPath()),
$this->formatControllerLink($controller, $route->getPath(), $options['container'] ?? null),
];

if ($showControllers) {
$row[] = $controller ? $this->formatControllerLink($controller, $this->formatCallable($controller)) : '';
$row[] = $controller ? $this->formatControllerLink($controller, $this->formatCallable($controller), $options['container'] ?? null) : '';
}

$tableRows[] = $row;
Expand All @@ -84,7 +84,7 @@ protected function describeRoute(Route $route, array $options = [])
{
$defaults = $route->getDefaults();
if (isset($defaults['_controller'])) {
$defaults['_controller'] = $this->formatControllerLink($defaults['_controller'], $this->formatCallable($defaults['_controller']));
$defaults['_controller'] = $this->formatControllerLink($defaults['_controller'], $this->formatCallable($defaults['_controller']), $options['container'] ?? null);
}

$tableHeaders = ['Property', 'Value'];
Expand Down Expand Up @@ -528,7 +528,7 @@ private function formatRouterConfig(array $config): string
return trim($configAsString);
}

private function formatControllerLink($controller, string $anchorText): string
private function formatControllerLink($controller, string $anchorText, callable $getContainer = null): string
{
if (null === $this->fileLinkFormatter) {
return $anchorText;
Expand All @@ -549,7 +549,23 @@ private function formatControllerLink($controller, string $anchorText): string
$r = new \ReflectionFunction($controller);
}
} catch (\ReflectionException $e) {
return $anchorText;
$id = $controller;
$method = '__invoke';

if ($pos = strpos($controller, '::')) {
$id = substr($controller, 0, $pos);
$method = substr($controller, $pos + 2);
}

if (!$getContainer || !($container = $getContainer()) || !$container->has($id)) {
return $anchorText;
}

try {
$r = new \ReflectionMethod($container->findDefinition($id)->getClass(), $method);
} catch (\ReflectionException $e) {
return $anchorText;
}
}

$fileLink = $this->fileLinkFormatter->format($r->getFileName(), $r->getStartLine());
Expand Down