Tovrba vlastního routeru – nedokáže tytvořit URL pro jakýkoliv presenter krom defaultu
- Tirus91
- Člen | 199
Ahoj,
narazil jsem na situaci, kdy si musím sepsat vlastní router, ovšem nestále
se mi nedaří.
V tuto chvíli mi přistoupí na http://xxx.cc/ a dostanu chybu
Invalid link: No route for Front:Sign:up(locale=cs)
V případě, že přistoupím na http://xxx.cc/prihlasit tak mi to nematchne správě, jelikož není údajně vyplněn $locale (persistentní) a to i když mám výchozí hodnotu dle nastavení v administraci (cs|en|…), ale když dám http://xxx.cc/cs/prihlasit, tak to najede, ale opět nesestaví URL pro Front:Sign:*
<?php
namespace Tirus\Routers;
use Nette\Application\Request;
use Nette\Application\Routers\Route;
use Nette\Http\IRequest;
use Nette\Http\Url;
use \Tracy\Debugger;
class FrontRoute extends Route {
const CACHE = 'Tirus.routing';
const DEFAULT_MODULE = 'Front';
const DEFAULT_PRESENTER = 'Homepage';
const DEFAULT_ACTION = 'default';
/** @var \Tirus\Models\LanguageModel */
private $languageModel;
/** @var \Nette\Database\Table\ActiveRow */
private $defaultLanguage;
/** @var \Tirus\Models\RouteModel */
private $routeModel;
/**
* @param \Tirus\Models\RouteModel $routeModel
*/
public function __construct(\Tirus\Models\RouteModel $routeModel, \Nette\Database\Table\ActiveRow $defaultLang, \Tirus\Models\LanguageModel $langModel) {
$this->routeModel = $routeModel;
$this->defaultLanguage = $defaultLang;
$this->languageModel = $langModel;
parent::__construct('<locale=' . $defaultLang->code . ' [a-z]{2}>/<slug .+>', array(
'presenter' => self::DEFAULT_PRESENTER,
'module' => self::DEFAULT_MODULE,
'action' => self::DEFAULT_ACTION,
'locale' => $defaultLang->code,
'slug' => array(
self::VALUE => '',
self::FILTER_IN => null,
self::FILTER_OUT => null,
),
));
}
/**
* @param \Nette\Http\IRequest
* @return \Nette\Application\Request|NULL
*/
public function match(IRequest $httpRequest) {
if (($appRequest = parent::match($httpRequest)) === null) {
return null;
}
$parameters = $appRequest->getParameters();
if (!array_key_exists('slug', $parameters) || ($page = $this->findPageMatch($parameters)) === null) {
return null;
}
if ($page['module'] != self::DEFAULT_MODULE) {
return null;
}
unset($parameters['action'], $parameters['locale']);
$request = new \Nette\Application\Request(
$page['module'] . ':' . $page['presenter'], $httpRequest->getMethod(), $parameters + array(
'slug' => $page['param_id'],
'action' => $page['action'],
'locale' => $page['language']
), $httpRequest->getPost(), $httpRequest->getFiles(), array(\Nette\Application\Request::SECURED => $httpRequest->isSecured())
);
return $request;
}
/**
* @param \Nette\Application\Request
* @param \Nette\Http\Url
* @return string|NULL
*/
public function constructUrl(Request $appRequest, Url $refUrl) {
$parameters = $appRequest->getParameters();
$pageId = null;
Debugger::barDump($parameters, '$parameters');
if (isset($parameters['slug'])) {
$pageId = $parameters['slug'];
unset($parameters['slug']);
}
Debugger::barDump($pageId, 'pageId');
$lang = $this->defaultLanguage->code;
if (isset($parameters['locale'])) {
$lang = $parameters['locale'] !== null ? $parameters['locale'] : $this->defaultLanguage->code;
unset($parameters['locale']);
}
Debugger::barDump($lang, 'lang');
$route = clone($this->routeModel);
$tmp = explode(':', $appRequest->getPresenterName());
Debugger::barDump($appRequest->presenterName,'PP');
Debugger::barDump($tmp);
$presenter = $tmp[1];
$languageModel = clone($this->languageModel);
$lan = $languageModel->getByCode($lang);
$page = $route->findAll()
->where('param_id', $pageId)
->where('module', self::DEFAULT_MODULE)
->where('presenter', $presenter)
->where('action', $parameters['action'])
->where('language_id IS NULL OR language_id ', $lan->id)
->order('id DESC')
->fetch();
if (!$page) {
Debugger::barDump($parameters, '!$parameters');
$page = $route->findAll()
->where('param_id', null)
->where('module', self::DEFAULT_MODULE)
->where('presenter', self::DEFAULT_PRESENTER)
->where('action', self::DEFAULT_ACTION)
->where('language_id IS NULL OR language_id ', $lan->id)
->order('id DESC')
->fetch();
}
unset($parameters['action']);
$par = array(
'module' => self::DEFAULT_MODULE,
'presenter' => $page->presenter,
'action' => $page->action,
'slug' => $page->slug,
'locale' => $lan->code
) + $parameters;
Debugger::barDump($par, 'PAR');
$appRequest->setPresenterName(self::DEFAULT_MODULE . ':' . $page->presenter);
$appRequest->setParameters($par);
Debugger::barDump(parent::constructUrl($appRequest, $refUrl), 'URL');
return parent::constructUrl($appRequest, $refUrl);
}
/**
* @param $parameters
* @return mixed[]|null
*/
private function findPageMatch($parameters) {
$lang = isset($parameters['locale']) && $parameters['locale'] !== null ? $parameters['locale'] : $this->defaultLanguage->code;
$route = clone($this->routeModel);
$page = $route
->findBySlug((string) $parameters['slug']);
if (count($page->count()) == 1) {
$page = $page->fetch();
if ($page) {
return $this->getPageArray($page);
}
return null;
}
$route = clone($this->routeModel);
$languageModel = clone($this->languageModel);
$page = $route->
findAll()
->where('slug', (string) $parameters['slug'])
->where('module', self::DEFAULT_MODULE)
->where('language_id', $languageModel->getByCode($this->defaultLanguage->code)->id)
->order('id DESC')
->fetchAll();
$page = $page->fetch();
if ($page) {
return $this->getPageArray($page);
}
return null;
}
private function getPageArray(\Nette\Database\Table\ActiveRow $page) {
$pageArray = $page->toArray();
if ($page->language_id == null) {
$pageArray['language'] = $this->defaultLanguage->code;
} else {
$lang = clone($this->languageModel);
$pageArray['language'] = $lang->findById($page->language_id)->code;
}
return $pageArray;
}
}
Jinak, při sestavování té URL se nic nedostane do metody constructUrl
Samotnýt RouteFactory je
<?php
namespace App;
use \Nette\Application\Routers\Route,
\Nette\Application\Routers\RouteList,
\Tirus\Routers;
/**
* Router factory.
*/
class RouterFactory {
private $routeModel;
private $defaultLang;
private $languageModel;
public function __construct(\Tirus\Models\RouteModel $routeModel, \Tirus\Models\LanguageModel $langModel, \Tirus\Models\SystemModel $systemModel) {
$this->routeModel = $routeModel;
$this->defaultLang = $systemModel->getCurrent()->language;
$this->languageModel = $langModel;
}
/**
* @return \Nette\Application\IRouter
*/
public function createRouter() {
$router = new RouteList();
$router[] = new Routers\FrontRoute($this->routeModel, $this->defaultLang, $this->languageModel);
$router[] = new Route('index.php', 'Front:Default:default', Route::ONE_WAY);
return $router;
}
Nette je 2.3.0
Editoval Tirus91 (8. 3. 2015 18:27)
- Tirus91
- Člen | 199
Takže stačilo upravit volání
parent::__construct('[<locale=' . $defaultLang->code . ' [a-z]{2}>/]<slug>[/<presenter>[/<action>]]', array(
'presenter' => self::DEFAULT_PRESENTER,
'module' => self::DEFAULT_MODULE,
'action' => self::DEFAULT_ACTION,
'locale' => $defaultLang->code,
'slug' => array(
self::VALUE => null,
self::FILTER_IN => null,
self::FILTER_OUT => null,
),
));
v tuto chvíli to již generuje odkazy, ovšem problém nastává, že to tam dává i presenter a action. Vyřešil jsem to str_replace(), ale to mi nepříjde nejlepší řešení