Ako preniesť email po registrácii z Factory do presenteru do flashMessage
- SontoEremo
- Člen | 341
Zdravím už celý deň si láme hlavu nad tým ako preniesť z forms->SignUpFormFactory do presenteru AccountsPresenter tak aby po odoslaní formulára keď nabehne flashMessage za zobrazil email užívateľa ktorý registráciu vykonal?
Nefunkčné a jemu podobné kódy končia vždy chybou!
$sEmail->addText('[' . $this->signUpFactory->email . ']');
$sEmail->addText('[' . $this->signUpFactory->values['email'] . ']');
- JZechy
- Člen | 161
Jelikož voláš továrnu a né samotný formulář.
Nejlepší asi bude použít události, kdy si ve formuláři vytvoříš třeba atribut onAfterRegistration, a v presenteru pak jenom tomuto atributu předáš odkaz na nějakou funkci, co vše zpracuje (jako když formuláři dáváš třeba onSuccess).
Ve formuláři pak onAfterRegistration zavoláš jako metodu a předáš tomu jako parametr registrační email, který můžeš v presenteru zpracovat jak chceš.
- SontoEremo
- Člen | 341
JZechy napsal(a):
Jelikož voláš továrnu a né samotný formulář.
Nejlepší asi bude použít události, kdy si ve formuláři vytvoříš třeba atribut onAfterRegistration, a v presenteru pak jenom tomuto atributu předáš odkaz na nějakou funkci, co vše zpracuje (jako když formuláři dáváš třeba onSuccess).
Ve formuláři pak onAfterRegistration zavoláš jako metodu a předáš tomu jako parametr registrační email, který můžeš v presenteru zpracovat jak chceš.
Ďakujem za odpoveď…
Skúšam to ale nejak neviem čo dosadiť do onAfterRegistration
teda v SignUpFormFactory doplním
public function onAfterRegistration($values) {
return $this->values->email;
}
a potom v AccountsPresenter vytiahnem
$this->signUpFactory->onAfterRegistration()
vyhadzuje Accessing methods as properties via $obj->onAfterRegistration is deprecated in
- Oli
- Člen | 1215
To se dělá trochu jinak. v SignUpForm si na konec zpracování formuláře dáš:
// property
public $onAfterRegistration = [];
// ...
public function process(Form $form, $values)
{
// ...
$this->onAfterRegistration($values);
}
A v presenteru potom
public function createComponentForm()
{
$form = $this->signUpFactory->create();
$form->onAfterRegistration[] = function($values) {
$this->flashMessage($values->email);
$this->redirect('Some:destination', $values->id);
};
return $form;
}
Editoval Oli (6. 10. 2016 22:24)
- JZechy
- Člen | 161
Tak trošku prakticky… Událost nastavíš při vytváření komponenty. Přímo v té komponentě (to, co vrací signUpFactory), si pak na libovolné místě zavoláš tu událost, třeba já v té komponentě na vhodném místě volám $this->onAfterCommit($guestbook).
<?php
// Takto vytvářím formulář v nadřazené komponentě.
// Zavolám továrničku, co mi vrátí instanci třídy, která vytváří a vykresluje formulář.
protected function createComponentGuestbookForm() {
$component = $this->guestbookFormFactory->create();
$component->onAfterCommit[] = $this->formSended;
return $component;
}
public function formSended() {
$this->flashMessage($this->t("forms.guestbook.messages.sended"), "success");
$this->entries = [];
$this->redrawControl("guestbook");
}
// V GuestbookForm (to, co vrátí továrnička) pak běžně zpracovávám formulář, kdy volám událost onAfterCommit.
public function processForm(\Nette\Application\UI\Form $form) {
$values = $form->getValues();
$ok = true;
$this->getDbUtils()->begin();
try {
// ...
$this->getDbUtils()->commit();
} catch(\Exception $e) {
$this->getDbUtils()->rollback();
$ok = false;
$this->catchException($e, $this);
}
if($ok) {
$this->onAfterCommit(); // Zde volám tu událost.
}
}
?>
Tvá signUpFactory je jenom továrnička, co ti z create() vrátí tu komponentu, nesnaž se na ní volat něco, co patří komponentě.
Editoval JZechy (6. 10. 2016 21:55)
- Jan Mikeš
- Člen | 771
Mohlo by to vypadat nějak takto:
class MyFormFactory {
public $onUserRegistered = [];
public function create()
{
// zde si vytvoříš formulář
$form->onSuccess[] = [$this, "processForm"];
return $form;
}
public function processForm($form, $values)
{
// logic
$this->onUserRegistered($values->email);
}
}
class MyPresenter {
protected function createComponentRegisterForm()
{
$this->formFactory->onUserRegistered[] = function($email)
{
$this->flashMessage("Díky ti $email za registraci!");
}
return $this->formFactory->create();
}
}
Ještě lepší než mít event přímo na factory by bylo lepší si veškerou logiku registrace přesunout do samostatné třídy, která bude registraci obsluhovat a event mít tam:
MyRegisterService {
public $onRegister = [];
public function register($email, $password)
{
// logic
$this->onRegister($email);
}
}
class MyFormFactory {
public function processForm($form, $values)
{
$this->registerService->register($values->email, $values->email);
}
}
class MyPresenter {
protected function createComponentRegisterForm()
{
$this->registerService->onUserRegistered[] = function($email)
{
$this->flashMessage("Díky ti $email za registraci!");
}
return $this->formFactory->create();
}
}
- Jan Mikeš
- Člen | 771
Rád bych ti ukázal ještě jeden přístup, který hojně využívám a myslím si, že pro tuto situaci je úplně ideální. Pokud ti jdě opravdu pouze o redirect a flashmessage, eventy mohou být trošku overkill, ty se podle mě hodí na složitější problémy, nebo pokud budeš chtít mít více handlerů.
Jedná se o předávání callbacku přímo do továrničky formuláře
skrze create()
metodu:
class MyFormFactory {
public function create(callable $callback)
{
// sestavení formu
$form->onSuccess[] = function($form, $values) use ($callback) {
$this->processForm($form, $values, $callback);
};
return $form;
}
public function processForm($form, $values, $callback)
{
// registrace ... atd
if ($form->isValid()) {
$callback($values->email);
}
}
}
class MyPresenter {
protected function createComponentRegisterForm()
{
return $this->formFactory->create(function($email){
$this->flashMessage("Děkujeme ti $email za registraci");
$this->redirect("Homepage:");
});
}
}
- SontoEremo
- Člen | 341
Ďakujem chlapci za odpovede a pomoc…
cez noc to budem skladať dokopy, ale opýtam sa Vás takto je dobre na
prihlasovania a registráciu používať forms zo sandboxu z nette 2.4 alebo
je dobré spraviť Jeden Presenter teda AccountPresenter a v ňom riešiť
registráciu a prihlasovanie keďže to budem používať len na jednom mieste a
nikde inde to už nebudem prenášať?
- Jan Mikeš
- Člen | 771
@SontoEremo doporučuji se učit a zkoušet používat best practicess hned od začátku, vytvářet si services na cokoliv, snažit se dodržovat SRP a nemít žádnou business logiku v presenterech → tu přesouvat pryč a presentery používat pouze pro volání services a obsluhu samotné aplikace (request+response) a předávání dat do šablon.
Pokud se to budeš snažit dělat všeude, časem to pro tebe bude úplná automatika a ani ti to nepřijde, navíc tu jsou nástroje jako PHPStorm, které ti hooodně usnadní práci a programování je pak jedna báseň ;).
Jsem velkým zastáncem DDD, zkus si přečíst nějaké knížky/články, za mě doporučuji https://leanpub.com/ddd-in-php – drasticky změnila můj pohled na vývoj v PHP.
Editoval Lexi (6. 10. 2016 22:15)