X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2FRoute.php;h=528fbce0f4817428f1a265e993274d0dd83451e5;hb=b1c6e51d1556176dbdb1cdbe1e26e2b77558d3fe;hp=e4b0603639fb6242226dfc58211d105786753841;hpb=2f6cb905fd9d72e7ba2536c2a7ed9cd2d07a4219;p=php-libraries%2FRouter.git diff --git a/src/Route.php b/src/Route.php index e4b0603..528fbce 100755 --- a/src/Route.php +++ b/src/Route.php @@ -1,23 +1,6 @@ [ ["link_id"] => "12312" ] ] - * @var bool + * @var null|string */ - private $parametersByName; + private $action; /** * @var array @@ -75,16 +52,26 @@ class Route private $config; /** - * @param $resource - * @param array $config + * @var null|string */ - public function __construct($resource, array $config) + private $class; + + /** + * @param string $pathInfo + * @param array $config + */ + public function __construct($pathInfo, array $config) { - $this->url = $resource; - $this->config = $config; - $this->methods = isset($config['methods']) ? (array) $config['methods'] : array(); - $this->target = isset($config['target']) ? $config['target'] : null; - $this->name = isset($config['name']) ? $config['name'] : null; + $this->url = $pathInfo; + $this->config = $config; + $this->methods = isset($config['methods']) ? (array)$config['methods'] : array(); + $this->target = isset($config['target']) ? $config['target'] : null; + $this->name = isset($config['name']) ? $config['name'] : null; + $this->parameters = isset($config['parameters']) ? $config['parameters'] : array(); + $this->filters = isset($config['filters']) ? $config['filters'] : array(); + $action = isset ($this->config['_controller']) ? explode('::', $this->config['_controller']) : array(); + $this->class = isset($action[0]) ? $action[0] : null; + $this->action = isset($action[1]) ? $action[1] : null; } public function getUrl() @@ -134,21 +121,27 @@ class Route $this->name = (string)$name; } - public function setFilters(array $filters, $parametersByName = false) + public function setFilters(array $filters) { - $this->filters = $filters; - $this->parametersByName = $parametersByName; + $this->filters = $filters; + } + + public function getFilters() + { + return $this->filters; } public function getRegex() { - return preg_replace_callback('/(:\w+)/', array(&$this, 'substituteFilter'), $this->url); + $url = preg_quote($this->url); + + return preg_replace_callback('/(\\\\(:\w+))/', array(&$this, 'substituteFilter'), $url); } private function substituteFilter($matches) { - if (isset($matches[1], $this->filters[$matches[1]])) { - return $this->filters[$matches[1]]; + if (isset($matches[1], $this->filters[$matches[2]])) { + return $this->filters[$matches[2]]; } return '([\w-%]+)'; @@ -164,26 +157,128 @@ class Route $this->parameters = $parameters; } - public function dispatch() + public function getValidController() + { + $class = $this->class; + $method = $this->action; + + if (!class_exists($class)) { + return null; + } + + if (empty($method) || trim($method) === '') { + $method = "__invoke"; + } + + try { + $classRexl = new \ReflectionClass($class); + } catch (\ReflectionException $ex) { + return null; + } + + try { + $methRexl = $classRexl->getMethod($method); + } catch (\ReflectionException $ex) { + return null; + } + + // use only public methods + // to avoid calling inherited protected methods + if(!$methRexl->isPublic()) { + return null; + } + + return $this->config['_controller']; + } + + /** + * sort parameters according the the method's arguments + * + * @return array + * + * @throws \ReflectionException + */ + private function sortParameters() { - $action = explode('::', $this->config['_controller']); + $class = $this->class; + $method = $this->action; + $parameters = $this->parameters; + $arguments = array(); - if ($this->parametersByName) { - $this->parameters = array($this->parameters); + if (empty($method) || trim($method) === '') { + $method = "__invoke"; } - $this->action = !empty($action[1]) && trim($action[1]) !== '' ? $action[1] : null; + $rexl = new \ReflectionMethod($class, $method); - if (!is_null($this->action)) { - $instance = new $action[0]; - call_user_func_array(array($instance, $this->action), $this->parameters); + foreach ($rexl->getParameters() as $methArgs) { + $arg = $methArgs->getName(); + + if (array_key_exists($arg, $parameters)) { + $arguments[$arg] = $parameters[$arg]; + + unset($parameters[$arg]); + } else { + // argument is not in the parameters + $arguments[$arg] = null; + } + } + + if (count($parameters) > 0) { + // fill the unset arguments + foreach ($arguments as $arg => &$v) { + if ($v === null) { + //$key = array_keys($parameters)[0]; + + $v = array_shift($parameters); + } + + if (count($parameters) <= 0) { + break; + } + } + } + + // merge the remaining parameters + return array_merge($arguments, $parameters); + } + + private function canBeEchoed($var) + { + return method_exists($var, '__toString') || (is_scalar($var) && !is_null($var)); + } + + public function dispatch($instance = null) + { + is_null($instance) and $instance = new $this->class(); + + $param = $this->sortParameters(); + + ob_start(); + + if (empty($this->action) || trim($this->action) === '') { + // __invoke on a class + $result = call_user_func_array($instance, $param); } else { - $instance = new $action[0]($this->parameters); + $result = call_user_func_array(array($instance, $this->action), $param); + } + + if ($this->canBeEchoed($result)) { + echo $result; } + + $buffer = ob_get_clean(); + + return $buffer; } public function getAction() { return $this->action; } + + public function getClass() + { + return $this->class; + } }