Po přidání nové routy se nematchne původní

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Artas
Člen | 3
+
0
-

Ahoj, mám menší problém s routováním – můj seznam rout vypadá takto:

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

		$router[] = $adminRouter = new RouteList('Admin');
		$adminRouter[] = new Route('administrace/<presenter>/<action>[/<id>]', 'Homepage:default');

		$router[] = $frontRouter = new RouteList('Front');
        $frontRouter[] = new Route('kosik', 'Cart:default');
        $frontRouter[] = new Route('objednavka', 'Order:default');
        $frontRouter[] = new Route('potvrzeni-objednavky', 'Order:confirm');
        $frontRouter[] = new Route('zbozi/<id>', array(
            'presenter' => 'Products',
            'action' => 'product',
            'id' => array(
                Route::FILTER_IN => function ($name) {
                    return $this->urlToId($name, $this->products);
                },
                Route::FILTER_OUT => function ($id) {
                   return $this->idToUrl($id, $this->products);
                }
            )
        ));
        $frontRouter[] = new Route('<id>[/<idSub>]', array(
            'presenter' => 'Products',
            'action' => 'default',
            'id' => array(
                Route::FILTER_IN => function ($name) {
                    return $this->urlToId($name, $this->categories);
                },
                Route::FILTER_OUT => function ($id) {
                    return $this->idToUrl($id, $this->categories);
                }
            ),
            'idSub' => array(
                Route::FILTER_IN => function ($name) {
                    return $this->urlToId($name, $this->subCategories);
                },
                Route::FILTER_OUT => function ($id) {
                    return $this->idToUrl($id, $this->subCategories);
                }
            )
        ));
		$frontRouter[] = new Route('<presenter>/<action>[/<id>]', 'Homepage:default');

		return $router;
	}

	public function idToUrl($id, $repository) {
 	if (!is_numeric($id)) {
            return $id;
        } else {
            $return = $repository->findById($id)->url;
            if (!$return) {
                throw new Nette\Application\BadRequestException;
            }
            return $return;
        }
    }

    public function urlToId($name, $repository) {
        if (is_numeric($name)) {
            return $name;
        }   else {
            $return = $repository->findBy(array('url' => $name))->fetch()->id;
            if (!$return) {
                throw new Nette\Application\BadRequestException;
            }
            return $return;
        }
    }

Problém je v tom, že po přidání předposlední routy
(

$frontRouter[] = new Route('<id>[/<idSub>]', array(

), přechází všechny požadavky na ní.

Když tu předposlední routu odstraním, tak vše funguje bez problémů. Nevím kde mám chybu. Děkuji za vaše rady.

Editoval Artas (24. 8. 2013 15:27)

David Matějka
Moderator | 6445
+
0
-

jelikoz te route odpovida i foo/bar – koukni se do debug baru pro routy a uvidis, pro jake vsechny routy by se url mohla matchnout.
resenim je treba specifikovat povoleny hodnoty pro routy, treba <id \d+>[/<idSub \d+>] ti povoli id jen ciselne

Artas
Člen | 3
+
0
-

matej21 napsal(a):

jelikoz te route odpovida i foo/bar – koukni se do debug baru pro routy a uvidis, pro jake vsechny routy by se url mohla matchnout.
resenim je treba specifikovat povoleny hodnoty pro routy, treba <id \d+>[/<idSub \d+>] ti povoli id jen ciselne

Vyzkoušel jsem:

$frontRouter[] = new Route('<id  \d+>[/<idSub \d+>]', array(
            'presenter' => 'Products',
            'action' => 'default',
            'id' => array(
                Route::FILTER_IN => function ($name) {
                    return $this->urlToId($name, $this->categories);
                },
                Route::FILTER_OUT => function ($id) {
                    return $this->idToUrl($id, $this->categories);
                }
            ),
            'idSub' => array(
                Route::FILTER_IN => function ($name) {
                    return $this->urlToId($name, $this->subCategories);
                },
                Route::FILTER_OUT => function ($id) {
                    return $this->idToUrl($id, $this->subCategories);
                }
            )
        ));

a tentokrát se mi ta routa nematchne nikdy, při ProductsPresenteru se dvěma parametry to propadne až na na obecnou poslední routu.

David Matějka
Moderator | 6445
+
0
-

kouknul jsem na to jen rychle, takze jsem si ani nevsim ze ty id nebudou cisla (\d+)

nejjenodussi bude tak dat route nejakej prefix – treba „produkty“ – tedy „produkty/<id>[/<idSub>]“
dalsi moznosti je v urlToId nehazet vyjimku pri chybe, ale vratit NULL, router by pote mel zkusit dalsi routu

Artas
Člen | 3
+
0
-

matej21 napsal(a):

kouknul jsem na to jen rychle, takze jsem si ani nevsim ze ty id nebudou cisla (\d+)

nejjenodussi bude tak dat route nejakej prefix – treba „produkty“ – tedy „produkty/<id>[/<idSub>]“
dalsi moznosti je v urlToId nehazet vyjimku pri chybe, ale vratit NULL, router by pote mel zkusit dalsi routu

S prefixem to funguje. Díky za radu.