Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • Controller
  • Dispatcher
  • Helpers
  • Pattern

Functions

  • contextualize
  • decontextualize
  1 <?php
  2 
  3 /*
  4  * This file is part of the ICanBoogie package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace ICanBoogie\Routing;
 13 
 14 use ICanBoogie\HTTP\RedirectResponse;
 15 use ICanBoogie\HTTP\Request;
 16 use ICanBoogie\HTTP\Response;
 17 
 18 use ICanBoogie\Route;
 19 use ICanBoogie\Routes;
 20 
 21 /**
 22  * Dispatches requests among the defined routes.
 23  *
 24  * If a route matching the request is found, the `$route` and `$decontextualized_path`
 25  * properties are add to the request object. `$route` holds the route object,
 26  * `$decontextualized_path` holds the decontextualized path. The path is decontextualized using
 27  * the {@link decontextualize()} function.
 28  *
 29  * <pre>
 30  * use ICanBoogie\HTTP\Dispatcher;
 31  *
 32  * $dispatcher = new Dispatcher(array('routes' => 'ICanBoogie\Routing\Dispatcher'));
 33  * </pre>
 34  */
 35 class Dispatcher implements \ICanBoogie\HTTP\IDispatcher
 36 {
 37     public function __invoke(Request $request)
 38     {
 39         $decontextualized_path = decontextualize($request->normalized_path);
 40 
 41         if ($decontextualized_path != '/')
 42         {
 43             $decontextualized_path = rtrim($decontextualized_path, '/');
 44         }
 45 
 46         $route = Routes::get()->find($decontextualized_path, $captured, $request->method);
 47 
 48         if (!$route)
 49         {
 50             return;
 51         }
 52 
 53         if ($route->location)
 54         {
 55             return new RedirectResponse(contextualize($route->location), 302);
 56         }
 57 
 58         $request->path_params = $captured + $request->path_params;
 59         $request->params = $captured + $request->params;
 60         $request->route = $route;
 61         $request->decontextualized_path = $decontextualized_path;
 62 
 63         return $this->dispatch($route, $request);
 64     }
 65 
 66     /**
 67      * Dispatches the route.
 68      *
 69      * @param Route $route
 70      * @param Request $request
 71      *
 72      * @return Response|null
 73      */
 74     protected function dispatch(Route $route, Request $request)
 75     {
 76         new Dispatcher\BeforeDispatchEvent($this, $route, $request, $response);
 77 
 78         if (!$response)
 79         {
 80             $controller = $route->controller;
 81 
 82             #
 83             # if the controller is not a callable then it is considered as a class name and
 84             # is used to instantiate the controller.
 85             #
 86 
 87             if (!is_callable($controller))
 88             {
 89                 $controller_class = $controller;
 90                 $controller = new $controller_class($route);
 91             }
 92 
 93             $response = $controller($request);
 94 
 95             if ($response !== null && !($response instanceof Response))
 96             {
 97                 $response = new Response($response, 200, array
 98                 (
 99                     'Content-Type' => 'text/html; charset=utf-8'
100                 ));
101             }
102         }
103 
104         new Dispatcher\DispatchEvent($this, $route, $request, $response);
105 
106         return $response;
107     }
108 
109     /**
110      * Fires {@link \ICanBoogie\Routing\Dispatcher\RescueEvent} and returns the response provided
111      * by third parties. If no response was provided, the exception (or the exception provided by
112      * third parties) is rethrown.
113      *
114      * @return \ICanBoogie\HTTP\Response
115      */
116     public function rescue(\Exception $exception, Request $request)
117     {
118         if (isset($request->route))
119         {
120             new Dispatcher\RescueEvent($exception, $request, $request->route, $response);
121 
122             if ($response)
123             {
124                 return $response;
125             }
126         }
127 
128         throw $exception;
129     }
130 }
131 
132 /*
133  * Events
134  */
135 
136 namespace ICanBoogie\Routing\Dispatcher;
137 
138 use ICanBoogie\HTTP\Request;
139 use ICanBoogie\HTTP\Response;
140 use ICanBoogie\Route;
141 use ICanBoogie\Routing\Dispatcher;
142 
143 /**
144  * Event class for the `ICanBoogie\Routing\Dispatcher::dispatch:before` event.
145  *
146  * Third parties may use this event to provide a response to the request before the route is
147  * mapped. The event is usually used by third parties to redirect requests or provide cached
148  * responses.
149  */
150 class BeforeDispatchEvent extends \ICanBoogie\Event
151 {
152     /**
153      * The route.
154      *
155      * @var \ICanBoogie\Route
156      */
157     public $route;
158 
159     /**
160      * The HTTP request.
161      *
162      * @var \ICanBoogie\HTTP\Request
163      */
164     public $request;
165 
166     /**
167      * Reference to the HTTP response.
168      *
169      * @var \ICanBoogie\HTTP\Response
170      */
171     public $response;
172 
173     /**
174      * The event is constructed with the type `dispatch:before`.
175      *
176      * @param Dispatcher $target
177      * @param array $payload
178      */
179     public function __construct(Dispatcher $target, Route $route, Request $request, &$response)
180     {
181         if ($response !== null && !($response instanceof Response))
182         {
183             throw new \InvalidArgumentException('$response must be an instance of ICanBoogie\HTTP\Response. Given: ' . get_class($response) . '.');
184         }
185 
186         $this->route = $route;
187         $this->request = $request;
188         $this->response = &$response;
189 
190         parent::__construct($target, 'dispatch:before');
191     }
192 }
193 
194 /**
195  * Event class for the `ICanBoogie\Routing\Dispatcher::dispatch` event.
196  *
197  * Third parties may use this event to alter the response before it is returned by the dispatcher.
198  */
199 class DispatchEvent extends \ICanBoogie\Event
200 {
201     /**
202      * The route.
203      *
204      * @var \ICanBoogie\Route
205      */
206     public $route;
207 
208     /**
209      * The request.
210      *
211      * @var \ICanBoogie\HTTP\Request
212      */
213     public $request;
214 
215     /**
216      * Reference to the response.
217      *
218      * @var \ICanBoogie\HTTP\Response|null
219      */
220     public $response;
221 
222     /**
223      * The event is constructed with the type `dispatch`.
224      *
225      * @param Dispatcher $target
226      * @param array $payload
227      */
228     public function __construct(Dispatcher $target, Route $route, Request $request, &$response)
229     {
230         $this->route = $route;
231         $this->request = $request;
232         $this->response = &$response;
233 
234         parent::__construct($target, 'dispatch');
235     }
236 }
237 
238 /**
239  * Event class for the `ICanBoogie\Routing\Dispatcher::rescue` event.
240  *
241  * Third parties may use this event to _rescue_ an exception by providing a suitable response.
242  * Third parties may also use this event to replace the exception to rethrow.
243  */
244 class RescueEvent extends \ICanBoogie\Exception\RescueEvent
245 {
246     /**
247      * Route to rescue.
248      *
249      * @var \ICanBoogie\Route
250      */
251     public $route;
252 
253     /**
254      * Initializes the {@link $route} property.
255      *
256      * @param \Exception $target
257      * @param \ICanBoogie\HTTP\Request $request
258      * @param \ICanBoogie\Route $route
259      * @param \ICanBoogie\HTTP\Response|null $response
260      */
261     public function __construct(\Exception &$target, Request $request, Route $route, &$response)
262     {
263         $this->route = $route;
264 
265         parent::__construct($target, $request, $response);
266     }
267 }
Autodoc API documentation generated by ApiGen 2.8.0