Beispiel #1
0
 /**
  * Process the supplied url.
  *
  * This route takes a simplified series of patterns such as :controller and
  * replaces them with more complex regular expressions which are then used
  * within a preg_match_callback to match against the given uri.
  *
  * If a 'filter' regex is set within the $options array that regex will be
  * used within the preg_match_callback. Otherwise a default regex of
  * ([a-zA-Z0-9_\+\-%]+) is used.
  *
  * If one of the 'simplified' patterns within the rule is :results, this is
  * treated specially and uses a ([a-zA-Z0-9_\+\-%\/]+) regex which will match
  * the same as the default as well as / .
  *
  * This causes the pattern to match entire sections of uri's. Allowing a
  * simple pattern like the default /:controller/:action/:results to match
  * uri's like /foo/bar/a/b/c/d/e/f/g/h and cause everything after /foo/bar
  * to be added to the Payload object as results (which are in turn transformed
  * into key => value pairs).
  *
  * TODO: A lot of this fluffing around could (and likely should) be moved into
  * the __construct and other protected internal methods.
  *
  * @param Proem\Http\Request $request
  */
 public function process(Request $request)
 {
     // All routes must at least specify a rule.
     if (!isset($this->options['rule'])) {
         return false;
     }
     // Setup.
     $rule = str_replace('/', '/?', $this->options['rule']);
     $targets = isset($this->options['targets']) ? $this->options['targets'] : [];
     $customFilters = isset($this->options['filters']) ? $this->options['filters'] : [];
     $defaultTokens = $this->defaultTokens;
     $defaultFilters = $this->defaultFilters;
     $url = $request->getRequestUri();
     $tokens = [];
     $values = [];
     $results = [];
     // Build the main regular expression.
     $regex = '^' . preg_replace_callback('@:[\\w]+@', function ($matches) use($customFilters, $defaultTokens, $defaultFilters) {
         $key = str_replace(':', '', $matches[0]);
         if (isset($customFilters[$key])) {
             if (isset($defaultFilters[$customFilters[$key]])) {
                 return '(' . $defaultFilters[$customFilters[$key]] . ')';
             } else {
                 if ($customFilters[$key][0] == ':') {
                     throw new \RuntimeException("The custom filter named \"{$key}\" references a\n                                non-existent builtin filter named \"{$customFilters[$key]}\".");
                 } else {
                     return '(' . $customFilters[$key] . ')';
                 }
             }
         } elseif (isset($defaultTokens[$key])) {
             return '(' . $defaultTokens[$key] . ')';
         } else {
             return '(' . $defaultFilters[':default'] . ')';
         }
     }, $rule) . '/?$';
     // Find all tokens.
     preg_match_all('@:([\\w]+)@', $rule, $tokens, PREG_PATTERN_ORDER);
     $tokens = $tokens[0];
     // Test the main regular expression against the url.
     if (preg_match('@^' . $regex . '$@', $url, $values)) {
         // Discard *all* matches index.
         array_shift($values);
         // Match tokens to values
         foreach ($tokens as $index => $value) {
             if (isset($values[$index])) {
                 $results[substr($value, 1)] = urldecode($values[$index]);
             }
         }
         // Replace any results with specific targets..
         foreach ($targets as $key => $value) {
             $results[$key] = $value;
         }
         // If the current $key is "params" & the string within $value looks
         // like a / seperated string, parse it into an associative array.
         if (isset($results['params']) && strpos($results['params'], '/') !== false) {
             preg_match_all("/([^\\/]+)\\/([^\\/]+)/", $results['params'], $m);
             $results = array_merge($results, array_combine($m[1], $m[2]));
             unset($results['params']);
         }
         // Route has matched, return results.
         return $results;
     }
     return false;
 }
Beispiel #2
0
 public function testOptionalSwitchMatchesCenter()
 {
     $request_with = Request::create('/foo/bar/bob');
     $request_without = Request::create('/foo/bob');
     $route = new Route(['rule' => '/:module/:controller?/:action']);
     $this->assertTrue(is_array($route->process($request_with)));
     $this->assertTrue(is_array($route->process($request_without)));
 }