Commit
…oblems
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?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\Console\Input\InputArgument; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Routing\RouterInterface; | ||
use Symfony\Component\Routing\Matcher\TraceableUrlMatcher; | ||
|
||
/** | ||
* A console command to test route matching. | ||
* | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
*/ | ||
class RouterMatchCommand extends ContainerAwareCommand | ||
{ | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function isEnabled() | ||
{ | ||
if (!$this->getContainer()->has('router')) { | ||
return false; | ||
} | ||
$router = $this->getContainer()->get('router'); | ||
if (!$router instanceof RouterInterface) { | ||
return false; | ||
} | ||
return parent::isEnabled(); | ||
} | ||
|
||
/** | ||
* @see Command | ||
*/ | ||
protected function configure() | ||
{ | ||
$this | ||
->setDefinition(array( | ||
new InputArgument('path_info', InputArgument::REQUIRED, 'A path info'), | ||
)) | ||
->setName('router:match') | ||
->setDescription('Helps debug routes by simulating a path info match') | ||
->setHelp(<<<EOF | ||
The <info>router:match</info> simulates a path info match: | ||
<info>router:match /foo</info> | ||
EOF | ||
) | ||
; | ||
} | ||
|
||
/** | ||
* @see Command | ||
*/ | ||
protected function execute(InputInterface $input, OutputInterface $output) | ||
{ | ||
$router = $this->getContainer()->get('router'); | ||
$matcher = new TraceableUrlMatcher($router->getRouteCollection(), $router->getContext()); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
fabpot
Author
Member
|
||
|
||
$traces = $matcher->getTraces($input->getArgument('path_info')); | ||
|
||
$matches = false; | ||
foreach ($traces as $i => $trace) { | ||
if (TraceableUrlMatcher::ROUTE_ALMOST_MATCHES == $trace['level']) { | ||
$output->writeln(sprintf('<fg=yellow>Route "%s" almost matches but %s</>', $trace['name'], lcfirst($trace['log']))); | ||
} elseif (TraceableUrlMatcher::ROUTE_MATCHES == $trace['level']) { | ||
$output->writeln(sprintf('<fg=green>Route "%s" matches</>', $trace['name'])); | ||
$matches = true; | ||
} elseif ($input->getOption('verbose')) { | ||
$output->writeln(sprintf('Route "%s" does not match: %s', $trace['name'], $trace['log'])); | ||
} | ||
} | ||
|
||
if (!$matches) { | ||
$output->writeln('<fg=red>None of the routes matches</>'); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?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\DataCollector; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\DataCollector\DataCollector; | ||
use Symfony\Component\Routing\Matcher\TraceableUrlMatcher; | ||
use Symfony\Component\Routing\RouterInterface; | ||
|
||
/** | ||
* RouterDataCollector. | ||
* | ||
* @author Fabien Potencier <fabien@symfony.com> | ||
*/ | ||
class RouterDataCollector extends DataCollector | ||
{ | ||
private $router; | ||
|
||
public function __construct(RouterInterface $router = null) | ||
{ | ||
$this->router = $router; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function collect(Request $request, Response $response, \Exception $exception = null) | ||
{ | ||
$this->data['path_info'] = $request->getPathInfo(); | ||
|
||
if (!$this->router) { | ||
$this->data['traces'] = array(); | ||
} else { | ||
$matcher = new TraceableUrlMatcher($this->router->getRouteCollection(), $this->router->getContext()); | ||
|
||
$this->data['traces'] = $matcher->getTraces($request->getPathInfo()); | ||
} | ||
} | ||
|
||
public function getPathInfo() | ||
{ | ||
return $this->data['path_info']; | ||
} | ||
|
||
public function getTraces() | ||
{ | ||
return $this->data['traces']; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'router'; | ||
} | ||
} |
I see an issue with such a setup:
getRouteCollection
calls the loader (it is intended to do so) so running the command in the prod (non-debug) environment may produce a different result than the routing of a request because the request will use the cache. A common issue according to what I see on IRC is forgetting to clear the prod cache after changing the routing. It could be a good idea to have a command doing the matching with the cached router.