/** * Attempts to dispatch the supplied Route object. Returns false if it fails * @param Route $route * @throws classFileNotFoundException * @throws badClassNameException * @throws classNameNotFoundException * @throws classMethodNotFoundException * @throws classNotSpecifiedException * @throws methodNotSpecifiedException * @return mixed - result of controller method or FALSE on error */ public function dispatch(Route $route) { $class = trim($route->getMapClass()); $method = trim($route->getMapMethod()); $arguments = $route->getMapArguments(); if ('' === $class) { throw new classNotSpecifiedException('Class Name not specified'); } if ('' === $method) { throw new methodNotSpecifiedException('Method Name not specified'); } //Because the class could have been matched as a dynamic element, // it would mean that the value in $class is untrusted. Therefore, // it may only contain alphanumeric characters. Anything not matching // the regexp is considered potentially harmful. $class = str_replace('\\', '', $class); preg_match('/^[a-zA-Z0-9_]+$/', $class, $matches); if (count($matches) !== 1) { throw new badClassNameException('Disallowed characters in class name ' . $class); } //Apply the suffix $file_name = $this->classPath . $class . $this->suffix; $class = $class . str_replace('.php', '', $this->suffix); //At this point, we are relatively assured that the file name is safe // to check for it's existence and require in. if (FALSE === file_exists($file_name)) { throw new classFileNotFoundException('Class file not found'); } else { require_once $file_name; } //Check for the class class if (FALSE === class_exists($class)) { throw new classNameNotFoundException('class not found ' . $class); } //Check for the method if (FALSE === method_exists($class, $method)) { throw new classMethodNotFoundException('method not found ' . $method); } //All above checks should have confirmed that the class can be instatiated // and the method can be called $obj = new $class(); return call_user_func(array($obj, $method), $arguments); }
public function testMatchRegExpMap() { $route = new Route(); $route->setPath('/:class/:method/:id'); $route->addDynamicElement(':class', ':class'); $route->addDynamicElement(':method', ':method'); $route->addDynamicElement(':id', '^\\d{4}$'); $this->assertTrue($route->matchMap('/someclass/somemethod/1234')); $this->assertTrue($route->matchMap('/someclass/somemethod/0234')); $this->assertFalse($route->matchMap('/someclass/somemethod/12345')); $this->assertFalse($route->matchMap('/someclass/somemethod/abc')); $this->assertFalse($route->matchMap('/someclass/somemethod/')); $this->assertFalse($route->matchMap('/someclass/somemethod')); $route = new Route(); $route->setPath('/:class/:method/:id'); $route->addDynamicElement(':class', '^startWith'); $route->addDynamicElement(':method', 'endsIn$'); $route->addDynamicElement(':id', '^\\d{4}$'); $route_result = $route->matchMap('/startWith_/_endsIn/1234'); $this->assertTrue($route_result); $this->assertSame('startWith_', $route->getMapClass()); $this->assertSame('_endsIn', $route->getMapMethod()); }