Získání ID (a jiných údajů) uživatele pro formulář

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

Ahoj,
mám na Vás takový dotaz. Aktuálně pracuju na zpracování formuláře pro změnu hesla a potřeboval bych radu jak a kdy získat ID přihlášeného uživatele.

Moje představa je zatím tato:

  1. Uživatel odešle formulář s novým a starým heslem
  2. V továrničce na formulář se zavolá formSucceeded($form, $values), kde zavolám metodu v modelu UserManager jménem changePassword($old_password, $new_password)

První otázka zní, můžu získat ID uživatele až v modelu? nebo ji musim do modelu poslat – , changePassword($old_password, $new_password, $user_id)?

Druhá otázka zní, jak dostat ID v modelu? Stačí toto?

//Model UserManager
use Nette,
	Nette\Security\Passwords,
    Nette\Security\IIdentity;
//.....
//.....
  /** @var Nette\Security\IIdentity */
    private $user;

public function __construct(Nette\Security\IIdentity $user)
	{
        $this->user = $user;
	}
//.....
//.....
// a pak v nějaké metodě použít toto?
$this->user->id;
Blujacker
Člen | 89
+
0
-

Ahoj,

rekl bych ze ano, ja si v modelu normalne predavam User takto

function __construct(\Nette\Security\User $user){
    $user->id;
    $user->getIdentity();
    ...
}
Croc
Člen | 270
+
0
-

Nějak se mi to nedaří. Pokud definuju User v construktoru, dostávám chybu:

Circular reference detected for services

Pokud definuju User takto:

/** @var Nette\Security\User
    * @inject */
   public $user;

Je to v poho, ale pak nevím jak dostat ID přihlášeného uživatele. Zkoušel jsem všechno možné co mě napadlo ale neúspěšně.

$this->user->getId() //hází chybu:

Call to a member function getId() on null
// Metoda v modelu UserManager

  public function changePassword($old_password, $new_password)
    {
            $row = $this->findAllUsers()->where(self::COLUMN_ID, /* zde potřebuji user ID */)->fetch();

            if (!Passwords::verify($old_password, $row[self::COLUMN_PASSWORD_HASH])) {
                throw new Nette\Security\AuthenticationException('Zadané heslo není správné.', self::INVALID_CREDENTIAL);
            }
            else {
                try {
                    $this->findAllUsers()->where(self::COLUMN_ID, /* zde potřebuji user ID */)->update(array(
                        self::COLUMN_PASSWORD_HASH => Passwords::hash($new_password),
                    ));
                } catch (Nette\Database\UniqueConstraintViolationException $e) {
                    throw new DuplicateNameException;
                }
            }
    }

Editoval Croc (29. 4. 2015 10:15)

greeny
Člen | 405
+
0
-

Třeba takhle nějak?

class UserManager
{
	private $user;

	public function __construct(Nette\Security\User $user)
	{
		$this->user = $user;
	}

	public function changePassword($old, $new)
	{
		$id = $this->user->getId();
		// change password
		return TRUE;
	}
}
jiri.pudil
Nette Blogger | 1032
+
+1
-

Nikde jinde než v presenterech @inject anotace defaultně nefungují, proto Call to a member function getId() on null. Circular reference je nejspíš způsobené tím, že ta třída implementuje IAuthenticator, a tady narážíš na SRP – autentizace a změna hesla jsou dvě úplně jiné věci, a určitě by tudíž bylo lepší vyčlenit implementaci IAuthenticator do samostatné třídy. Pak budeš moct User do toho manageru injectnout bez potíží přes konstruktor.

Croc
Člen | 270
+
0
-

@greeny : Takto sem to právě měl…

@jiri.pudil : To bude ono :). Odpoledne na to kouknu… Díky moc