Pri presmerovaní cez forward() nefunguje odoslanie formuláru

sucho
Člen | 57
+
0
-

Zdravím pre minimalizovanie počtu rout a krajšie URL ktoré začínajú rovno za /
som si vytvoril jednu tabuľku kde ukladám tvar URL a z akého Presentra sa má načítať

Potom cez forward presmerujem do správneho presentra

$this->forward(':Product:default', ['id' => $this-id]);

Zobrazenie funguje super
ale keď použijem na tom novom presentri nejaký formulár alebo handle
tak to prestane fungovať a niekde sa to stratí (pritom dáta v Request sú)
ale tak zrejme kvôli tomu že control nieje pripojený k tomu prvému presentru

ešte dodám že je to na Nette 2.4

Daewoo
Člen | 37
+
0
-

Tenhle problém je i v Nette 3.2.6. Právě to řeším v rámci refaktoru, přestal mi jet globální vyhledávací formulář jako persist komponenta. Díval jsem se do kódu Nette – Presenter.php a pravdou je, že pokud je getMethod() rovno čemukoli jinému než POST (v našem případě to bude FORWARD), tak to neinicializuje do globalParams data z getRequest()->getPost(), aby to spárovalo příchozí signály s komponentami. Reinit globalParams – initGlobalParameters() je private. Pole getRequest()->getPost() je zde prázdné, getHttpRequest()->getPost() již data obsahuje. Hloubějc jsem to nezkoumal. Ta kontrola getMethod() je právě v tom getRequest()->getPost(). Možná by stačilo vyměnit volání v Nette kódu z getRequest za getHttpRequest? Nejsem expert.

Kód jsem obdržel takový, že mi jedna actiona rozhazuje podle slugu presentery (rozjebává mi to do určité míry i generátor odkazů, ale s tím jsem se dokázal sžít) a nechci do toho moc zasahovat, jde o starý kód. No, a tady je kámen úrazu – formulář nefunguje. Předchozí dráteník to nějak dal dokupy, napůl to fungovalo, ale tenhle můj refaktoring má svoje limity a primární koneckonců je, aby jelo všechno jak má.

Je na to nějaký workaround? Teď to mám na prasáka v action presenteru přes getHttpRequest a ručně volám successMetodu z té vyhledávací komponenty…

Editoval Daewoo (19. 11. 17:25)

MajklNajt
Člen | 498
+
+1
-

Podľa mňa je toto správne chovanie po forwarde, ide v podstate o zamaskovaný redirect, takže nevidím dôvod, aby forwardovaný presenter videl POST dáta z nejakého iného presentera

Daewoo
Člen | 37
+
0
-

Já rozumím tomu, proč by to tak mělo fungovat, v podstatě s tím i souhlasím. Ale:

  1. K těm datům se reálně téměř bez problémů z forwardovaného presenteru dostanu. Technicky to tudíž jde, není zde omezení na nižší úrovni, proč se omezovat výš? Ono tam asi k reálnému redirectu nedochází (někde jsem četl, že se jen reinicializuje celý presenter) – střeva jsem blíž nezkoumal, což mě přivádí k bodu 2:
  2. I když to třeba akademicky není úplně OK, asi bych raději upřednostnil praktičnost. Vidím to v tomhle případě jako zbytečnou „šikanu“. Pokud Nette ta data vidí = dostane se k nim, není důvod, aby je normálně nezpracoval i signálově, byť třeba nějakou „neoficiální“ cestou. Na čem by to mohlo jinde ztroskotat?

Možná mi něco uniká, už do toho čumím moc dlouho.

Editoval Daewoo (19. 11. 17:36)

m.brecher
Generous Backer | 873
+
0
-

@Daewoo

Forward presenteru není plnohodnotný redirect a to z jednoho důvodu. Nedochází k inicializaci celé aplikace úplně shora jako u http redirectu, ale Nette inicializuje od presenteru. Ideální je forwardovat pouze na Error4xxPresenter a v normálním 200 provozu používat klasický http redirect.

Kód jsem obdržel takový, že mi jedna actiona rozhazuje podle slugu presentery

V akci jednoho presenteru se podle slugu forwarduje na další presentery ? Lepší by určitě bylo mít místo slugu rovnou action a již z routeru volat správný presenter POST/GET, takhle se dostáváš díky atypickému forwardu do potíží. Vždycky to jde takhle přímo udělat a forward vše jen zkomplikuje.

Jestli se ten forward nevyplatí refactorovat na get, tak použij přístup k POST datům z httpRequestu.

Vidím to v tomhle případě jako zbytečnou „šikanu“. Pokud Nette ta data vidí = dostane se k nim, není důvod, aby je normálně nezpracoval i signálově,

Chyba je především používat FORWARD místo redirect. Asi by se to mělo doplnit do dokumentace, protože až pečlivým testování člověk zjistí rozdíly mezi redirect a forward. Klasický redirect je GET a nemá v HTTP protokolu podporu pro POST. Forwardovat z presenteru na jiný presenter když odesílám formulář není nikdy dobrý nápad.

Smysl by dávalo dopracovat FORWARD tak, aby to byl plnohodnotný redirect. S tím rozdílem, že by se application startovalo z Requestu a httpRequest by vůbec nebyl potřeba. V ajaxovem odesílaných formulářích by se hodil hodně. Ale jenom jako ekvivalent GET HTTP redirectu. Takže i kdyby se FORWARD dopracoval kam by se dopracovat měl, stejně by se neměl používat jak popisuješ.

Editoval m.brecher (20. 11. 3:49)