Získat username z UserManageru

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

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

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

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)