From b892264882398c43c352f0552e431c6d44f7b7cf Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Thu, 11 Oct 2012 16:05:04 +0200 Subject: [PATCH] =?UTF-8?q?d=C3=A9claration=20dans=20le=20bundle=20de=20la?= =?UTF-8?q?=20m=C3=A9canique=20des=20controlleurs=20un=20controlleur=20qui?= =?UTF-8?q?=20contient=20une=20collection=20de=20Matcher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Thelia/Controller/DefaultController.php | 11 +++ core/lib/Thelia/Controller/NullController.php | 15 +++ core/lib/Thelia/Core/TheliaBundle.php | 30 +++++- .../Thelia/Routing/Matcher/DefaultMatcher.php | 34 +++++++ .../Matcher/TheliaMatcherCollection.php | 94 +++++++++++++------ 5 files changed, 152 insertions(+), 32 deletions(-) create mode 100644 core/lib/Thelia/Controller/DefaultController.php create mode 100644 core/lib/Thelia/Controller/NullController.php create mode 100644 core/lib/Thelia/Routing/Matcher/DefaultMatcher.php diff --git a/core/lib/Thelia/Controller/DefaultController.php b/core/lib/Thelia/Controller/DefaultController.php new file mode 100644 index 000000000..8e22ce8c2 --- /dev/null +++ b/core/lib/Thelia/Controller/DefaultController.php @@ -0,0 +1,11 @@ + diff --git a/core/lib/Thelia/Controller/NullController.php b/core/lib/Thelia/Controller/NullController.php new file mode 100644 index 000000000..83568dcad --- /dev/null +++ b/core/lib/Thelia/Controller/NullController.php @@ -0,0 +1,15 @@ + diff --git a/core/lib/Thelia/Core/TheliaBundle.php b/core/lib/Thelia/Core/TheliaBundle.php index 3faf7dc84..667f5c3bb 100644 --- a/core/lib/Thelia/Core/TheliaBundle.php +++ b/core/lib/Thelia/Core/TheliaBundle.php @@ -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'))); + + + } } diff --git a/core/lib/Thelia/Routing/Matcher/DefaultMatcher.php b/core/lib/Thelia/Routing/Matcher/DefaultMatcher.php new file mode 100644 index 000000000..a78553f14 --- /dev/null +++ b/core/lib/Thelia/Routing/Matcher/DefaultMatcher.php @@ -0,0 +1,34 @@ +controller = $controller; + } + + public function matchRequest(Request $request) { + + + $objectInformation = new \ReflectionObject($this->controller); + + $parameter = array( + '_controller' => $objectInformation->getName().'::noAction' + ); + + return $parameter; + } +} + + +?> diff --git a/core/lib/Thelia/Routing/Matcher/TheliaMatcherCollection.php b/core/lib/Thelia/Routing/Matcher/TheliaMatcherCollection.php index 023a09d97..fb9d3be8b 100644 --- a/core/lib/Thelia/Routing/Matcher/TheliaMatcherCollection.php +++ b/core/lib/Thelia/Routing/Matcher/TheliaMatcherCollection.php @@ -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'); } /**