Registrace pomocí /App/model/UserManager.php
- sd
- Člen | 87
Zdravím,
teprve se s Nette seznamuji a tak se omlouvám, pakliže je můj dotaz hloupý :(…
Snažím se udělat registraci uživatele založené na
/App/model/UserManager.php (v sandboxu).
Jenže, jakmile zvaliduji odesílaný formulář, zavolám funkci
UserManager->add() Laděnka vypíše chybu:
Argument 1 passed to App\UserManager::__construct() must be an instance of
Nette\Database\Context, none given, called in
/Applications/XAMPP/xamppfiles/htdocs/StockAdminN/sandbox/app/presenters/RegisterPresenter.php
on line 57 and defined
A v error stránce laděnky je červeně vyzančená část kódu z UserManager.php, řádek 27 (funkce __construct).
Můj upravený UserManager.php
<?php
namespace App;
use Nette,
Nette\Utils\Strings;
/**
* Users management.
*/
class UserManager extends Nette\Object implements Nette\Security\IAuthenticator
{
const
TABLE_NAME = 'users',
COLUMN_ID = 'id',
COLUMN_NICK = 'login',
COLUMN_PASSWORD_HASH = 'password',
COLUMN_NAME = 'name',
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;
$password = self::removeCapsLock($password);
$row = $this->database->table(self::TABLE_NAME)->where(self::COLUMN_NICK, $username)->fetch();
if (!$row) {
throw new Nette\Security\AuthenticationException('The username is incorrect.', self::IDENTITY_NOT_FOUND);
} elseif (!Passwords::verify($password, $row[self::COLUMN_PASSWORD_HASH])) {
throw new Nette\Security\AuthenticationException('The password is incorrect.', 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 add($username, $password, $name, $role)
{
$this->database->table(self::TABLE_NAME)->insert(array(
self::COLUMN_NICK => $username,
self::COLUMN_PASSWORD_HASH => Passwords::hash(self::removeCapsLock($password)),
self::COLUMN_NAME => $name,
self::COLUMN_ROLE => $role,
));
}
/**
* Fixes caps lock accidentally turned on.
* @return string
*/
private static function removeCapsLock($password)
{
return $password === Strings::upper($password)
? Strings::lower($password)
: $password;
}
}
Můj RegisterPresenter.php (upravil jsem SignPresenter.php)
<?php
namespace App\Presenters;
use Nette,
App\Model;
/**
* Sign in/out presenters.
*/
class RegisterPresenter extends BasePresenter
{
/**
* Register form factory.
* @return Nette\Application\UI\Form
*/
protected function createComponentRegisterForm()
{
$roles = array(
'comp1' => 'Company 1',
'comp2' => 'Company 2',
'comp3' => 'Company 3',
);
$form = new Nette\Application\UI\Form;
$form->addText('username', 'Username:')
->setRequired('Please enter your username.');
$form->addPassword('password1', 'Password:')
->setRequired('Please enter your password.');
$form->addPassword('password2', 'Password again:')
->setRequired('Please enter your password.');
$form->addText('name', 'Your name:')
->setRequired('Please enter your name.');
$form->addRadioList('radio2', 'Select your company:', $roles);
$form->addSubmit('send', 'Register');
//call method registerFormSucceeded() on success
$form->onSuccess[] = $this->registerFormSucceeded;
return $form;
}
public function registerFormSucceeded($form)
{
$values = $form->getValues();
if($values->password1 == $values->password2){
$user = new \App\UserManager;
$user->add($values->username, $values->password1, $values->name, $values->radio2);
$this->flashMessage('You have been registered succesfuly.');
} else {
$this->flashMessage('Something goes wrong, maybe the passwords doesn\'t match.');
}
}
}
Děkuji,
sd
- Jiří Nápravník
- Člen | 710
Protože nemůžeš zavolat new \App\UserManager, musel bys mu předat připojení k databázi.
Musíš si vytáhnout ten UserManager z DI kontejneru, což uděláš v presenteru tak, že si nad konstruktor napíšeš
/**
* @var App\Model\UserManager
* @inject
*/
public $userManager;
a tak kde ten manager potřebuješ použiješ $this->userManager
No a určitě doporučuju pročíst si dokumentaci, aspon quickstart, protože tma jistě tyhle věci najdeš
- sd
- Člen | 87
Děkuji moc za odpověď. Dokumentaci jsem tak nějak koumal, ale nějak jsem to úplně nepobral, omlouvám se.
Jenže teď se mi nedaří „nasměrovat“ presenter do složky /model/UserManager.php. Pořád se snaží hledat /model/ jako podadresář složky /presenters/. Nefunguje ani:
/**
* @var ..\Model\UserManager
* @inject
*/
public $userManager;
Chybová hláška:
Nette\InvalidStateException
Please use a fully qualified name of class/interface in @var annotation at App\Presenters\RegisterPresenter::$userManager property. Class ‚App\Presenters\App\Model\UserManager‘ cannot be found
Jak ho mám nasměrovat do složky app/model/UserManager?
Děkuji,
sd
Editoval sd (29. 3. 2014 19:36)
- Oli
- Člen | 1215
Důležitá věc je, že vubec neřešíš fyzické umístění souboru. Jediné co řešíš je jmenný prostor. Takže správně je:
/**
* @var \App\UserManager
* @inject
*/
public $userManager;
Protože třída UserManager má namespace App. Pokud by měla namespace App\Model\Karel\Novák a byla umístěna v sandbox/app/model tak ji do presenteru dostaneš jako:
/**
* @var \App\Model\Karel\Novák\UserManager
* @inject
*/
public $userManager;