/** * Return routes for given request and response * * @param string verb * @param string path * @param string type The Content-Type, or NULL * @param scriptlet.Preference accept the "Accept" header's contents * @return var[] */ public function targetsFor($verb, $path, $type, Preference $accept) { if (!isset($this->routes[$verb])) { return array(); } // Short-circuit // Figure out matching routes $path = rtrim($path, '/'); $matching = $order = array(); foreach ($this->routes[$verb] as $route) { if (!preg_match($route->getPattern(), $path, $segments)) { continue; } // Check input type if specified by client if (NULL !== $type) { $pref = new Preference($route->getAccepts($this->input)); if (NULL === ($input = $pref->match(array($type)))) { continue; } $q = $pref->qualityOf($input, 6); } else { $input = NULL; $q = 0.0; } // Check output type if (NULL === ($output = $accept->match($route->getProduces($this->output)))) { continue; } // Found possible candidate $matching[] = array('handler' => $route->getHandler(), 'target' => $route->getTarget(), 'params' => $route->getParams(), 'segments' => $segments, 'input' => $input, 'output' => $output); $order[sizeof($matching) - 1] = $q + $accept->qualityOf($output, 6); } // Sort by quality arsort($order, SORT_NUMERIC); $return = array(); foreach ($order as $offset => $q) { $return[] = $matching[$offset]; } return $return; }