errorPresenter, v něm komponenta s formulářem
- Aearsis
- Člen | 57
Zdravím.
Jsem v nette a obecně MVC nový, pravděpodobně to budete považovat za banalitu, ale já si prostě už nevím rady. Mám errorPresenter, na kterém uživateli zobrazuji hlášku, že na presenter který se snaží zobrazit nemá dostatečná práva, jelikož není přihlášen. Na každé stránce mám komponentu LoginForm, a v ní formulář na přihlášení. Jenže ve chvíli, kdy se uživatel pokusí přihlásit, formulář ho přesměruje na errorPresenter, který nejde volat jen tak. Jak se tohle má řešit? Zkoušel jsem pomocí ->setAction() nad formulářem přesměrovávát, ale tahle metoda neudělá prostě nic, zkoušel jsem jak nette linky, tak absolutní, ale vždycky je v atributu action u formuláře onen errorPresenter. Díky předem za každou radu :)
- Ondřej Mirtes
- Člen | 1536
Jakým způsobem kontroluješ oprávnění? Ukaž kód té kontroly + kód tvého ErrorPresenteru.
- Aearsis
- Člen | 57
PagePresenter:
<?php
if (!$this->user->isAllowed("page/$id", "view")) {
throw new Exception("Nemáte dostatečná oprávnění prohlížet tuto stránku.", Page::FORBIDDEN);
}
?>
errorPresenter pouze do @layout.php vypíše hlášku, nic víc, nic míň.
LoginForm.php:
<?php
class LoginForm extends Control {
function okClicked(SubmitButton $ok) {
$values = $ok->getForm()->getValues();
if (!isset($this->user)) $this->user = Environment::getUser();
$this->user->authenticate($values["Username"], $values["Password"]);
}
function handleLogout() {
if (!isset($this->user)) $this->user = Environment::getUser();
$this->user->signOut(true);
$this->redirect("this");
}
function createComponentForm() {
$form = new AppForm;
// Sem jsem zkoušel dávat $form->setAction(...);
/* přeskakuju naplnění formuláře políčky */
$form->addSubmit("OK", "Přihlásit")->onClick[] = array($this, "okClicked");
$this["form"] = $form;
}
}
?>
@layout.phtml:
<?php
<div id="LoginBox">
{control loginForm}
</div>
?>
- Ondřej Mirtes
- Člen | 1536
PagePresenter – neměl by to být BasePresenter? Je ten uvedený kód v metodě startup()?
Takže pokud se jako nepřihlášený dostáváš na stránku, kterou má na starost ten PagePresenter, tak je vše v pořádku, ale při přihlašování (předpokládám, že ten formulář ti také vytváří továrnička v PagePresenter) ti neprojde ta podmínka isAllowed. Chybu teď tedy nevidím, problém bude nejspíš v tvém nastavení zdrojů, privileges a rolí.
Mimochodem, dva detaily:
- Pro „Permission denined“ slouží výjimka
BadRequestException("hláška", 403)
. - v továrničce createComponentForm má být
return $form
, ne tvoje$this["form"] = $form
;
- Aearsis
- Člen | 57
Díky, připomínky jsou to určitě věcné, nicméně asi si mě nepochopil, tohle všechno funguje dobře a je přesně tak jak mám vymyšlené. PagePresenter je dobře – kontroluju vstup na jednotlivé stránky. Je také správně, že to nepřihlášeného uživatele vykopne. Mě jde o to, mu rovnou na errorPresenteru nabídnout možnost přihlášení se, což nejde, protože komponenta se snaží znovu vytvořit na errorPresenteru, který ale nejde vyvolat „uměle“.
- Aearsis
- Člen | 57
Ano, samozřejmě by to šlo, ale když už mám tu přihlašovací komponentu (ale přihlašovací presenter nemám – když mám komponentu, neměl by být potřeba…), moje myšlenka je taková, že to bude součást stránky, každé stránky. A neříkejte mi, že takovou vlastně normální věc, jako formuláře na errorPresenteru (co kdybych na něj chtěl dát kontaktní form na autora, kde by mohl návštěvník sdělit co dělal když se to stalo?) nemá nette nějak pěkně vymyšlené.
- Aearsis
- Člen | 57
Každé stránky, tudíž i té, na které se vypisuje chyba. Že logicky nejde volat zvenku jsem si stihnul všimnout, chtěl bych vědět jak ten formulář donutit odkazovat se na presenter který byl volán před tím než vznikla ta chyba…
To jest když vznikne na Page, tak chtít aby se znovu dostával na Page pro přihlášení…
Editoval Aearsis (19. 11. 2009 18:14)
- Aearsis
- Člen | 57
Tak nakonec jsem to vyřešil přes storeRequest, a formulářem odkazujícím natvrdo na UserPresenter. Ještě bych rád dodal, že metoda setAction nefunguje jak má, pokud je v továrničce, protože se action přepíše. Možná by to stálo za to nějak ošetřit (verze 0.9.1; dc607f0) :-) Děkuji všem za pomoc a věcné připomínky
- Ola
- Člen | 385
Ta setAction nefunguje protože po vrácení formuláře v továrničce se teprve připojí k presenteru což zahrnuje i nastavení cíle. Pokud bys to dělal takto:
<?php
public function createComponentForm()
{
$form = new AppForm($this, 'form');
$form->setAction('dfignfisd');
}
?>
tak by to mělo jít.
- David Grudl
- Nette Core | 8218
Problém je v tom, že action se nastavuje automaticky a to v okamžiku připojení komponenty k presenteru. Cílem se poté stává aktuální presenter.
Tohle chování selže v okamžiku, kdy se renderuje error presenter, na který nelze vytvořit odkaz. Narovinu, je to nedomyšlenost frameworku, prostě mě tenhle případ nenapadl.
Nejsnazší workaround je v tuto chvíli asi ten, co napsal Ola, promyslím co s tím udělat koncepčně.
- Šaman
- Člen | 2658
Ahoj, už se tohle nějak pořešilo? Taky teď řeším, proč mi při chybě nefungují některé odkazy které se mají zobrazovat na každé stránce (konkrétně lišta přihlášení/odhlášení) a taky nešlape v UserPanelu přepínání uživatele (problém bude stejný, volá se handler nad aktuálním presenterem).
Editoval Šaman (28. 6. 2011 19:15)
- Elijen
- Člen | 171
Nějaký pokrok v Nette2? :-)
Takto ošklivě to musím obcházet já (formulář v komponentě)
$form = new Form($this, 'fulltextForm');
$form->setAction($this->getPresenter()->link(":front:Homepage:", array("do" => "fulltext-fulltextForm-submit")));
Editoval Elijen (10. 2. 2012 17:45)
- Tomas P
- Člen | 27
Ja mam velmi podobny problem… s v2.0.10
Sice to nema nic spolocne s formularom ale generujem v komponente link na
akciu v komponente (teda na handleXY()) a to na strankach kde sa zavola
$this->error()
proste nefunguje.
Konkretne ide o nejaky loginControl
na
prihlasovanie/odhlasovanie, takze to nema dovod nebyt na stranke kde uzivatela
informujem o nejakej 404 veci pomocou error presenteru…
<?php
// v sablone nefunguje
<a href="{link logout}">Odhlásit se</a>
// ale naopak funguje (ako pise Elijen)
// v render()
$this->template->workaround = $this->getPresenter()->link("Homepage:", array("do" => "login-logout"));
// v sablone
<a href="{$workaround}">Odhlásit se</a>
?>
Pre zaujimavost to prve pise takuto chybu
error: No route for
Error:default(exception[xdebug_message]=Nette\Application\BadRequestException:
grr in
/Users/oscar/Sites/fresenius/web/libs/nette/nette/Nette/Application/UI/Presenter.php
on line 707
Call Stack: …atd.
No, ta hlaska je spravne, ale ono to nezacne fungovat ani keby taka routa
existovala (a podla mna existovat nema, a v podstate sa na nej nachadzame).
Dufam ze som to popisal jasne… snad sa vam to podari nejak reprodukovat a
skusit opravit.
Napr. $this->error()
sa zavola z presenteru ktory by sa mohol
stale tvarit ako aktualny presenter, nemusel by sa stat aktualny ErrorPresenter,
alebo musi? (this->error hadze exceptnu tak si niesom isty)? Resp. nechapem
preco/ako sa zrazu stane parentom vsetkych komponent error presenter.
Momentalne mam pocit, ze ErrorPresenter je pouzitelny iba v pripade ze nase komponenty neobsahuju ziadne odkazy na svoje akcie… alebo pouzivat ten divny workaround.
- Aearsis
- Člen | 57
Není problém v tom, že by ErrorPresenter nebyl plnohodnotný presenter, a to že se stane parentem všech komponent je očekávané chování (přece nebude vykreslená stránka napůl šablonou errorpresenteru a napůl z komponent cizího presenteru…). Jde zejména o to, že není možné udělat na chybu odkaz – což je také očekávané chování. Jde tedy spíše o paradox.
U formulářů se to dá vyřešit tím, že přepíšeš metodu attached, kde v případě že byla připojena k ErrorPresenteru tak nastavíš action na nějaký HomepagePresenter. U odkazů v komponentách je problém složitější.
Celé by to šlo ošklivě vyřešit přetížením metody createRequest
ErrorPresenteru, ale předpokládám že final
tam není
jen tak…