Overview

Namespaces

  • api
  • config
  • database
  • PHP
  • Slim
    • Exception
    • Http
    • Middleware
  • utiliy

Classes

  • Environment
  • Log
  • LogWriter
  • Middleware
  • Route
  • Router
  • Slim
  • View
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Slim - a micro PHP 5 framework
  4:  *
  5:  * @author      Josh Lockhart <info@slimframework.com>
  6:  * @copyright   2011 Josh Lockhart
  7:  * @link        http://www.slimframework.com
  8:  * @license     http://www.slimframework.com/license
  9:  * @version     2.0.0
 10:  * @package     Slim
 11:  *
 12:  * MIT LICENSE
 13:  *
 14:  * Permission is hereby granted, free of charge, to any person obtaining
 15:  * a copy of this software and associated documentation files (the
 16:  * "Software"), to deal in the Software without restriction, including
 17:  * without limitation the rights to use, copy, modify, merge, publish,
 18:  * distribute, sublicense, and/or sell copies of the Software, and to
 19:  * permit persons to whom the Software is furnished to do so, subject to
 20:  * the following conditions:
 21:  *
 22:  * The above copyright notice and this permission notice shall be
 23:  * included in all copies or substantial portions of the Software.
 24:  *
 25:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 26:  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 27:  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 28:  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 29:  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 30:  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 31:  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 32:  */
 33: namespace Slim;
 34: 
 35: /**
 36:  * Route
 37:  * @package Slim
 38:  * @author  Josh Lockhart, Thomas Bley
 39:  * @since   1.0.0
 40:  */
 41: class Route
 42: {
 43:     /**
 44:      * @var string The route pattern (e.g. "/books/:id")
 45:      */
 46:     protected $pattern;
 47: 
 48:     /**
 49:      * @var mixed The route callable
 50:      */
 51:     protected $callable;
 52: 
 53:     /**
 54:      * @var array Conditions for this route's URL parameters
 55:      */
 56:     protected $conditions = array();
 57: 
 58:     /**
 59:      * @var array Default conditions applied to all route instances
 60:      */
 61:     protected static $defaultConditions = array();
 62: 
 63:     /**
 64:      * @var string The name of this route (optional)
 65:      */
 66:     protected $name;
 67: 
 68:     /**
 69:      * @var array Key-value array of URL parameters
 70:      */
 71:     protected $params = array();
 72: 
 73:     /**
 74:      * @var array value array of URL parameter names
 75:      */
 76:     protected $paramNames = array();
 77: 
 78:     /**
 79:      * @var array key array of URL parameter names with + at the end
 80:      */
 81:     protected $paramNamesPath = array();
 82: 
 83:     /**
 84:      * @var array HTTP methods supported by this Route
 85:      */
 86:     protected $methods = array();
 87: 
 88:     /**
 89:      * @var array[Callable] Middleware to be run before only this route instance
 90:      */
 91:     protected $middleware = array();
 92: 
 93:     /**
 94:      * Constructor
 95:      * @param string $pattern  The URL pattern (e.g. "/books/:id")
 96:      * @param mixed  $callable Anything that returns TRUE for is_callable()
 97:      */
 98:     public function __construct($pattern, $callable)
 99:     {
100:         $this->setPattern($pattern);
101:         $this->setCallable($callable);
102:         $this->setConditions(self::getDefaultConditions());
103:     }
104: 
105:     /**
106:      * Set default route conditions for all instances
107:      * @param  array $defaultConditions
108:      */
109:     public static function setDefaultConditions(array $defaultConditions)
110:     {
111:         self::$defaultConditions = $defaultConditions;
112:     }
113: 
114:     /**
115:      * Get default route conditions for all instances
116:      * @return array
117:      */
118:     public static function getDefaultConditions()
119:     {
120:         return self::$defaultConditions;
121:     }
122: 
123:     /**
124:      * Get route pattern
125:      * @return string
126:      */
127:     public function getPattern()
128:     {
129:         return $this->pattern;
130:     }
131: 
132:     /**
133:      * Set route pattern
134:      * @param  string $pattern
135:      */
136:     public function setPattern($pattern)
137:     {
138:         $this->pattern = $pattern;
139:     }
140: 
141:     /**
142:      * Get route callable
143:      * @return mixed
144:      */
145:     public function getCallable()
146:     {
147:         return $this->callable;
148:     }
149: 
150:     /**
151:      * Set route callable
152:      * @param  mixed $callable
153:      * @throws \InvalidArgumentException If argument is not callable
154:      */
155:     public function setCallable($callable)
156:     {
157:         if (!is_callable($callable)) {
158:             throw new \InvalidArgumentException('Route callable must be callable');
159:         }
160: 
161:         $this->callable = $callable;
162:     }
163: 
164:     /**
165:      * Get route conditions
166:      * @return array
167:      */
168:     public function getConditions()
169:     {
170:         return $this->conditions;
171:     }
172: 
173:     /**
174:      * Set route conditions
175:      * @param  array $conditions
176:      */
177:     public function setConditions(array $conditions)
178:     {
179:         $this->conditions = $conditions;
180:     }
181: 
182:     /**
183:      * Get route name
184:      * @return string|null
185:      */
186:     public function getName()
187:     {
188:         return $this->name;
189:     }
190: 
191:     /**
192:      * Set route name
193:      * @param  string $name
194:      */
195:     public function setName($name)
196:     {
197:         $this->name = (string) $name;
198:     }
199: 
200:     /**
201:      * Get route parameters
202:      * @return array
203:      */
204:     public function getParams()
205:     {
206:         return $this->params;
207:     }
208: 
209:     /**
210:      * Set route parameters
211:      * @param  array $params
212:      */
213:     public function setParams($params)
214:     {
215:         $this->params = $params;
216:     }
217: 
218:     /**
219:      * Get route parameter value
220:      * @param  string                    $index     Name of URL parameter
221:      * @return string
222:      * @throws \InvalidArgumentException If route parameter does not exist at index
223:      */
224:     public function getParam($index)
225:     {
226:         if (!isset($this->params[$index])) {
227:             throw new \InvalidArgumentException('Route parameter does not exist at specified index');
228:         }
229: 
230:         return $this->params[$index];
231:     }
232: 
233:     /**
234:      * Set route parameter value
235:      * @param  string                    $index     Name of URL parameter
236:      * @param  mixed                     $value     The new parameter value
237:      * @throws \InvalidArgumentException If route parameter does not exist at index
238:      */
239:     public function setParam($index, $value)
240:     {
241:         if (!isset($this->params[$index])) {
242:             throw new \InvalidArgumentException('Route parameter does not exist at specified index');
243:         }
244:         $this->params[$index] = $value;
245:     }
246: 
247:     /**
248:      * Add supported HTTP method(s)
249:      */
250:     public function setHttpMethods()
251:     {
252:         $args = func_get_args();
253:         $this->methods = $args;
254:     }
255: 
256:     /**
257:      * Get supported HTTP methods
258:      * @return array
259:      */
260:     public function getHttpMethods()
261:     {
262:         return $this->methods;
263:     }
264: 
265:     /**
266:      * Append supported HTTP methods
267:      */
268:     public function appendHttpMethods()
269:     {
270:         $args = func_get_args();
271:         $this->methods = array_merge($this->methods, $args);
272:     }
273: 
274:     /**
275:      * Append supported HTTP methods (alias for Route::appendHttpMethods)
276:      * @return \Slim\Route
277:      */
278:     public function via()
279:     {
280:         $args = func_get_args();
281:         $this->methods = array_merge($this->methods, $args);
282: 
283:         return $this;
284:     }
285: 
286:     /**
287:      * Detect support for an HTTP method
288:      * @return bool
289:      */
290:     public function supportsHttpMethod($method)
291:     {
292:         return in_array($method, $this->methods);
293:     }
294: 
295:     /**
296:      * Get middleware
297:      * @return array[Callable]
298:      */
299:     public function getMiddleware()
300:     {
301:         return $this->middleware;
302:     }
303: 
304:     /**
305:      * Set middleware
306:      *
307:      * This method allows middleware to be assigned to a specific Route.
308:      * If the method argument `is_callable` (including callable arrays!),
309:      * we directly append the argument to `$this->middleware`. Else, we
310:      * assume the argument is an array of callables and merge the array
311:      * with `$this->middleware`.  Each middleware is checked for is_callable()
312:      * and an InvalidArgumentException is thrown immediately if it isn't.
313:      *
314:      * @param  Callable|array[Callable]
315:      * @return \Slim\Route
316:      * @throws \InvalidArgumentException If argument is not callable or not an array of callables.
317:      */
318:     public function setMiddleware($middleware)
319:     {
320:         if (is_callable($middleware)) {
321:             $this->middleware[] = $middleware;
322:         } elseif (is_array($middleware)) {
323:             foreach($middleware as $callable) {
324:                 if (!is_callable($callable)) {
325:                     throw new \InvalidArgumentException('All Route middleware must be callable');
326:                 }
327:             }
328:             $this->middleware = array_merge($this->middleware, $middleware);
329:         } else {
330:             throw new \InvalidArgumentException('Route middleware must be callable or an array of callables');
331:         }
332: 
333:         return $this;
334:     }
335: 
336:     /**
337:      * Matches URI?
338:      *
339:      * Parse this route's pattern, and then compare it to an HTTP resource URI
340:      * This method was modeled after the techniques demonstrated by Dan Sosedoff at:
341:      *
342:      * http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/
343:      *
344:      * @param  string $resourceUri A Request URI
345:      * @return bool
346:      */
347:     public function matches($resourceUri)
348:     {
349:         //Convert URL params into regex patterns, construct a regex for this route, init params
350:         $patternAsRegex = preg_replace_callback('#:([\w]+)\+?#', array($this, 'matchesCallback'),
351:             str_replace(')', ')?', (string) $this->pattern));
352:         if (substr($this->pattern, -1) === '/') {
353:             $patternAsRegex .= '?';
354:         }
355: 
356:         //Cache URL params' names and values if this route matches the current HTTP request
357:         if (!preg_match('#^' . $patternAsRegex . '$#', $resourceUri, $paramValues)) {
358:             return false;
359:         }
360:         foreach ($this->paramNames as $name) {
361:             if (isset($paramValues[$name])) {
362:                 if (isset($this->paramNamesPath[ $name ])) {
363:                     $this->params[$name] = explode('/', urldecode($paramValues[$name]));
364:                 } else {
365:                     $this->params[$name] = urldecode($paramValues[$name]);
366:                 }
367:             }
368:         }
369: 
370:         return true;
371:     }
372: 
373:     /**
374:      * Convert a URL parameter (e.g. ":id", ":id+") into a regular expression
375:      * @param  array    URL parameters
376:      * @return string   Regular expression for URL parameter
377:      */
378:     protected function matchesCallback($m)
379:     {
380:         $this->paramNames[] = $m[1];
381:         if (isset($this->conditions[ $m[1] ])) {
382:             return '(?P<' . $m[1] . '>' . $this->conditions[ $m[1] ] . ')';
383:         }
384:         if (substr($m[0], -1) === '+') {
385:             $this->paramNamesPath[ $m[1] ] = 1;
386: 
387:             return '(?P<' . $m[1] . '>.+)';
388:         }
389: 
390:         return '(?P<' . $m[1] . '>[^/]+)';
391:     }
392: 
393:     /**
394:      * Set route name
395:      * @param  string     $name The name of the route
396:      * @return \Slim\Route
397:      */
398:     public function name($name)
399:     {
400:         $this->setName($name);
401: 
402:         return $this;
403:     }
404: 
405:     /**
406:      * Merge route conditions
407:      * @param  array      $conditions Key-value array of URL parameter conditions
408:      * @return \Slim\Route
409:      */
410:     public function conditions(array $conditions)
411:     {
412:         $this->conditions = array_merge($this->conditions, $conditions);
413: 
414:         return $this;
415:     }
416: }
417: 
GeoApi API documentation generated by ApiGen 2.8.0