Jak na callbacky pro filter in/out
- akadlec
- Člen | 1326
Jak korektně udělat callbacky pro filtry rout? Potřebuji překládat IDčka na SLUGy a naopak. V routě mám zaregistrované callbacky na statické funkce, ale tam se potřebuji dostat k fasádě abych se dostal k datům v db. Prozatím to řeším takto neštastně:
class FoldersRouter
{
/**
* @param string $slug
*
* @return int|bool
*/
public static function getFolderIdBySlug($slug)
{
// Check if slug is string...
if ( is_numeric($slug) ) {
// ...then convert is not necessary
return $slug;
}
// Get module facade
$folderFacade = \Nette\Environment::getService('mailboxModule.folderFacade');
if ( $folderEntity = $folderFacade->findOneBySlug((string) $slug) ) {
return $folderEntity->getId();
}
return FALSE;
}
/**
* @param int $id
*
* @return string|bool
*/
public static function getFolderSlugById($id)
{
// Check if identifier is string
if ( is_string($id) ) {
// ...then convert is not necessary
return $id;
}
// Get module facade
$folderFacade = \Nette\Environment::getService('mailboxModule.folderFacade');
if ( $folderEntity = $folderFacade->findOneByIdentifier((int) $id) ) {
return $folderEntity->getSlug();
}
return FALSE;
}
}
jako korektně nahradit \Nette\Environment ?
- jiri.pudil
- Nette Blogger | 1029
Co takhle mít tyhle metody v nějaké službě, aby sis do ní mohl injectnout závislosti? Tu službu samotnou si pak injectneš do RouterFactory a callback napíšeš nestaticky.
- akadlec
- Člen | 1326
No právě že routy se registrují v ModuleExtension jako RoutesDefinition takže když se definuje callback tak toho k dispozici moc není.
class MailboxModuleExtension extends NamedExtension implements IRouterProvider
{
public function getRoutesDefinition()
{
$list[] = new NetteRouteMock('//app.[!<domain [a-zA-Z0-9-]+>].[!<tld [a-zA-Z0-9-]+>]/[!<locale [a-z]{2,4}>/]mailbox[/<mailbox>]', array(
'module' => 'Application',
'presenter' => 'Default',
'action' => 'default',
'mailbox' => array(
Route::FILTER_OUT => 'FoldersRouter::getFolderSlugById',
Route::FILTER_IN => 'FoldersRouter::getFolderIdBySlug'
),
'locale' => array(
Route::VALUE => 'en',
'fixity' => Route::CONSTANT,
)
));
}
}
Editoval akadlec (4. 3. 2014 9:33)
- David Grudl
- Nette Core | 8218
Překládat v routách ID na SLUG a obráceně je nesmysl. Pokud chci používat slugy, tak prostě používám v odkazech slugy, a ne ID. Jaký má smysl dávat do odkazů ID, když je pak musím převádět? Převádění znamená hromadu neoptimálních dotazů na databázi, úplně zbytečných.
Navíc ID a slug nejsou ekvivalentní identifikátory. ID je identifikátor, který se z principu nemění. Slug se měnit může. Potom ale musím zachovat funkčnost i pro původní slugy, pro které si vytvořím další databázovou tabulku, a musím zajistit přesměrování na aktuální slug. Což ovšem není úkol pro router, nýbrž presenter.
- enumag
- Člen | 2118
Překládat v routách ID na SLUG a obráceně je nesmysl.
+1
Pokud chci používat slugy, tak prostě používám v odkazech slugy, a ne ID.
-1
, když vytvářím odkaz tak nechci vědět nic o tom zda
v reálné URL je ID nebo slug, chci aby mě routování přesně od těchto
věcí odstínilo
Editoval enumag (4. 3. 2014 14:48)
- Majkl578
- Moderator | 1364
když vytvářím odkaz tak nechci vědět nic o tom zda v reálné URL je ID nebo slug, chci aby mě routování přesně od těchto věcí odstínilo
Souhlas.
Převádění znamená hromadu neoptimálních dotazů na databázi, úplně zbytečných.
To je velmi relativní a obecně neplatné tvrzení. Záleží totiž na implementaci, která může i nemusí mít tento zmíněný vedlejší efekt.
Potom ale musím zachovat funkčnost i pro původní slugy, pro které si vytvořím další databázovou tabulku, a musím zajistit přesměrování na aktuální slug. Což ovšem není úkol pro router, nýbrž presenter.
To přeci nyní řeší kanonizace v presenteru.
- akadlec
- Člen | 1326
jejda pánové, tak mě v tom děláte hokej ;) tento můj případ je zatím v ovládacím rozhraní kde není nutné zachovávat staré url tvary, jen jde o „hezké“ url. Faktem je že SLUG mám k dispozici a tak je možné jej přímo do linku házet, pak si ale zase musím poupravit trycall co mě do action* render* handle* rovnou předává objekty které hledá nad entitou podle ID.
- David Grudl
- Nette Core | 8218
enumag napsal(a):
když vytvářím odkaz tak nechci vědět nic o tom zda v reálné URL je ID nebo slug, chci aby mě routování přesně od těchto věcí odstínilo
Pak je rozumným kompromisem nepředávat ani ID, ani slug, ale rovnou entitu, ze které si routa vybere, co potřebuje.
- akadlec
- Člen | 1326
no abych pravdu řek tak nijak, stále tam mám statické classy.
jen bych teda doplnil co bylo uvedeno výše že by se měla rovnou předat entita…ono v podstatě i to je možnost, mě jen ten callback vyhodnotí co bylo předáno, když entita, tak se jednoduše z ní vytáhne slug a když se předalo ID tak se vytáhne entita z db a veme její slug atd…teoreticky bych se toho statického načtení služby dokázal zbavit.
- Tomáš Votruba
- Moderator | 1114
@akadlec Pokud bys chtěl odstranit statické classy, poslal jsem PR do Flame\Modules, který umožňuje použití služeb v routách.