errorPresenter, v něm komponenta s formulářem

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

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
+
0
-

Jakým způsobem kontroluješ oprávnění? Ukaž kód té kontroly + kód tvého ErrorPresenteru.

Aearsis
Člen | 57
+
0
-

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
+
0
-

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
+
0
-

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“.

_Martin_
Generous Backer | 679
+
0
-

A co kdyby ten ErrorPresenter v případě chyby „nepřihlášení uživatele“ přesměroval na přihlašovací presenter? (Ono je otázka, proč na něj nesměruješ rovnou; ale to je tvoje věc, že radši používáš výjimky).

Aearsis
Člen | 57
+
0
-

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é.

_Martin_
Generous Backer | 679
+
0
-

Aearsis napsal(a):

Tak má to být součást každé stránky, nebo ErrorPresenteru? Jinak ErrorPresenter (logicky) nelze volat z venku, čili na něj nelze ani směrovat formulář.

Aearsis
Člen | 57
+
0
-

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
+
0
-

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
+
0
-

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.

Aearsis
Člen | 57
+
0
-

Nicméně stále si myslím, že by šlo nějak ošetřit že pokud je nastavena action manuálně, pak se ani po připojení k presenteru nezmění… ne?

David Grudl
Nette Core | 7417
+
0
-

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 | 2528
+
0
-

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)

frosty22
Člen | 373
+
0
-

Pravděpodobně nepořešilo, nyní mám stejný problém – error presenter nezpracovává signály.

Elijen
Člen | 171
+
0
-

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)

David Grudl
Nette Core | 7417
+
0
-

Formuláře budou řešeny až v další verzi.

simPod
Člen | 374
+
0
-

a co ted? nette 2.0.3 stejny problem
submit formulare na error presenteru nejde a zaroven signaly taky ne

Editoval simPod (5. 7. 2012 2:19)

skallet
Člen | 2
+
0
-

Pořád se to nevyřešilo ? ..

Aearsis
Člen | 57
+
0
-

Nevěřil bych, že můj malý všetečný dotaz poukáže na takovou neřešitelnou věc :)
Pokud vím, tak není.

Editoval Aearsis (26. 11. 2012 17:50)

Tomas P
Člen | 27
+
0
-

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
+
0
-

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…

darthcz
Člen | 113
+
0
-

Taky jsem na to právě narazil. Konkrétně u uživatelské lišty, ve které mám přihlášení a odkazy na zapomenuté jméno/heslo… Pořád bez řešení?

sKopheK
Člen | 207
+
0
-

ErrorPresentery jsou v Nette zakleté :). Máte někdo zkušenosti s workaroundem u odkazů zabezpečených mechanismem SecuredLinks? Musel jsem to řešit ručním přidáním parametrů za vygenerovanou URL.

Editoval sKopheK (22. 4. 2014 13:20)