Vlastní router – definice

Pepino
Člen | 245
+
+1
-

Zdravím, potřeboval bych poradit s definicí pro vlastní router.

O co mi jde: Chci mít routy pro kategorie např: kategorie/podkategorie/podpodkategorie/ ale zároveň chci mít možnost v těch kategoriích filtrovat přes url kategorie/podkategorie/p_10:25:65/d_11:18/u_222:455/

Ty dvojtečky jsou oddělovače jednotlivých ID „parametrů“. Může se filtrovat podle jedné vlastnosti nebo několika.

Kód je následující:

public function __construct($storage) {

    parent::__construct('https://%host%/[<presenter>/][<action>/][<id>/]<slug .+>[/p_<parameter_filters>][/d_<depth_filters>][/u_<user_filters>]', array(
        'slug' => [
            Route::VALUE => null,
            Route::FILTER_IN => null,
            Route::FILTER_OUT => null,
        ],
        'parameter_filters' => null,
        'depth_filters' => null,
        'user_filters' => null,
        'presenter' => self::DEFAULT_PRESENTER,
        'action' => self::DEFAULT_ACTION,
        'id' => self::DEFAULT_ID,
    ));

}

Díky za každý tip.

duke
Člen | 650
+
0
-

Pro složitější logiku routování (kde se parametry vzájemně ovlivňují – např. kde se dle slugu určuje presenter a akce) lze použít globální filtry.
Předně bys měl zajistit, aby routa byla jednoznačná (aby bylo např. jasné, co je presenter/akce/id a co slug – to lze také řešit globálními filtry).

Pepino
Člen | 245
+
0
-

duke napsal(a):

Pro složitější logiku routování (kde se parametry vzájemně ovlivňují – např. kde se dle slugu určuje presenter a akce) lze použít globální filtry.
Předně bys měl zajistit, aby routa byla jednoznačná (aby bylo např. jasné, co je presenter/akce/id a co slug – to lze také řešit globálními filtry).

Můžeš mě nakopnout kouskem konkrétního kódu? Není mi to úplně jasné jak to funguje.

duke
Člen | 650
+
0
-

V rychosti něco jako (netestováno):

$frontModule[] = new Route('<slug>[/p_<parameter_filters>][/d_<depth_filters>][/u_<user_filters>]', [
    'presenter' => 'Homepage',
    'action' => 'default',
    'slug' => [
        Route::FILTER_OUT => null,
        Route::PATTERN => '.*'
    ],
    null => [
        Route::FILTER_IN => function (array $params) use ($slugResolver) {
			// podle $params['slug'] vrátí modifikované $params
			// (obsahující klíče 'presenter', 'action', případně 'id' a další) nebo null v případě, že daný slug neexistuje
            return $slugResolver->filterIn($params);
        },
		Route::FILTER_OUT => function (array $params) use ($slugResolver) {
			// podle $params['presenter'], $params['action'] a $params['id'] vrátí modifikované $params
			// (obsahující klíč 'slug') nebo null v případě, že slug pro dané parametry neexistuje
			return $slugResolver->filterOut($params);
		}
    ],
]);
duke
Člen | 650
+
0
-

Ještě je tam tedy problém v tom, že parametr <slug> nyní pohltí i případné další parametry jako "/p-foo/d-bar/u-baz". To lze řešit buď změnou reguláru z '.*' na něco striktnějšího, nebo je možné provést parsování těchto parametrů až v globálním vstupním filtru (vyextrahovat je z $params['slug'], ten modifikovat a nastavit případně $params['parameter_filters'] atd.).

Editoval duke (10. 7. 2018 14:11)