示例#1
0
 /**
  * @param  string  URL mask, e.g. '<presenter>/<action>/<id \d{1,3}>'
  * @param  array|string|\Closure  default values or metadata or callback for NetteModule\MicroPresenter
  * @param  int     flags
  */
 public function __construct($mask, $metadata = [], $flags = 0)
 {
     if (is_string($metadata)) {
         list($presenter, $action) = Nette\Application\Helpers::splitName($metadata);
         if (!$presenter) {
             throw new Nette\InvalidArgumentException("Second argument must be array or string in format Presenter:action, '{$metadata}' given.");
         }
         $metadata = [self::PRESENTER_KEY => $presenter];
         if ($action !== '') {
             $metadata['action'] = $action;
         }
     } elseif ($metadata instanceof \Closure || $metadata instanceof Nette\Callback) {
         if ($metadata instanceof Nette\Callback) {
             trigger_error('Nette\\Callback is deprecated, use Nette\\Utils\\Callback::closure().', E_USER_DEPRECATED);
         }
         $metadata = [self::PRESENTER_KEY => 'Nette:Micro', 'callback' => $metadata];
     }
     $this->flags = $flags | static::$defaultFlags;
     $this->setMask($mask, $metadata);
     if (static::$defaultFlags) {
         trigger_error('Route::$defaultFlags is deprecated, router by default keeps the used protocol.', E_USER_DEPRECATED);
     } elseif ($flags & self::SECURED) {
         trigger_error('Router::SECURED is deprecated, specify scheme in mask.', E_USER_DEPRECATED);
         $this->scheme = 'https';
     }
 }
示例#2
0
 public function run(Nette\Application\Request $request)
 {
     $exception = $request->getParameter('exception');
     if ($exception instanceof Nette\Application\BadRequestException) {
         list($module, , $sep) = Nette\Application\Helpers::splitName($request->getPresenterName());
         return new Responses\ForwardResponse($request->setPresenterName($module . $sep . 'Error4xx'));
     }
     $this->logger->log($exception, ILogger::EXCEPTION);
     return new Responses\CallbackResponse(function () {
         require __DIR__ . '/templates/Error/500.phtml';
     });
 }
示例#3
0
 /**
  * @return Nette\Application\IResponse
  */
 public function run(Nette\Application\Request $request)
 {
     $e = $request->getParameter('exception');
     if ($e instanceof Nette\Application\BadRequestException) {
         // $this->logger->log("HTTP code {$e->getCode()}: {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", 'access');
         list($module, , $sep) = Nette\Application\Helpers::splitName($request->getPresenterName());
         return new Responses\ForwardResponse($request->setPresenterName($module . $sep . 'Error4xx'));
     }
     $this->logger->log($e, ILogger::EXCEPTION);
     return new Responses\CallbackResponse(function () {
         require __DIR__ . '/templates/Error/500.phtml';
     });
 }
示例#4
0
 /**
  * Maps command line arguments to a Request object.
  * @return Nette\Application\Request|NULL
  */
 public function match(Nette\Http\IRequest $httpRequest)
 {
     if (empty($_SERVER['argv']) || !is_array($_SERVER['argv'])) {
         return NULL;
     }
     $names = [self::PRESENTER_KEY];
     $params = $this->defaults;
     $args = $_SERVER['argv'];
     array_shift($args);
     $args[] = '--';
     foreach ($args as $arg) {
         $opt = preg_replace('#/|-+#A', '', $arg);
         if ($opt === $arg) {
             if (isset($flag) || ($flag = array_shift($names))) {
                 $params[$flag] = $arg;
             } else {
                 $params[] = $arg;
             }
             $flag = NULL;
             continue;
         }
         if (isset($flag)) {
             $params[$flag] = TRUE;
             $flag = NULL;
         }
         if ($opt !== '') {
             $pair = explode('=', $opt, 2);
             if (isset($pair[1])) {
                 $params[$pair[0]] = $pair[1];
             } else {
                 $flag = $pair[0];
             }
         }
     }
     if (!isset($params[self::PRESENTER_KEY])) {
         throw new Nette\InvalidStateException('Missing presenter & action in route definition.');
     }
     list($module, $presenter) = Nette\Application\Helpers::splitName($params[self::PRESENTER_KEY]);
     if ($module !== '') {
         $params[self::PRESENTER_KEY] = $presenter;
         $presenter = $module;
     }
     return new Application\Request($presenter, 'CLI', $params);
 }
示例#5
0
 /**
  * @param  array   default values
  * @param  int     flags
  */
 public function __construct($defaults = [], $flags = 0)
 {
     if (is_string($defaults)) {
         list($presenter, $action) = Nette\Application\Helpers::splitName($defaults);
         if (!$presenter) {
             throw new Nette\InvalidArgumentException("Argument must be array or string in format Presenter:action, '{$defaults}' given.");
         }
         $defaults = [self::PRESENTER_KEY => $presenter, 'action' => $action === '' ? Application\UI\Presenter::DEFAULT_ACTION : $action];
     }
     if (isset($defaults[self::MODULE_KEY])) {
         $this->module = $defaults[self::MODULE_KEY] . ':';
         unset($defaults[self::MODULE_KEY]);
     }
     $this->defaults = $defaults;
     $this->flags = $flags;
     if ($flags & self::SECURED) {
         trigger_error('IRouter::SECURED is deprecated, router by default keeps the used protocol.', E_USER_DEPRECATED);
     }
 }
示例#6
0
 /**
  * Formats view template file names.
  * @return array
  */
 public function formatTemplateFiles()
 {
     list(, $presenter) = \Nette\Application\Helpers::splitName($this->getName());
     $dir = dirname($this->getReflection()->getFileName());
     $dir = is_dir("{$dir}/Templates") ? $dir : dirname($dir);
     return ["{$dir}/Templates/{$presenter}/{$this->view}.latte"];
 }
示例#7
0
 /**
  * Request/URL factory.
  * @param  Component  base
  * @param  string   destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]"
  * @param  array    array of arguments
  * @param  string   forward|redirect|link
  * @return string   URL
  * @throws InvalidLinkException
  * @internal
  */
 protected function createRequest($component, $destination, array $args, $mode)
 {
     // note: createRequest supposes that saveState(), run() & tryCall() behaviour is final
     $this->lastCreatedRequest = $this->lastCreatedRequestFlag = NULL;
     // PARSE DESTINATION
     // 1) fragment
     $a = strpos($destination, '#');
     if ($a === FALSE) {
         $fragment = '';
     } else {
         $fragment = substr($destination, $a);
         $destination = substr($destination, 0, $a);
     }
     // 2) ?query syntax
     $a = strpos($destination, '?');
     if ($a !== FALSE) {
         parse_str(substr($destination, $a + 1), $args);
         $destination = substr($destination, 0, $a);
     }
     // 3) URL scheme
     $a = strpos($destination, '//');
     if ($a === FALSE) {
         $scheme = FALSE;
     } else {
         $scheme = substr($destination, 0, $a);
         $destination = substr($destination, $a + 2);
     }
     // 4) signal or empty
     if (!$component instanceof self || substr($destination, -1) === '!') {
         list($cname, $signal) = Helpers::splitName(rtrim($destination, '!'));
         if ($cname !== '') {
             $component = $component->getComponent(strtr($cname, ':', '-'));
         }
         if ($signal === '') {
             throw new InvalidLinkException('Signal must be non-empty string.');
         }
         $destination = 'this';
     }
     if ($destination == NULL) {
         // intentionally ==
         throw new InvalidLinkException('Destination must be non-empty string.');
     }
     // 5) presenter: action
     $current = FALSE;
     list($presenter, $action) = Helpers::splitName($destination);
     if ($presenter === '') {
         $action = $destination === 'this' ? $this->action : $action;
         $presenter = $this->getName();
         $presenterClass = get_class($this);
     } else {
         if ($presenter[0] === ':') {
             // absolute
             $presenter = substr($presenter, 1);
             if (!$presenter) {
                 throw new InvalidLinkException("Missing presenter name in '{$destination}'.");
             }
         } else {
             // relative
             list($module, , $sep) = Helpers::splitName($this->getName());
             $presenter = $module . $sep . $presenter;
         }
         if (!$this->presenterFactory) {
             throw new Nette\InvalidStateException('Unable to create link to other presenter, service PresenterFactory has not been set.');
         }
         try {
             $presenterClass = $this->presenterFactory->getPresenterClass($presenter);
         } catch (Application\InvalidPresenterException $e) {
             throw new InvalidLinkException($e->getMessage(), NULL, $e);
         }
     }
     // PROCESS SIGNAL ARGUMENTS
     if (isset($signal)) {
         // $component must be IStatePersistent
         $reflection = new ComponentReflection(get_class($component));
         if ($signal === 'this') {
             // means "no signal"
             $signal = '';
             if (array_key_exists(0, $args)) {
                 throw new InvalidLinkException("Unable to pass parameters to 'this!' signal.");
             }
         } elseif (strpos($signal, self::NAME_SEPARATOR) === FALSE) {
             // counterpart of signalReceived() & tryCall()
             $method = $component->formatSignalMethod($signal);
             if (!$reflection->hasCallableMethod($method)) {
                 throw new InvalidLinkException("Unknown signal '{$signal}', missing handler {$reflection->getName()}::{$method}()");
             }
             // convert indexed parameters to named
             self::argsToParams(get_class($component), $method, $args, [], $missing);
         }
         // counterpart of IStatePersistent
         if ($args && array_intersect_key($args, $reflection->getPersistentParams())) {
             $component->saveState($args);
         }
         if ($args && $component !== $this) {
             $prefix = $component->getUniqueId() . self::NAME_SEPARATOR;
             foreach ($args as $key => $val) {
                 unset($args[$key]);
                 $args[$prefix . $key] = $val;
             }
         }
     }
     // PROCESS ARGUMENTS
     if (is_subclass_of($presenterClass, __CLASS__)) {
         if ($action === '') {
             $action = self::DEFAULT_ACTION;
         }
         $current = ($action === '*' || strcasecmp($action, $this->action) === 0) && $presenterClass === get_class($this);
         $reflection = new ComponentReflection($presenterClass);
         // counterpart of run() & tryCall()
         $method = $presenterClass::formatActionMethod($action);
         if (!$reflection->hasCallableMethod($method)) {
             $method = $presenterClass::formatRenderMethod($action);
             if (!$reflection->hasCallableMethod($method)) {
                 $method = NULL;
             }
         }
         // convert indexed parameters to named
         if ($method === NULL) {
             if (array_key_exists(0, $args)) {
                 throw new InvalidLinkException("Unable to pass parameters to action '{$presenter}:{$action}', missing corresponding method.");
             }
         } else {
             self::argsToParams($presenterClass, $method, $args, $destination === 'this' ? $this->params : [], $missing);
         }
         // counterpart of IStatePersistent
         if ($args && array_intersect_key($args, $reflection->getPersistentParams())) {
             $this->saveState($args, $reflection);
         }
         if ($mode === 'redirect') {
             $this->saveGlobalState();
         }
         $globalState = $this->getGlobalState($destination === 'this' ? NULL : $presenterClass);
         if ($current && $args) {
             $tmp = $globalState + $this->params;
             foreach ($args as $key => $val) {
                 if (http_build_query([$val]) !== (isset($tmp[$key]) ? http_build_query([$tmp[$key]]) : '')) {
                     $current = FALSE;
                     break;
                 }
             }
         }
         $args += $globalState;
     }
     if ($mode !== 'test' && !empty($missing)) {
         foreach ($missing as $rp) {
             if (!array_key_exists($rp->getName(), $args)) {
                 throw new InvalidLinkException("Missing parameter \${$rp->getName()} required by {$rp->getDeclaringClass()->getName()}::{$rp->getDeclaringFunction()->getName()}()");
             }
         }
     }
     // ADD ACTION & SIGNAL & FLASH
     if ($action) {
         $args[self::ACTION_KEY] = $action;
     }
     if (!empty($signal)) {
         $args[self::SIGNAL_KEY] = $component->getParameterId($signal);
         $current = $current && $args[self::SIGNAL_KEY] === $this->getParameter(self::SIGNAL_KEY);
     }
     if (($mode === 'redirect' || $mode === 'forward') && $this->hasFlashSession()) {
         $args[self::FLASH_KEY] = $this->getFlashKey();
     }
     $this->lastCreatedRequest = new Application\Request($presenter, Application\Request::FORWARD, $args, [], []);
     $this->lastCreatedRequestFlag = ['current' => $current];
     if ($mode === 'forward' || $mode === 'test') {
         return;
     }
     // CONSTRUCT URL
     if ($this->refUrlCache === NULL) {
         $this->refUrlCache = new Http\Url($this->httpRequest->getUrl());
         $this->refUrlCache->setPath($this->httpRequest->getUrl()->getScriptPath());
     }
     if (!$this->router) {
         throw new Nette\InvalidStateException('Unable to generate URL, service Router has not been set.');
     }
     $url = $this->router->constructUrl($this->lastCreatedRequest, $this->refUrlCache);
     if ($url === NULL) {
         unset($args[self::ACTION_KEY]);
         $params = urldecode(http_build_query($args, NULL, ', '));
         throw new InvalidLinkException("No route for {$presenter}:{$action}({$params})");
     }
     // make URL relative if possible
     if ($mode === 'link' && $scheme === FALSE && !$this->absoluteUrls) {
         $hostUrl = $this->refUrlCache->getHostUrl() . '/';
         if (strncmp($url, $hostUrl, strlen($hostUrl)) === 0) {
             $url = substr($url, strlen($hostUrl) - 1);
         }
     }
     return $url . $fragment;
 }