-
Notifications
You must be signed in to change notification settings - Fork 27
[WIP] Create custom behavior for RouteNotFoundException #177
Changes from 6 commits
07f82f1
f84801b
92dcac3
c4b5db8
838326c
6b4ef0d
d488351
a38748f
b43205b
1965165
e24ef17
1f503d9
cc20e5a
d6a4168
ec419eb
a8d8b1a
065f3de
5f728a8
48e18f8
245baf0
ff47fe3
4bf8b4f
0210a96
33a38a9
95501b5
a79d05b
d285952
b0c8c95
ecdaba7
1071d80
2ba2f5f
d7a36ee
0065722
ead1422
b58061a
a344ed1
a3e3a9d
3d0aa64
3cc7e0d
436112e
9dcb337
be8bf38
2f62868
60b5837
2977160
da86417
f7dce24
d235909
35f9ff2
b0d4281
745eb82
a0615c7
3415e86
f574e57
00962cd
bb1257c
e9de76d
d772177
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\DependencyInjection\Compiler; | ||
|
||
|
||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Exception\LogicException; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
/** | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
class RegisterBestMatcherPass implements CompilerPassInterface | ||
{ | ||
/** | ||
* {@inheritDoc} | ||
* | ||
* @throws LogicException If a tagged service is not public. | ||
*/ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
if (!$container->hasDefinition('cmf_seo.error_handling.matcher.presentation')) { | ||
return; | ||
} | ||
|
||
$presentationDefinition = $container->getDefinition('cmf_seo.error_handling.matcher.presentation'); | ||
$taggedServices = $container->findTaggedServiceIds('cmf_seo.best_matcher'); | ||
|
||
foreach ($taggedServices as $id => $attributes) { | ||
$definition = $container->getDefinition($id); | ||
if (!$definition->isPublic()) { | ||
throw new LogicException(sprintf('Matcher "%s" must be public.', $id)); | ||
} | ||
|
||
$group = null; | ||
foreach ($attributes as $attribute) { | ||
if (isset($attribute['group'])) { | ||
$group = $attribute['group']; | ||
break; | ||
} | ||
} | ||
$group = null !== $group ? $group : 'default'; | ||
|
||
$presentationDefinition->addMethodCall('addMatcher', array(new Reference($id), $group)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony CMF package. | ||
* | ||
* (c) 2011-2014 Symfony CMF | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\ErrorHandling; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
/** | ||
* This BestMatcher tries to create a route collection of | ||
* all ancestors of a given uri. | ||
* | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
class AncestorBestMatcher extends PhpcrBestMatcher | ||
{ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extra blank line |
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function create(Request $request) | ||
{ | ||
// TODO: Implement create() method. | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somebody (@dantleech, @lsmith77) any hints to build a good and fast query for getting all ancestors? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't want to use a query but instead want to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yes .. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony CMF package. | ||
* | ||
* (c) 2011-2014 Symfony CMF | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\ErrorHandling; | ||
|
||
use Symfony\Bundle\TwigBundle\Controller\ExceptionController; | ||
use Symfony\Cmf\Bundle\SeoBundle\Exception\InvalidArgumentException; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Exception\FlattenException; | ||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; | ||
|
||
/** | ||
* This presentation model enriches the the values to render the | ||
* error pages by the help of so called BestMatcher. | ||
* | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
class BestMatchPresentation extends ExceptionController | ||
{ | ||
/** | ||
* Chain of matcher. | ||
* | ||
* @var array|BestMatcherInterface[] | ||
*/ | ||
protected $matcherChain = array(); | ||
|
||
/** | ||
* @param Request $request | ||
* @param FlattenException $exception | ||
* @param DebugLoggerInterface $logger | ||
* @param string $_format | ||
* @return Response | ||
*/ | ||
public function showAction( | ||
Request $request, | ||
FlattenException $exception, | ||
DebugLoggerInterface $logger = null, | ||
$_format = 'html' | ||
) { | ||
$code = $exception->getStatusCode(); | ||
|
||
if (404 !== $code) { | ||
return parent::showAction($request, $exception, $logger, $_format); | ||
} | ||
|
||
$currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1)); | ||
$bestMatches = array(); | ||
|
||
foreach ($this->matcherChain as $group => $matcher) { | ||
$bestMatches[$group] = $matcher->create($request); | ||
} | ||
|
||
$template = $this->findTemplate($request, $_format, $code, $this->debug); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would a matcher need to provide its own template maybe? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thougt we just can use the common behavior, means: overwrite the TwigTemplate. |
||
|
||
return new Response($this->twig->render( | ||
$template, | ||
array( | ||
'status_code' => $code, | ||
'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', | ||
'exception' => $exception, | ||
'logger' => $logger, | ||
'currentContent' => $currentContent, | ||
'best_matches' => $bestMatches, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the test template does not use this information if i see correctly. we should have the documentation provide a good example how to use this info There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea, thats exactly my problem, but i have got no solution for it. :-( |
||
) | ||
)); | ||
} | ||
|
||
/** | ||
* @param BestMatcherInterface $matcher | ||
* @param string $group Unique per Chain. | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function addMatcher(BestMatcherInterface $matcher, $group) | ||
{ | ||
if (array_key_exists($group, $this->matcherChain)) { | ||
throw new InvalidArgumentException(sprintf('You can only add on matcher with group %s.', $group)); | ||
} | ||
|
||
$this->matcherChain[$group] = $matcher; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\ErrorHandling; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\Routing\RouteCollection; | ||
|
||
/** | ||
* Interface to create a BestMatcher. | ||
* | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
interface BestMatcherInterface | ||
{ | ||
/** | ||
* Based on the current request BestMatcher creates collections of | ||
* route as suggestions to navigate to. | ||
* | ||
* @param Request $request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a blank line after this |
||
* @return RouteCollection | ||
*/ | ||
public function create(Request $request); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony CMF package. | ||
* | ||
* (c) 2011-2014 Symfony CMF | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\ErrorHandling; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\Routing\RouteCollection; | ||
|
||
/** | ||
* This BestMatcher will try to detect a parent route of a given uri. | ||
* | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
class ParentBestMatcher extends PhpcrBestMatcher | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this not keep phpcr in the class name? or all live in Doctrine\Phpcr? |
||
{ | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function create(Request $request) | ||
{ | ||
$routes = new RouteCollection(); | ||
$uriAsArray = explode('/', $request->getUri()); | ||
if (count($uriAsArray) <= 1) { | ||
return $routes; | ||
} | ||
|
||
$uriAsArray = array_shift($uriAsArray); | ||
$parentUri = implode('/', $uriAsArray); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony CMF package. | ||
* | ||
* (c) 2011-2014 Symfony CMF | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Cmf\Bundle\SeoBundle\ErrorHandling; | ||
|
||
use Doctrine\Common\Persistence\ManagerRegistry; | ||
use Doctrine\ODM\PHPCR\DocumentManager; | ||
|
||
/** | ||
* Abstract BestMatcher for those who needs make use of base | ||
* phpcr-odm classes. | ||
* | ||
* @author Maximilian Berghoff <Maximilian.Berghoff@gmx.de> | ||
*/ | ||
abstract class PhpcrBestMatcher implements BestMatcherInterface | ||
{ | ||
/** | ||
* @var ManagerRegistry | ||
*/ | ||
protected $managerRegistry; | ||
|
||
/** | ||
* @param ManagerRegistry $managerRegistry | ||
*/ | ||
public function setManagerRegistry($managerRegistry) | ||
{ | ||
$this->managerRegistry = $managerRegistry; | ||
} | ||
|
||
/** | ||
* @return ManagerRegistry | ||
*/ | ||
public function getManagerRegistry() | ||
{ | ||
return $this->managerRegistry; | ||
} | ||
|
||
/** | ||
* @param string $class | ||
* @return null|DocumentManager | ||
*/ | ||
public function getManagerForClass($class) | ||
{ | ||
return $this->managerRegistry->getManagerForClass($class); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
|
||
<parameters> | ||
<parameter key="cmf_seo.error_handling.matcher.parent.class">Symfony\Cmf\Bundle\SeoBundle\ErrorHandling\ParentBestMatcher</parameter> | ||
<parameter key="cmf_seo.error_handling.matcher.ancestor.class">Symfony\Cmf\Bundle\SeoBundle\ErrorHandling\AncestorBestMatcher</parameter> | ||
</parameters> | ||
|
||
<services> | ||
<service id="cmf_seo.error_handling.matcher.parent" class="%cmf_seo.error_handling.matcher.parent.class%"> | ||
<call method="setManagerRegistry"> | ||
<argument type="service" id="doctrine_phpcr" /> | ||
</call> | ||
<tag name="cmf_seo.best_matcher" group="parent" /> | ||
</service> | ||
<service id="cmf_seo.error_handling.matcher.ancestor" class="%cmf_seo.error_handling.matcher.ancestor.class%"> | ||
<call method="setManagerRegistry"> | ||
<argument type="service" id="doctrine_phpcr" /> | ||
</call> | ||
<tag name="cmf_seo.best_matcher" group="ancestor" /> | ||
</service> | ||
|
||
</services> | ||
|
||
</container> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we use european dates, not the confused american ones ;-) so its YYYY-MM-DD