déclaration dans le bundle de la mécanique des controlleurs

un controlleur qui contient une collection de Matcher
This commit is contained in:
Manuel Raynaud
2012-10-11 16:05:04 +02:00
parent 69ac78c790
commit b892264882
5 changed files with 152 additions and 32 deletions

View File

@@ -0,0 +1,11 @@
<?php
namespace Thelia\Controller;
use Thelia\Controller\NullController;
class DefaultController extends NullController{
}
?>

View File

@@ -0,0 +1,15 @@
<?php
namespace Thelia\Controller;
abstract class NullController {
/**
* Nothing to do
*/
public function noAction(){
}
}
?>

View File

@@ -14,14 +14,38 @@ class TheliaBundle extends Bundle {
$container->addScope( new Scope('request'));
$container->register('request', 'Symfony\Component\HttpFoundation\Request');
$container->register('dispatcher','Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher')
->addArgument(new Reference('service_container'));
$container->register('resolver', 'Thelia\Controller\TheliaController');
$container->register('controller.default','Thelia\Controller\DefaultController');
$container->register('matcher.default','Thelia\Routing\Matcher\DefaultMatcher')
->addArgument(new Reference('controller.default'));
$container->register('matcher','Thelia\Routing\Matcher\theliaMatcherCollection')
->addMethodCall('add', array(new Reference('matcher.default'), -255))
//->addMethodCall('add','a matcher class (instance or class name)
;
$container->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver');
$container->register('parser','Thelia\Core\TheliaTemplate');
/**
* RouterListener implements EventSubscriberInterface and listen for kernel.request event
*/
$container->register('listener.router', 'Symfony\Component\HttpKernel\EventListener\RouterListener')
->setArguments(array(new Reference('matcher')));
//$container->register('listener.view')
$container->register('http_kernel','Symfony\Component\HttpKernel\HttpKernel')
->addArgument(new Reference('dispatcher'))
->addArgument(new Reference('resolver'));
$container->register('dispatcher','Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher')
->addArgument(new Reference('service_container'))
->addMethodCall('addSubscriber', array(new Reference('listener.router')));
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Thelia\Routing\Matcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Thelia\Controller\NullController;
/**
* Default matcher when no action is needed and there is no result for urlmatcher
*/
class DefaultMatcher implements RequestMatcherInterface{
protected $controller;
public function __construct(NullController $controller) {
$this->controller = $controller;
}
public function matchRequest(Request $request) {
$objectInformation = new \ReflectionObject($this->controller);
$parameter = array(
'_controller' => $objectInformation->getName().'::noAction'
);
return $parameter;
}
}
?>

View File

@@ -3,14 +3,21 @@
namespace Thelia\Routing\Matcher;
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
//use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\RequestContextAwareInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpFoundation\Request;
class TheliaMatcherCollection implements RequestMatcherInterface, UrlMatcherInterface {
class TheliaMatcherCollection implements RequestMatcherInterface, RequestContextAwareInterface {
protected $context;
protected $matchers = array();
protected $defaultMatcher;
protected $sortedMatchers = array();
/**
* Constructor
@@ -18,18 +25,48 @@ class TheliaMatcherCollection implements RequestMatcherInterface, UrlMatcherInte
* Check if this constructor id needed (is RequestContext needed ? )
*/
public function __construct() {
$this->context = new RequestContext();
}
public function add($matcher){
if(!$matcher instanceof RequestMatcherInterface && !$matcher instanceof UrlMatcherInterface){
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
/**
* allow to add a matcher routing class to the matchers collection
* matcher must implement RequestMatcherInterface or UrlMatcherInterface
*
* @param RequestMatcherInterface $matcher
* @param int $priority set the priority of the added matcher
*
*/
public function add(RequestMatcherInterface $matcher, $priority = 0){
if(!is_object($matcher)){
$matcher = new $matcher();
}
$this->matchers[] = $matcher;
if(!isset($this->matchers[$priority])){
$this->matchers[$priority] = array();
}
$this->matchers[$priority][] = $matcher;
$this->sortedMatchers = array();
}
public function getSortedMatchers(){
if(empty($this->sortedMatchers)){
$this->sortedMatchers = $this->sortMatchers();
}
return $this->sortedMatchers;
}
public function sortMatchers(){
$sortedMatchers = array();
krsort($this->matchers);
foreach($this->matchers as $matcher){
$sortedMatchers = array_merge($sortedMatchers,$matcher);
}
return $sortedMatchers;
}
@@ -46,28 +83,27 @@ class TheliaMatcherCollection implements RequestMatcherInterface, UrlMatcherInte
* @throws ResourceNotFoundException If no matching resource could be found
* @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed
*/
public function matchRequest(Request $request){
public function matchRequest(Request $request) {
if(empty($this->matchers)){
throw new \InvalidArgumentException('there is no matcher added to the TheliaMatcherCollection');
}
}
/**
* Tries to match a URL path with a set of routes.
*
* If the matcher can not find information, it must throw one of the exceptions documented
* below.
*
* @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)
*
* @return array An array of parameters
*
* @throws ResourceNotFoundException If the resource could not be found
* @throws MethodNotAllowedException If the resource was found but the request method is not allowed
*
* @api
*/
public function match($pathinfo){
foreach($this->getSortedMatchers() as $matcher){
try{
return $matcher->matchRequest($request);
}
catch (ResourceNotFoundException $e){
//no action, wait for next matcher
}
catch(MethodNotAllowedException $e){
/**
* @todo what todo with a MethodNotAllowedException ?
*/
}
}
throw new ResourceNotFoundException('No one matcher in this collection matched the current request');
}
/**