Routování domény 3tího řádu

ondraLE
Člen | 18
+
0
-

Ahoj, mám projekt, který má jednotlivé „klienty“ rozhozeny dle domény 3tího řádu, např klient1.domena.cz, a klient2.domena.cz.
V routeru mám funkční nastavení takto:

$router->addRoute('<locale>/<module>/<presenter>/<action>[/<id>]', [
            'locale' => [
                Route::Value => 'cs',
                Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
            ],
            'module' => 'Basic',
            'presenter' => 'Home',
            'action' => 'default',
            'id' => null,
        ]);

pokud bych chtěl dle návodu přidat rozlišení domény, zkoušel jsem toto, ale pokaždé route not found:

$router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', [
            'locale' => [
                Route::Value => 'cs',
                Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
            ],
			'client' => 'Defaultclient',
            'module' => 'Basic',
            'presenter' => 'Home',
            'action' => 'default',
            'id' => null,
        ]);

Tušíte kde je problém?

Pak druhá věc, pokud se rozběhne správné routování a identifikace klienta, potřebuji aby např. obrázky typu .jpg, se automaticky načítaly z jiné složky. Fyzicky jsou uloženy v appDir/files/{client}/cokoli.jpg,
routa:

$router->withPath("files")->addRoute("[<folder>/]<filename>", function ($filename, $folder = ""){
            echo $filename. "- ".$folder."\n";
        });

Zde bude stačit přímo načíst readfile z dané složky a poslat? Tedy hledal bych file: www/files/{client}/{folder}/{filename} nebo je
lepší na soubor provést redirect? Jde mi o to, že pokud jsou připojeny např. obrázky, aby fyzická cesta k souboru byla „schována“ za tento formát.
Díky za rady.

m.brecher
Generous Backer | 761
+
+1
-

@ondraLE

pokaždé route not found:

Zkus vynechat to zpětné lomítko:

// tvůj kód
$router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

// zkus toto:
$router->addRoute('<client>.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

// nebo natvrdo doménu:
$router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
ondraLE
Člen | 18
+
0
-

m.brecher napsal(a):

// tvůj kód
$router->addRoute('<client>\.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

// zkus toto:
$router->addRoute('<client>.%domain%/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

// nebo natvrdo doménu:
$router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

lomítko nepomohlo, nemůže to být tím, že tam mám ještě číslo portu? běží mi to na 8888 a localhostu, tak nevím, zda správně přeloží %domain% i jako localhost

Editoval ondraLE (16. 4. 8:08)

m.brecher
Generous Backer | 761
+
-2
-

@ondraLE

běží mi to na 8888 a localhostu

Jestli to provozuješ na lokálním serveru, tak tam subdoménu asi nastavit nepůjde. Tam můžeš mít jenom http://localhost/… Můžeš to zkusit vyřešit tak, že si uděláš dvě různé routy pro lokální vývoj a pro produkční nasazení – cca nějak takto:

if($_SERVER['REMOTE_ADDR'] === '127.0.0.1'){
    router->addRoute('<client>/<locale>/<module>/<presenter>/<action>[/<id>]', .....)

}else{
    router->addRoute('<client>.mojedomena.cz/<locale>/<module>/<presenter>/<action>[/<id>]', .....)
}
ondraLE
Člen | 18
+
0
-

perfekt, to funguje, díky! a pak mám poslední dotaz. dělám projekt, který bude mít admin sekci, v url /admin/{jazyk}/modul/presenter/action
např. http://localhost:8888/admin/cs/cms/menu/, zároveň frontend, kde cokoli za lomítkem (nebude-li /admin) mi hodí na frontend presenter, modulu front.

mám common.neon mapping takto:

    mapping:
        Front: App\Module\Front\Presenters\*Presenter
        *: App\Module\Admin\*\Presenters\*Presenter

router:

public static function createRouter(): RouteList
    {
        $router = new RouteList;

        $router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]', [
            'locale' => [
                Route::Value => 'cs',
                Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
            ],
            'module' => 'Basic',
            'presenter' => 'Home',
            'action' => 'default',
            'id' => null,
        ]);
        $router->withModule("Front")->addRoute('<locale>/<link>[/<id>]', [
            'locale' => [
                Route::Value => 'cs',
                Route::FilterIn => fn($locale) =>!is_null($locale) ? $locale : 'cs',
            ],
            'link' => 'Home',
            'presenter' => 'Frontend',
            'action' => 'default',
            'id' => null,
        ]);
        return $router;
    }

Potíž je v tom, že když zavolám localhost:8888/admin/cs/cms/menu/ správně do jde na routu admin a vše funguje,
pokud zavolám: localhost:8888/cs/test , skočí mi to sice na správný frontend presenter, ale URL přesměruje na admin:
localhost:8888/admin/cs/front/frontend/?link=test, netuším proč to přesměrovává.

update:
pokud přehodím pořadí rout, a upravím tu veřejnou takto:
$router->withModule("Front")->addRoute('<locale>/<link[test]>[/<id>]', [... tak to sice funguje jak má, nicméně posílá se mi pak parametr link[admin]=test, viz:

Front:Frontend:default
locale = cs
link[admin] = test
link = Home
id = null

Editoval ondraLE (16. 4. 21:20)

m.brecher
Generous Backer | 761
+
+1
-

@ondraLE

netuším proč to přesměrovává. Byla by rada?

Routy Nette jsou v tomhle trochu záludné. Nette totiž aplikuje dvě různá pravidla po sobě, a člověka občas překvapí právě takovéto přesměrování. První pravidlo je – první routa která matchne url se použije. Druhé pravidlo je, že presenter získaný request ověřuje na duplicitu a zkusí z něj LinkGenerátorem vygenerovat link. Pokud se liší od původního url, přesměruje na něj – je to totiž kanonické url.

A když se podívám do Tvojí routy, tak tam duplicita url vidět je:

// matchne jakýkoliv modul a jakýkoliv presenter
$router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]'
// matchne presentery v modulu Front
$router->withModule("Front")->addRoute('<locale>/<link>[/<id>]'

Takže když máš link na druhou routu, tak LinkGenerátor přesměruje na první, která ten request také matchne – je první, proto je kanonická.

Musíš vyloučit v obecném pravidle pro modul v první routě modul Front:

$router->addRoute('admin/<locale>/<module (?!front).*>/<presenter>/<action>[/<id>]'
Kamil Valenta
Člen | 762
+
0
-

m.brecher napsal(a):

Jestli to provozuješ na lokálním serveru, tak tam subdoménu asi nastavit nepůjde. Tam můžeš mít jenom http://localhost/

To úplně ne. „Lokální“ server se možnostmi konfigurace nijak neliší od produkčního či jiného.
Ba naopak, mrskat vícero projektů na http://localhost/<něco> musí být docela opruz.
Někteří si jednotlivé hosty pojmenovávají „fiktivními“ doménami s TLD .loc nebo .local,
ale v zásadě si člověk může nastavit TLD klidně .cz a v host souboru si doménu nasměrovat na 127.0.0.1

ondraLE
Člen | 18
+
0
-

m.brecher napsal(a):

@ondraLE

netuším proč to přesměrovává. Byla by rada?

Routy Nette jsou v tomhle trochu záludné. Nette totiž aplikuje dvě různá pravidla po sobě, a člověka občas překvapí právě takovéto přesměrování. První pravidlo je – první routa která matchne url se použije. Druhé pravidlo je, že presenter získaný request ověřuje na duplicitu a zkusí z něj LinkGenerátorem vygenerovat link. Pokud se liší od původního url, přesměruje na něj – je to totiž kanonické url.

A když se podívám do Tvojí routy, tak tam duplicita url vidět je:

// matchne jakýkoliv modul a jakýkoliv presenter
$router->addRoute('admin/<locale>/<module>/<presenter>/<action>[/<id>]'
// matchne presentery v modulu Front
$router->withModule("Front")->addRoute('<locale>/<link>[/<id>]'

Takže když máš link na druhou routu, tak LinkGenerátor přesměruje na první, která ten request také matchne – je první, proto je kanonická.

Musíš vyloučit v obecném pravidle pro modul v první routě modul Front:

$router->addRoute('admin/<locale>/<module (?!front).*>/<presenter>/<action>[/<id>]'

funguje! díky moc!

Lze ještě do routeru injektovat nějakou továrnu, ve které mám nastaven nějaký parametr, kterých bych rád využil u vlastního filtru routeru (Route::FilterIn =>fce) ?

m.brecher
Generous Backer | 761
+
+1
-

@ondraLE

Lze ještě do routeru injektovat nějakou továrnu … ?

Ano, s využitím potenciálu Nette DI, např:

services:
	- App\Router\RouterFactory::createRouter(@App\Components\Provider)
    - App\Components\Provider
public static function createRouter(App\Components\Provider $provider): RouteList
{
    // zde $provider použiješ
}
ondraLE
Člen | 18
+
0
-

m.brecher napsal(a):

@ondraLE

Lze ještě do routeru injektovat nějakou továrnu … ?

Ano, s využitím potenciálu Nette DI, např:

services:
	- App\Router\RouterFactory::createRouter(@App\Components\Provider)
    - App\Components\Provider
public static function createRouter(App\Components\Provider $provider): RouteList
{
    // zde $provider použiješ
}

že mě to nenapadlo, opět funkční, díky!