Ako rozdeliť SignPresenter na niečo menšie a prehľadnejšie
- Matey
- Člen | 142
Zdravím, poradí mi prosím niekto ako správne rozdeliť SignPresenter ktorý je už pomerne veľký a neprehľadný, jeho názov nezodpovedá tomu čo dokáže, na jednotlivé časti. Prípadne do akej adresárovej štruktúry by sa to hodilo najlepšie?
Ja by som si to asi rozkúskoval do komponent, ale rád by som počul názor/radu niekto skúseného :) ďakujem
A ešte jedna vec, pri prihlasovaní, v prípade že sú zadané správne údaje ale účet nie je aktivovaný, vyhodím vlastnú ActivationException, nastavím session a podľa session ponúknem preposlanie aktivačného emailu, podobne to robím ešte pri zabudnutom hesle, je to dobrý spôsob s tým session?
Teraz môj SignPresenter:
<?php
namespace App\FrontModule\Presenters;
use Nette\Application\UI\Form;
use LeanQuery\DomainQueryFactory;
use App\Domain\User;
use App\Domain\UserRepository;
use Nette\Security\AuthenticationException;
use Nette\Utils\Random;
use Nette\Mail\Message;
use Nette\Mail\SmtpMailer;
class SignPresenter extends BasePresenter
{
/** @var DomainQueryFactory @inject */
public $domainQueryFactory;
/** @var UserRepository @inject */
public $userRepositry;
private $session;
protected function startup() {
parent::startup();
$this->session = $this->getSession('Sign');
}
public function renderDefault() {
$session = $this->getSession('Sign');
if ($session->activation) {
$this->template->activation = true;
} else {
$this->template->activation = false;
}
}
/* ========== Sign In ========== */
protected function createComponentSignInForm() {
$form = new Form;
$form->addText('login', 'Login:')
->setRequired();
$form->addPassword('password', 'Heslo:')
->setRequired();
$form->addCheckbox('remember', 'Zapamatat:');
$form->addSubmit('submit', 'Prihlasit');
$form->onSuccess[] = $this->processSignInForm;
return $form;
}
public function processSignInForm(Form $form, $values) {
if ($values->remember) {
$this->user->setExpiration('35 days', FALSE);
} else {
$this->user->setExpiration('30 minutes', TRUE);
}
try {
$this->user->login($values->login, $values->password);
$this->redirect('Sign:default');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
} catch (\App\Exception\ActivationException $e) {
$this->session->activation = $values->login;
$this->session->setExpiration(300, 'activation');
$form->addError($e->getMessage());
}
}
/* ========== Registration ========== */
protected function createComponentRegistrationForm() {
$form = new Form;
$form->addText('username', 'Užívateľské meno:')
->addRule($form::FILLED, 'Zadaj prosím užívateľské meno.');
$form->addText('email', 'Email:')
->setType('email')
->addRule($form::FILLED, 'Zadaj prosím emailovú adresu.')
->addRule($form::EMAIL, 'Zadaj prosím platnú emailovú adresu.');
$form->addPassword('password', 'Heslo:')
->addRule($form::FILLED, 'Zadaj prosím heslo.');
$form->addPassword('password2', 'Heslo znovu:')
->addRule($form::FILLED, 'Zadaj prosím heslo.')
->addRule($form::EQUAL, 'Heslá sa nezhodujú', $form['password'])
->setOmitted();
$form->addSubmit('submit', 'Zaregistrovať sa');
$form->onSuccess[] = $this->processRegistrationForm;
return $form;
}
public function processRegistrationForm(Form $form, $values) {
$user = $this->userCheck($values->username, $values->email);
if ($user) {
if ($user->username == $values->username && $user->email == $values->email) {
$form->addError('Účet so zadanými údajmi už existuje. Skúste sa prihlásiť prípadne obnoviť zabudnuté heslo');
} elseif ($user->username == $values->username) {
$form->addError('Účet s uživateľským menom '. $values->username .' už existuje.');
} elseif ($user->email == $values->email) {
$form->addError('Účet s emailom '. $values->email .' už existuje.');
}
} else {
$user = new User;
$user->username = $values->username;
$user->email = $values->email;
$user->password = $values->password;
$this->userRepositry->persist($user);
$this->sendActivationEmail($user);
$this->flashMessage('Registráca prebehla úspešne. Na email ti príde aktivačný link.');
$this->redirect('this');
}
}
/* ========== Activation ========== */
public function actionActivation($token = null) {
if (isset($token)) {
$user = $this->tokenExist($token);
if (!isset($user)) {
$this->error('Neplatný token');
} else {
$user->token = null;
$user->active = 1;
$this->userRepositry->persist($user);
$this->flashMessage('Účet je aktivovaný.');
$this->redirect('Sign:default');
}
} elseif ($this->session->activation) {
$user = $this->userExist($this->session->activation);
$this->sendActivationEmail($user);
unset($this->session->activation);
$this->flashMessage('Na Vašu emailovú adresu bol poslaný email s odkazom na aktiváciu účtu.');
$this->redirect('Sign:default');
} else {
$this->error('Neoprávnený prístup k aktivácii.');
}
}
private function sendActivationEmail(User $user) {
try {
$user->token = Random::generate(32);
$this->userRepositry->persist($user);
$template = clone $this->getTemplate();
$template->setFile(__DIR__.'/../templates/Sign/activationEmail.latte');
$template->link = $this->link('//Sign:activation', array('token' => $user->token));
$template->user = $user;
$mail = new Message;
$mail->setFrom('WW <noreply@ww.tld>')
->addTo($user->email)
->setSubject('Aktivácia účtu')
->setHtmlBody($template);
$mailer = new SmtpMailer();
$mailer->send($mail);
} catch (\Nette\Mail\SmtpException $e) {
\Tracy\Debugger::log('Problem s odoslanim emailu: '.$e->getMessage());
$this->flashMessage('Došlo ku chybe pri odosielaní emailu. Prosím skúste to neskôr.');
}
}
//pokračovanie v ďalšom poste.. nevojde sa do jedneho, také je to prehustené a to som premazal anotacie :)
?>
- Matey
- Člen | 142
<?php
// pokračovanie
/* ========== Reset Password ========== */
/**
* @return Form
*/
protected function createComponentRequireResetPasswordForm() {
$form = new Form;
$form->addText('email', 'Email:')
->setType('email')
->addRule($form::FILLED, 'Zadaj prosím emailovú adresu.')
->addRule($form::EMAIL, 'Zadaj prosím platnú emailovú adresu.');
$form->addSubmit('submit', 'Odoslať');
$form->onSuccess[] = $this->processRequireResetPasswordForm;
return $form;
}
public function processRequireResetPasswordForm(Form $form, $values) {
$user = $this->userExist($values->email);
if (!$user) {
$form->addError('Zadaj prosím rovnakú emailovú adresu s akou si sa registroval');
} else {
$this->sendResetPasswordEmail($user);
$this->flashMessage('Na email Vám bola odoslaná správa inštrukciami na obnovu hesla.');
$this->redirect('Sign:default');
}
}
private function sendResetPasswordEmail(User $user) {
try {
$user->token = Random::generate(32);
$this->userRepositry->persist($user);
$template = clone $this->getTemplate();
$template->setFile(__DIR__.'/../templates/Sign/resetPasswordEmail.latte');
$template->link = $this->link('//Sign:reset-password', array('token' => $user->token));
$mail = new Message;
$mail->setFrom('WW <noreply@ww.tld>')
->addTo($user->email)
->setSubject('Reset hesla')
->setHtmlBody($template);
$mailer = new SmtpMailer();
$mailer->send($mail);
} catch (\Nette\Mail\SmtpException $e) {
\Tracy\Debugger::log('Problem s odoslanim emailu: '.$e->getMessage());
$this->flashMessage('Došlo ku chybe pri odosielaní emailu. Prosím skúste to neskôr.');
}
}
public function renderResetPassword($token = null) {
if (isset($token)) {
$user = $this->tokenExist($token);
if (!$user) {
$this->error('Neplatný token');
} else {
$this->session->resetPassword = $user->email;
$this->template->resetPassword = true;
}
} else {
$this->template->resetPassword = false;
}
}
protected function createComponentResetPasswordForm() {
$form = new Form;
$form->addPassword('password', 'Nové heslo:')
->addRule($form::FILLED, 'Zadaj prosím nové heslo.');
$form->addPassword('password2', 'Nové heslo znovu:')
->addRule($form::FILLED, 'Zadaj prosím znovu nové heslo.')
->addRule($form::EQUAL, 'Heslá sa nezhodujú', $form['password'])
->setOmitted();
$form->addSubmit('submit', 'Zmeniť heslo');
$form->onSuccess[] = $this->processResetPasswordForm;
return $form;
}
public function processResetPasswordForm(Form $form, $values) {
if (!$this->session->resetPassword) {
$this->error('Neopravneny pristup');
}
$user = $this->userExist($this->session->resetPassword);
$user->token = null;
$user->password = $values->password;
$this->userRepositry->persist($user);
$this->flashMessage('Heslo je zmenené.');
unset($this->session->resetPassword);
$this->redirect('Sign:default');
}
/* ========== Change Password ========== */
protected function createComponentChangePasswordForm() {
$form = new Form;
$form->addPassword('currentPassword', 'Aktuálne heslo:')
->addRule($form::FILLED, 'Zadaj prosím tvoje aktuálne heslo');
$form->addPassword('password', 'Heslo:')
->addRule($form::FILLED, 'Zadaj prosím heslo.');
$form->addPassword('password2', 'Heslo znovu:')
->addRule($form::FILLED, 'Zadaj prosím heslo.')
->addRule($form::EQUAL, 'Heslá sa nezhodujú', $form['password'])
->setOmitted();
$form->addSubmit('submit', 'Zmeniť heslo');
$form->onSuccess[] = $this->processChangePasswordForm;
return $form;
}
public function processChangePasswordForm(Form $form, $values) {
if (!$this->user->isLoggedIn()) {
$this->error('Neoprávnený prístup.');
}
$user = $this->userUser($this->user->id);
if (!$user->matchesPassword($values->currentPassword)) {
$form->addError('Aktuálne heslo nie je správne.');
} else {
$user->password = $values->password;
$this->userRepositry->persist($user);
$this->flashMessage('Heslo je zmenené.');
$this->redirect('this');
}
}
public function handleSignOut() {
$this->user->logout();
$this->flashMessage('Bol ste odhlásený.');
$this->redirect('Sign:default');
}
/* ========== DomainQuery ========== */
private function userUser($id) {
return $this->domainQueryFactory->createQuery()
->from('App\Domain\User', 'u')
->select('u')
->where('id = %i', $id)
->getEntity();
}
private function userExist($login) {
return $this->domainQueryFactory->createQuery()
->from('App\Domain\User', 'u')
->select('u')
->where('username = %s || email = %s', $login, $login)
->getEntity();
}
private function userCheck($username, $email) {
return $this->domainQueryFactory->createQuery()
->from('App\Domain\User', 'u')
->select('u')
->where('username = %s || email = %s', $username, $email)
->getEntity();
}
private function tokenExist($token) {
return $this->domainQueryFactory->createQuery()
->from('App\Domain\User', 'u')
->select('u')
->where('token = %s', $token)
->getEntity();
}
}
?>
- iguana007
- Člen | 970
Já to mám tak, že Sign presenter řeší to, podle čeho
se jmenuje, tj. pouze přihlašování. Registraci, správu hesla apod. si
dávám do User presenteru nebo se to taky může rozdělit
ještě na User a Register.
Formuláře si dávám do samostaných tříd (přijde mi to přehlednější a
lépe se mi s tím pracuje) a práci s databází by měly řešit modely,
nikoli presentery.
- David Kudera
- Člen | 455
minimálně dvě věci, pohledej, jak oddělit formuláře a vlastně všechny komponenty, aby měli svou vlastní třídu (hledej např. generované továrničky). A za druhé to pod komentářem DomainQuery by mělo být v nějakým modelu a určitě ne v presenteru ;-)
- David Kudera
- Člen | 455
@TomášVotruba díky :-)
A ještě jsem si vzpomněl, že před pár dny jsem tu psal ukázku i s použitím dalších „dodatečných“ parametrů pro komponentu (předaných např. z presenteru) odkaz
- castamir
- Člen | 629
Ještě jedna ukázka, jak řešit čistě přihlašování:
Editoval castamir (1. 8. 2014 16:36)
- Matey
- Člen | 142
pustím sa do toho, zjavne z toho bude viac presenterov a v nich autowired komponenty, tie som si už vyskúšal pri komentároch
ďakujem