Převod formuláře ve stylu nette 0.8 do nového Nette
- miho
- Člen | 13
Ahoj. Převzal jsem apku psanou v Nette 0.8. Potřebuji ji dostat do novější verze Nette. Je v ní hromada (100+) formulářů udělaných „postaru“:
Když to budu všechno předělávat na komponenty, tak se z toho zblázním, takže se pokouším to ochcat. Když formulář ukotvím přes $form->setParent($this); tak to po odeslání hodí There is no handler for signal ‚-submit‘ in class App\Presenters\HomepagePresenter. Což dává smysl, form samotný handler nemá… ale moc mi to nepomáhá když chci, aby handloval přímo presenter. Je nějaká šance to v novém Nette rozjet v této podobě? Nebo alespoň tak, že vytvoření formu nechám jak je a handler onSuccess hodím mimo? Zkoušel jsem $form->onSuccess[] = [$this, ‚fakeHandler‘]; a přidat public function fakeHandler(UI\Form $form, $data): void { } ale hodí to stejnou chybu. Když použiju pro ukotvení $this->addComponent($form,‚loginform‘); tak to hodí The signal receiver component ‚loginform‘ is not found.
- Marek Bartoš
- Nette Blogger | 1296
addComponent()
je správně pro přidání komponenty do stromu
a zbavíš se tím chyby s handlerem. Problém ale je, že signál se
zpracovává mezi action*
a render*
, přidávat
definici formuláře v renderu je tedy pozdě. Přesuň definici do
actionLogin()
a mělo by ti to fungovat.
onSuccess
nemusíš řešit, to isSubmitted()
a
isValid()
je v podstatě jen alternativní zápis.
Editoval Marek Bartoš (28. 3. 2023 18:05)
- m.brecher
- Generous Backer | 888
@miho
Když to budu všechno předělávat na komponenty, tak se z toho zblázním, takže se pokouším to ochcat.
Píšu z hlavy, takže bez záruky, ale myslím, že komponenty z toho dělat nemusíš, formuláře fungují pořád postaru i bez komponent a bez factory rovnou v presenteru.
Co možná už je jinak je metoda isValid()? Našeptávač IDE me našeptal metodu $form->isSuccess()
Tak to zkus takhle – jednoduše vyhodit isSubmitted() + isValid() a místo toho dej isSuccess() ;) mohlo by to řešit problém.
Editoval m.brecher (28. 3. 2023 18:30)
- m.brecher
- Generous Backer | 888
@miho
Napsal jsem to blbě, sorry,
problém je v tom, že chceš na formuláři nastavit handler v době, když už je po handlování = už proběhl signal processing presenteru !!
Můžeš metody renderSomeForm() přepsat na actionSomeForm() (action proběhne před zpracováním signálu) + místo ->isSuccess() použít korektní callback $form->onSuccess[] = function(…){…}
Mohou teoreticky nastat další komplikace, potom nezbyde než korektně napsat jak je doporučeno v dokumentaci createComponentSomeForm(). Zkus a uvidíš.
Editoval m.brecher (28. 3. 2023 18:30)
- m.brecher
- Generous Backer | 888
@miho
Nějak takhle:
Obejdeš tím elegantní koncept vytváření komponent až když jsou potřeba pomocí createComponent<Component>, ale když jsou toho stovky a není čas :). Fungovat by to mělo, formulář se vytvoří podle akce i kdyby se nakonec nevykresloval.
edit
Tak mě došlo, že formulář nebude v hierarchii komponent presenteru – právě proto, že jsme obešli createComponent<Component>() :(.
Tady už moje představivost končí, napadá mě ještě $presenter->addComponent(), to je poslední možnost:
Editoval m.brecher (28. 3. 2023 18:37)
- m.brecher
- Generous Backer | 888
@miho
User Warning Form was submitted but there are no associated handlers.
Ano, musíš to napsat jak jsem ti poslal $form->onSuccess[] = …, ono se to musí volat později !! Callback !! Ve fázi action není form zpracovaný a není succeeded !!
Editoval m.brecher (28. 3. 2023 18:40)
- m.brecher
- Generous Backer | 888
@miho
Tahle verze: … funguje, do té podmínky se to zcela jistě dostane …
Nedostane a nemůže dostat !!
Formulář je vytvořený jako objekt v RAM paměti na serveru, ale NENÍ připojen do stromu komponent presenteru! Presenter obdrží signál, ale nenajde formulář ani handler.
Tipoval bych, že aby to fungoval takhle jak to máš natvrdo v action<Action>() tak nejde obejít:
a) napsat to jako callback – jak jsem Ti poslal
b) ručně přidat $form do presenteru addComponent()
Editoval m.brecher (28. 3. 2023 18:45)
- Marek Bartoš
- Nette Blogger | 1296
Fajn, na warning u chybějícího onSuccess jsem zapomněl, ale není
pravda, že by to nefungovalo bez onSuccess :) Data z http requestu jsou
v action dostupná, formulář je připojený do stromu a zvládne si je
vytáhnout a Nette to správně validuje.
Warning je jen pro případ, kdy je úspěšné zpracování
opomněné úplně.
@mbrecher Chápu, že se snažíš pomoct, zkus to však trochu zkráceně a kontrolovat si, zda to co tvrdíš tak skutečně je :) addComponent() tam má, nic jiného třeba není.
Editoval Marek Bartoš (28. 3. 2023 18:55)
- miho
- Člen | 13
Díky za rady @Marek Bartoš a @m.brecher – určitě by to takhle šlo ale bylo by to více přepisování. Finální, extrémně hnusná… ale funkční verze zarnuje nicnedělající falešný handler a skutečný handler v action (do těch podmínek se to dostane, takže jsou splněny:
zkrátka je třeba to oblbnout, aby to dělalo to, co člověk potřebuje, tedy chová se to přesně jako MacOS ;-)
BTW takové zbytečné změny jako že už není $this->user->authenticate ale $this->user->login atd, přičemž příklady na netu uvádějí tu první variantu, to dělá @DavidGrudl schválně aby naštval lidi, nebo to je jen náhoda? ;-)
Editoval miho (28. 3. 2023 18:56)
- Marek Bartoš
- Nette Blogger | 1296
$form->onSuccess[] = function() {}
bude fungovat stejně
dobře.
A fakt se to nedělá proto, aby byli lidi naštvaní. Dělá se to proto, že v tom lidi často chybovali nebo funkci pochopili špatně. A jestli nechceš být další s banem, tak bude příště vhodnější dotaz, proč to tak funguje, bez souzení jak se autor snaží dělat naschvály.
- David Grudl
- Nette Core | 8249
Jaké příklady na netu uvádí tu první variantu?
(btw původní metoda tam je)
- Marek Bartoš
- Nette Blogger | 1296
Proto se postupuje po jednotlivých (x.y) verzích. Opravíš chyby, posuneš se dál. Ideálně s phpstanem a phpstan-deprecation-rules, které tě na všechny deprecations upozorní.
- miho
- Člen | 13
To bych musel několikrát pošoupnout verzi PHP a tím i knihoven a linuxu, který je pod tím (nebo to dát do dockeru). To zní děsivě.
Vypadá to, že tenhle task mě naučí dělat spoooustu prasáren. Hele na tu krásu:
A už nemusím přepisovat 478 výskytu dibi::query různě rozesetých v kódu a přidávat přes DI databázi do desítek tříd v modelu ;-)
- David Grudl
- Nette Core | 8249
Jestli je někde použité authenticate(), tak to opravím. Jen mi musíš říct kde.
- Marek Bartoš
- Nette Blogger | 1296
To bych musel několikrát pošoupnout verzi PHP a tím i knihoven a linuxu, který je pod tím
Stačí ti spustit samotný phpstan na jiné verzi php. Kód phpstan nespouští, takže je to safe.