Jak při registraci ověřit existujícího uživatele?
- icanjan
- Člen | 30
Mám v presenteru po odesláni registračního formuláře tuto metodu
public function registerFormSubmitted(UI\Form $form) {
$values = $form->getValues();
$uzivEmail = $this->getParameter('email');
$uzivatel = $this->database->table('uzivatele')->get($uzivEmail);
if (!$uzivatel) {
$this->flashMessage('Uzivatel uz existuje', 'warning');
$this->redirect('this');
}
else
{
$this->database->table('uzivatele')->insert(array(
'email' => $values->email,
'heslo' => $values->password,
));
$this->flashMessage('Registrace proběhla úspěšně. Nyní se můžete přihlásit.', 'success');
$this->redirect('this');
}
}
Ale nefunguje mě to tak jak bych si představoval. Konkrétně podmínka:
if (!$uzivatel)
na to, jestli uživatel se zadaným emailem už v databázi existuje.
Pokud ano, chci to prostě jen vypsat na stránku, ne abych skončil s errorem
v debuggeru.
Dělám to dobře nějakou takovou podmínkou nebo se to musí přes nějaké
try?
Pokud ano, jak se dostanu zpět na stejnou stránku a s informací, že
se před tím registrace nepodařila?
Díky
- icanjan
- Člen | 30
Díky, a pro úplnost pro případné další čtenáře.
Moje řešení:
try {
$uzivatel = $this->database->table('uzivatele')->get($emailm);
$this->database->table('uzivatele')->insert(array(
'email' => $values->email,
'heslo' => $values->password,
));
$this->flashMessage('Registrace proběhla úspěšně. Nyní se můžete přihlásit.', 'success');
$this->redirect('this');
} catch (Exception $e) {
$form->addError($e->getMessage());
}
a na začátek presenteru použít
use Exception;
A pak vypsání chyby v .latte pod formulářem (obšlehnuto z jiného dotazu):
{form registerForm}
...
{if $form->hasErrors()}
<div n:foreach="$form->errors as $errorMessage" class="alert alert-danger">
<button type="button" class="close" data-dismiss="alert">×</button>
{$errorMessage}
</div>
{/if}
{/form}
- icanjan
- Člen | 30
No, se ukázalo, že to furt tak jasný není.
Mám teď v catch tento kód:
} catch (Exception $e) {
if ($e->getCode() == 23000) { // puvodne tady bylo ===
// pokud je chyba v duplicitě klíče, přidáme chybu do formu
$form->addError($e->getMessage()."Registrace se nezdařila.");
} else {
$form->addError($e->getMessage()." - JINA CHYBA.".$e->getCode());
// pokud jde o jinou chybu, necháme ji probublat výš
// throw $e;
}
}
Za prvné: mě zajímá, proč mě to do catch leze i když
to žádnou vyjímku nevyhodí? Při úspěšném vložení do databáze to
stejně do catch vleze, konkrétně do else větve.
Dále: V příkladu jsem našel, že na porovnání s chybou
se používá operátor ===. Ale ten mě nefunguje, leze to pak do else. Musel
jsem použít ==. Nechápu. Vysvětlí někdo?
Předem díky.
Editoval icanjan (6. 7. 2014 15:05)
- Mysteria
- Člen | 797
try {
...
} catch(\PDOException $e) { // SQL chyba
if ((int)$e->errorInfo[1] === 1062) { // SQL kód pro narušení unikátního klíče
/* Nick je obsazen, vyber si jinej */
} else { /* Jiná SQL chyba */ }
} catch (\Exception $e) { /* Jakákoliv obecná chyba */ }
Tři === porovnávají i datový typ, tzn. "16" === 16 bude FALSE, protože jedno je string a druhý int,
takže musíš přetypovat (int)"16" === 16 bude TRUE stejně jako "16" == 16.
Editoval Mysteria (6. 7. 2014 16:12)
- Majkl578
- Moderator | 1364
Osobně si myslím, že formulář by měl mít validaci na existující jméno mimo submit handler. Tzn. vlastní pravidlo, něco takového:
$form->addText('email')
->...
->addRule(function (IControl $control) {
return !$this->usersRepository->isEmailRegistered($control->getValue());
}, 'E-mail je již registrován.');
To je samozřejmě optimistická validace, která ale v 99% funguje. Pro pesimistickou verzi je unikátní klíč v databázi (a i tady můžeš někde v modelu chytat a analyzovat výjimku, kterou převedeš např. na EmailAlreadyRegisteredException a v submit handleru explicitně odchytíš).