Získat username z UserManageru
- Tymikes
- Člen | 63
Zdravim,
problém je celkem jednoduchý, nemůžu dostat z UserManagera uživatelské
jméno, když jsem v RegisterPresenteru a přitom private $userManager
mám.
Proč?
Call to undefined method App\Model\UserManager::table().
$this->userManager->table('users')->where(array('username' => $values->username))->fetch();
RegisterPresenter
<?php
namespace App\Presenters;
use Nette,
App\Model\UserManager;
class RegisterPresenter extends BasePresenter
{
private $userManager;
public function __construct (UserManager $userManager)
{
$this->userManager = $userManager;
}
protected function createComponentRegisterForm()
{
$form = new Nette\Application\UI\Form;
$form->getElementPrototype();
$form->addText('username', 'Uživatelské jméno:')
->setRequired('Prosím vyplňte uživatelské jméno.')
->addRule($this->duplicitniJmeno, 'Uzivatelské jméno je již použito, zadejte prosím nové!!!');
$form->addPassword('password', 'Password:')
->setRequired('Prosím vyplňte heslo.');
$form->addText('password2', 'Opište heslo:')
->setRequired('Prosím zopakujte svoje heslo..');
$form->addSubmit('send', 'Register');
$form->onSuccess[] = array($this, 'registerFormSucceeded');
return $form;
}
public function registerFormSucceeded ($form, $values)
{
if ($values['password'] == $values['password2'])
{
$this->userManager->pridat($values['username'], $values['password']);
$this->flashMessage('Vaše registrace proběhla úspěšně', 'success');
try {
$this->getUser()->login($values->username, $values->password);
$this->redirect('Homepage:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
else{$this->flashMessage('Vaše hesla se neshodují', 'success');}
}
public function duplicitniJmeno($values){
return !$this->userManager->table('users')->where(array('username' => $values->username))->fetch();
}
}
<?php
namespace App\Model;
use Nette;
use Nette\Security\Passwords;
/**
* Users management.
*/
class UserManager extends Nette\Object implements Nette\Security\IAuthenticator
{
const
TABLE_NAME = 'users',
COLUMN_ID = 'id',
COLUMN_NAME = 'username',
COLUMN_PASSWORD_HASH = 'password',
COLUMN_ROLE = 'role';
/** @var Nette\Database\Context */
private $database;
public function __construct(Nette\Database\Context $database)
{
$this->database = $database;
}
/**
* Performs an authentication.
* @return Nette\Security\Identity
* @throws Nette\Security\AuthenticationException
*/
public function authenticate(array $credentials)
{
list($username, $password) = $credentials;
$row = $this->database->table(self::TABLE_NAME)->where(self::COLUMN_NAME, $username)->fetch();
if (!$row) {
throw new Nette\Security\AuthenticationException('Nesprávné uživatelské jméno.', self::IDENTITY_NOT_FOUND);
} elseif (!Passwords::verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
throw new Nette\Security\AuthenticationException('Nesprávné heslo.', self::INVALID_CREDENTIAL);
} elseif (Passwords::needsRehash($row[self::COLUMN_PASSWORD_HASH])) {
$row->update(array(
self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
));
}
$arr = $row->toArray();
unset($arr[self::COLUMN_PASSWORD_HASH]);
return new Nette\Security\Identity($row[self::COLUMN_ID], $row[self::COLUMN_ROLE], $arr);
}
/**
* Adds new user.
* @param string
* @param string
* @return void
*/
public function pridat($username, $password)
{
try {
$this->database->table(self::TABLE_NAME)->insert(array(
self::COLUMN_NAME => $username,
self::COLUMN_PASSWORD_HASH => Passwords::hash($password),
self::COLUMN_ROLE => "registered"
));
} catch (Nette\Database\UniqueConstraintViolationException $e) {
throw new DuplicateNameException;
}
}
}
class DuplicateNameException extends \Exception
{}
Editoval Tymikes (16. 3. 2016 18:06)
- Šaman
- Člen | 2666
UserManager ale nemá public property table
.
A z presenteru/komponenty bys vůbec neměl sahat přímo na databázi, pokud
používáš model.
Dopiš si do toho UserManagera metodu třeba
getUserByUsername($username)
a použij tu.
Jinak nedoporučuji se moc inspirovat UserManagerem – s těma konstantama a koneckonců i pojmenováním to není dobrý příklad. On tam je hlavně z důvodů, aby se dal nějak čistě přidávat uživatel a vypadá tak, jak vypadá proto, aby bylo možné ho pomocí těch konstant rychle upravit na jinou strukturu databáze. Ale je to zároveň repository, zároveň autentikátor.
Jako ukázku hodně jednoduchého modelu a repozitářů mohu ukázat třeba tohle.
Autentikátor
si pak netahá uživatele sám z databáze, ale dostane v konstruktoru
UserRepository
. (Je to jiný projekt, tento používá Dibi, ale
princip je stejný. A metoda calculateHash
je dnes už zbytečná,
umí to spočítat Nette i PHP samo.)
Editoval Šaman (16. 3. 2016 19:13)
- Tymikes
- Člen | 63
Jojo, díky určitě se na to kouknu. Tak tohle funguje, ale nevypíše mi to alert, který mám v rule.
UserManager
public function getUserName($uzivatel)
{
return $this->database->table('users')->where(array('username' => $uzivatel))->fetch();
}
RegisterPresenter
public function duplikaceJmeno($values)
{
$uzivatel = $values->getValue();
return !($this->userManager->getUserName($uzivatel));
}
--------------------------------Zkoušel jsem ještě----------------------------
$form->onValidate[] = array($this, 'duplikaceJmeno');
public function duplikaceJmeno($form)
{
$uzivatel = $form->getValues()->username;
if ($this->userManager->getUserName($uzivatel) != false)
{
$form->addError('Uživatelské jméno %name již existuje');
}
}
A zjistil jsem, že se mi errory nějak nevypisují.
//Aha při low level formulářích, musím errory ještě vypsat.. :)
Vyřešeno, děkuji :)
Editoval Tymikes (16. 3. 2016 22:38)