Nesprávné pořadí parametrů v URL generovaném v Presenteru

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

Našel jsem problém (a předpokládám též bug), který je na mě trochu moc komplexní – prohledal jsem fórum i trochu prošel kód a řešení nevidím. Pokud jsem něco přehlédl, bude mi stačit odkaz. Díky.

K věci: když vytvořím link v presenteru, dopadne to např. takto:

<?php
$this->link('Article:read', array('a' => 'x', 'b' => 'y'))
// výsledek: /article/read/?a=x&b=y
?>

Pokud je však v presenteru proměnná b persistentní, proměnná b se zařadí na začátek query části URL (?b=y&a=x). Problém ovšem je, že nikoli ve vygenerovaném odkazu v presenteru, ale až po requestu na server, při jehož vyřizování se provede přesměrování na canonical URL.

Praktický problém nastává kvůli tomu, že při přesměrování se ztratí anchor, který byl v URL užitý. (Pokud k prohození proměnných nedojde, anchor samozřejmě „projde“, protože se s ním nijak nemanipuluje.) Příklad:

<?php
$this->link('Article:read#anchor', array('a' => 'x', 'b' => 'y'))
// výsledek: /article/read/?a=x&b=y#anchor
// následuje redirect na: /article/read/?b=y&a=x
?>

Moje otázky zní:

  1. Jako bug vidím to, že se URL nesestaví správně hned v presenteru. Je to feature? Jde to přepnout? (Podle Nette\Application\Route předpokládám, že by to měl být bug.)
  2. Dá se to případně obejít nějakým fíglem např. s PresenterRequest nebo routrem (kromě vypnutí canonical URLs)?

(Verze nette je 1.0-alpha.)

Editoval honza martinek (9. 8. 2010 0:55)

Filip Procházka
Moderator | 4668
+
0
-

V metodě Presenter::canonicalize() se nepředává #anchor ale jenom $presenter->action, problém bude asi v tom že fragment (kotvu) nejde pomocí php zjistit, čili jedině vypnout kanonizaci

A co se týče těch persistentních parametrů, je to, dá se říct, feature, protože při vytváření requestu se použijí persistentní proměnné a přičtou se k nim aktuální parametry, výsledkem je sčíná dvou polí array()+array(). Pokud je v prvním definován klíč tak si bude držet pozici a je jedno kolikátý je v aktuálních params

Editoval HosipLan (10. 8. 2010 4:17)

David Grudl
Nette Core | 8228
+
0
-

Hmm, asi by to chtělo dát sem ksort($args);

Filip Procházka
Moderator | 4668
+
0
-

spíš by se hodil nějaký „priority-merge“ argumentů, něco jako

dump( $userArgs + $persistentArgs + $userArgs );

což by teoreticky mělo upřednostnit uživatelem nastavené pořadí parametrů a zachovat jejich hodnotu :)

honza martinek
Člen | 22
+
0
-

Jde tam spíš o to, co navrhuje HosipLan, ale držel bych se původního znění odkazů (update nette měnící podobu všech odkazů by asi populární nebyl ;-)). Co jsem to tak zkoumal, tak na začátek se mi vyřadí ještě parametry z komponent, takže je to ještě komplikovanější. 

Jinak nejde ani tolik o to, aby se nějak řešil ten fragment, jako o to, aby Presenter se zapnutou kanonizací vracel stejnou URL jako Router->constructUrl() – tím se problém s fragmentem vyřeší (většinou myslím není nutné (nedokážu si nic takového představit), aby fragment prošel nějakým redirectem, stačí když přežije request).

Zatím jsem se pokusil vytvořit v presenteru metodu, která si nechá vygenerovat link přes $this->link() a pak ji proběhne routerem, který vrátí správnou variantu. Ale ještě do toho úplně nevidím, tak se mi to nepodařilo zprovoznit.

Ehm, tak jsem si to pořádně prošel a trochu lépe to pochopil – a ten ksort() to vážně řeší. Jsem myslel, že jádro je jinde (že se routuje při běhu aplikace ještě jinde než v presenteru). Půjde to do distribuce? Změní to spoustu kanonických adres na jiný tvar.

Editoval honza martinek (10. 8. 2010 11:06)

Filip Procházka
Moderator | 4668
+
0
-
$this->link('Article:read#anchor', array('c' => 'x', 'a' => 'y'))
// výsledek: /article/read/?c=x&a=y&a-something=persistent#anchor

řeší ksort i tohle ? nebo mi to změní pořadí na ?

// výsledek: /article/read/?a=y&a-something=persistent&c=x#anchor

Mně osobně to pořadí vůbec nevzrušuje, protože pokud někdo na pořadí query prvků v URL staví nějakou logiku v aplikaci, tak si koleduje o problém.

honza martinek
Člen | 22
+
0
-

Jde o to, aby procedura, která generuje link v presenteru, jej generovala vždy stejně. Ksort řadí i podle druhého, třetího etc. znaku klíče, takže to řeší.

Až teď jsem našel issue na githubu, kde je to zatím otevřené.

Editoval honza martinek (10. 8. 2010 14:22)

Majkl578
Moderator | 1364
+
0
-

HosipLan napsal(a):

Mně osobně to pořadí vůbec nevzrušuje, protože pokud někdo na pořadí query prvků v URL staví nějakou logiku v aplikaci, tak si koleduje o problém.

V tom případě by na to měl mít routu, nemyslíš?

Nicméně tyhle přesměrování, která jen promíchají pořadí se mi taky moc nelíbí a jsem pro vyřešení.

Filip Procházka
Moderator | 4668
+
0
-

měl jsem na mysli pořadí query prvků, path v routě zaměnit pravděpodobně nejde :)

David Grudl
Nette Core | 8228
+
0
-

fixed