Permalink
Browse files

Made routes regex enables

  • Loading branch information...
1 parent 4950fd3 commit 49ca24175a0078345ed880d0703baef098eb1b28 @brucespang committed Sep 24, 2010
Showing with 116 additions and 21 deletions.
  1. +0 −1 README
  2. +34 −20 frank/core.php
  3. +1 −0 frank/frank.php
  4. +59 −0 frank/helpers.php
  5. +8 −0 index.php
  6. +14 −0 tests/FrankTest.php
View
@@ -6,7 +6,6 @@ What Frank.php is missing:
3. Error handling besides not_found(function(){});
4. Environments
5. Testing
-6. Regex routes, or using "*" in routes. For now, just use :whatever and passing, and you should be all set.
Here is Sinatra's hello world:
require 'sinatra'
View
@@ -397,41 +397,55 @@ private static function get_method(){
* @return array Function to call and parameters to call it with
*/
private static function route($method, $request){
- $params = array();
-
- if(isset(self::$routes[$method][$request])){
- $block = self::$routes[$method][$request];
- }else{
- $wilds = preg_grep('#^/.*/:.*$#', array_keys(self::$routes[$method]));
+ $params = array(
+ 'splat' => array(),
+ 'captures' => array()
+ );
- foreach($wilds as $wild){
- $wild_preg = preg_replace('/:[A-Za-z0-9]+/', '(.*?)', $wild);
- if(preg_match("#^$wild_preg\$#", $request, $matches)){
- $block = self::$routes[$method][$wild];
- preg_match('/:[A-Za-z0-9]+/', $wild, $wild_names);
- foreach($wild_names as $key => $wild_name){
- $wild_name = str_replace(':', '', $wild_name);
- $params[$wild_name] = urldecode($matches[$key+1]);
- }
- }
+ if(isset(self::$routes[$method][$request])){
+ $function = self::$routes[$method][$request];
+ } elseif(($route = reverse_preg_match_array($request, array_keys(self::$routes[$method]), array('#\*(/|$)#', '/:[A-Za-z0-9]+/'))) && $route !== false){
+ $route = end($route);
+
+ // The only different things between the request url and the
+ // route should be the regex's, so we get them.
+ $changes = url_diff($request, $route);
+
+ $function = self::$routes[$method][$route];
+
+ foreach($changes as $index => $value){
+ if(preg_match('/^:/', $index)){
+
+ //Strip leading :
+ $index = preg_replace('/^:/', '', $index);
+
+ $params[$index] = $value;
+
+ }elseif($index == '*'){
+
+ $params['splat'][] = $value;
+
+ } else {
+ $params['captures'][] = $value;
+ }
}
}
- if(!isset($block)){
+ if(!isset($function)){
self::$status = 404;
//We don't want to display headers for command line
if(!defined('STDIN'))
header("HTTP/1.1 404 Not Found");
if(isset(self::$errors['404']))
- $block = self::$errors['404'];
+ $function = self::$errors['404'];
else
- $block = function(){ echo "We couldn't find that page."; };
+ $function = function(){ echo "We couldn't find that page."; };
}
- return array($block, $params);
+ return array($function, $params);
}
}
?>
View
@@ -1,5 +1,6 @@
<?php
+ require('helpers.php');
require('core.php');
require('library.php');
View
@@ -0,0 +1,59 @@
+<?php
+
+ /**
+ * Reverse Preg Match Array
+ *
+ * Tries to match the contents of an array to a given string.
+ *
+ * @param string $string String to search with array
+ * @param array $regex_array Regexes to use for search
+ * @param array $also_match Other regexs to match
+ * @return array or false (depending on whether or not matches were found)
+ */
+ function reverse_preg_match_array($string, $regex_array, $also_match=array()){
+ $matches = array();
+
+ foreach($regex_array as $regex){
+
+ $new_regex = $regex;
+
+ foreach($also_match as $match)
+ $new_regex = preg_replace($match, '.*?', $new_regex);
+
+ if(preg_match("#^$new_regex$#", $string))
+ $matches[] = $regex;
+ }
+
+ if(count($matches) > 0)
+ return $matches;
+ else
+ return false;
+ }
+
+ /**
+ * URL Difference
+ *
+ * Returns an array containing the differences (split by /) in two urls
+ *
+ * @param string $url_1 Original url
+ * @param string $url_2 URL whose differences are returned
+ * @return array
+ */
+ function url_diff($url_1, $url_2){
+ //If the two urls are exactly the same, than we don't need to do anything.
+ if($url_1 == $url_2)
+ return array();
+
+ $differences = array();
+ $url_1 = explode('/', $url_1);
+ $url_2 = explode('/', $url_2);
+
+ foreach($url_1 as $key => $url_1_item){
+ if($url_2[$key] !== $url_1_item)
+ $differences[$url_2[$key]] = $url_1_item;
+ }
+
+ return $differences;
+ }
+
+?>
View
@@ -48,6 +48,14 @@ function hello($name){
echo hello($params['name']);
});
+ get("/splat/*", function($params){
+ echo $params['splat'][0];
+ });
+
+ get("/captures/(.*?)", function($params){
+ echo $params['captures'][0];
+ });
+
get("/halt", function(){
halt(404, 'Go away', array('Content-Type' => 'text/plain'));
});
View
@@ -62,6 +62,20 @@ public function test404(){
}
/**
+ * Tests if splat routes work
+ */
+ public function testSplat(){
+ $this->assertEquals("test", $this->get_data('/splat/test', array('pass' => true)));
+ }
+
+ /**
+ * Tests if regex routes work
+ */
+ public function testCaptures(){
+ $this->assertEquals("test", $this->get_data('/captures/test', array('pass' => true)));
+ }
+
+ /**
* Private Functions
*/

0 comments on commit 49ca241

Please sign in to comment.