Registrace pomocí /App/model/UserManager.php

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
sd
Člen | 87
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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;
sd
Člen | 87
+
0
-

Děkuji moc za vysvětlení! Funguje to :).
//sd