/** * On application run * @param Application $application * * @throws BadRequestException */ public function run(Application $application) { $router = $application->getRouter(); $appRequest = $router->match($this->request); if (!$appRequest) { $this->checkAllowedMethods(); } }
public static function initialize(Nette\Application\Application $application, Nette\Http\IRequest $httpRequest) { Debugger::$bar->addPanel(new self($application->getRouter(), $httpRequest)); Debugger::$blueScreen->addPanel(function ($e) use($application) { if ($e === NULL) { return array('tab' => 'Nette Application', 'panel' => '<h3>Requests</h3>' . Nette\Diagnostics\Helpers::clickableDump($application->getRequests()) . '<h3>Presenter</h3>' . Nette\Diagnostics\Helpers::clickableDump($application->getPresenter())); } }); }
/** * @inheritDoc */ public function loadState(array $params) { if (!($request = $params['request'] ?? $this->application->getRouter()->match($httpRequest = $this->getHttpRequest()))) { $request = $this->application->getRouter()->match(new Nette\Http\Request(new Nette\Http\UrlScript($httpRequest->getUrl()->getBaseUrl()))); } if ($request) { $this->application->onRequest($this->application, $request); $params += $request->getParameters(); } try { parent::loadState($params); } catch (Nette\Application\BadRequestException $exception) { if (!$this->web) { $this->web = new Ytnuk\Web\Entity(); $this->web->menu = new Ytnuk\Menu\Entity(); } } }
/** * Registers translation micro presenter * which handles translation saves * * This method is called from $app->onStartup() event */ static function register(Nette\Application\Application $app) { if (isset(self::$registeredRoute)) { throw new Nette\InvalidStateException(__CLASS__ . "::register called twice?"); } $routeList = $app->getRouter(); self::$registeredRoute = new Nette\Application\Routers\Route('/<language [a-z]{2}>/vbuilder-translation-bar/<token [a-z0-9]{8}>', function (vBuilder\Localization\Translator $translator, Nette\Http\Session $session) use($app) { list($request) = $app->getRequests(); $dictionary = NULL; foreach ($translator->getDictionaries() as $name => $dict) { if ($name == 'translationBar') { $dictionary = $dict; break; } } if ($dictionary === NULL) { throw new Nette\InvalidStateException("Missing translationBar dictionary"); } if (!$dictionary->isFrozen()) { $dictionary->init($request->parameters['language']); } if (!$request->isPost()) { throw new Nette\Application\BadRequestException('Expected POST', 400); } // Check authorization token (basic CSRF prevention) $session = $session->getSection(strtr(__CLASS__, '\\', '.')); if (!isset($session->authToken) || $request->parameters['token'] != $session->authToken) { throw new Nette\Application\BadRequestException('Invalid token', 403); } // Process input $data = Nette\Utils\Json::decode(file_get_contents('php://input'), Nette\Utils\Json::FORCE_ARRAY); if (isset($data['translations'])) { foreach ($data['translations'] as $tr) { if (!isset($tr['key']) || !isset($tr['value'])) { continue; } $dictionary->addTranslation($tr['key'], (array) $tr['value']); } } // @note atomicity? $dictionary->save(); $payload = array('ok' => TRUE); return new Nette\Application\Responses\JsonResponse($payload); }); // Add our route as first $routeList[] = self::$registeredRoute; // Bypass the index check by expanding array for ($i = count($routeList) - 1; $i > 0; $i--) { $routeList[$i] = $routeList[$i - 1]; } $routeList[0] = self::$registeredRoute; }
/** * Request/URL factory. * @param PresenterComponent base * @param string destination in format "[[module:]presenter:]action" or "signal!" or "this" * @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 // cached services for better performance static $presenterFactory, $router, $refUrl; if ($presenterFactory === NULL) { $presenterFactory = $this->application->getPresenterFactory(); $router = $this->application->getRouter(); $refUrl = new Http\Url($this->httpRequest->getUrl()); $refUrl->setPath($this->httpRequest->getUrl()->getScriptPath()); } $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); // requires disabled magic quotes $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 Presenter || substr($destination, -1) === '!') { $signal = rtrim($destination, '!'); $a = strrpos($signal, ':'); if ($a !== FALSE) { $component = $component->getComponent(strtr(substr($signal, 0, $a), ':', '-')); $signal = (string) substr($signal, $a + 1); } if ($signal == NULL) { // intentionally == 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; $a = strrpos($destination, ':'); if ($a === FALSE) { $action = $destination === 'this' ? $this->action : $destination; $presenter = $this->getName(); $presenterClass = get_class($this); } else { $action = (string) substr($destination, $a + 1); if ($destination[0] === ':') { // absolute if ($a < 2) { throw new InvalidLinkException("Missing presenter name in '{$destination}'."); } $presenter = substr($destination, 1, $a - 1); } else { // relative $presenter = $this->getName(); $b = strrpos($presenter, ':'); if ($b === FALSE) { // no module $presenter = substr($destination, 0, $a); } else { // with module $presenter = substr($presenter, 0, $b + 1) . substr($destination, 0, $a); } } try { $presenterClass = $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 PresenterComponentReflection(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->name}::{$method}()"); } if ($args) { // convert indexed parameters to named self::argsToParams(get_class($component), $method, $args); } } // 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 PresenterComponentReflection($presenterClass); if ($args || $destination === 'this') { // 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."); } } elseif ($destination === 'this') { self::argsToParams($presenterClass, $method, $args, $this->params); } else { self::argsToParams($presenterClass, $method, $args); } } // 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(array($val)) !== (isset($tmp[$key]) ? http_build_query(array($tmp[$key])) : '')) { $current = FALSE; break; } } } $args += $globalState; } // 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->getParameter(self::FLASH_KEY); } $this->lastCreatedRequest = new Application\Request($presenter, Application\Request::FORWARD, $args, array(), array()); $this->lastCreatedRequestFlag = array('current' => $current); if ($mode === 'forward' || $mode === 'test') { return; } // CONSTRUCT URL $url = $router->constructUrl($this->lastCreatedRequest, $refUrl); 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 = $refUrl->getHostUrl() . '/'; if (strncmp($url, $hostUrl, strlen($hostUrl)) === 0) { $url = substr($url, strlen($hostUrl) - 1); } } return $url . $fragment; }
/** * Returns absolute URL for given resource path * * @internal * * @param string resource path * @param array of parameters * * @return string absolute url */ public function link($path = NULL, array $parameters = array()) { $r = new Nette\Application\Request($this->appRequest->getPresenterName(), $this->appRequest->getMethod(), array_merge(array('action' => 'default', self::PARAM_KEY_PATH => ltrim($path, '/')), $parameters)); return $this->application->getRouter()->constructUrl($r, $this->httpRequest->getUrl()); }