Vlastní autentikátor – jak předat odkaz na databázi

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

Ahoj, sorry za možná úplně blbý dotaz.
Zkouším si hrát s nette a dělám si takovou aplikaci na testy. Když si vyberu test, můžu se k němu přihlásit buď jako admin a test různě měnit, nebo se přihlásím jako student a mohu test pouze vyplnit. Každé přihlášení řeší jiný formulář a každé ověření uživatele jiný authentikator. Ty se od sebe liší pouze tím, vůči jakému heslu ověřují uživatele.
Pro ověření admin hesla jsem si jen lehce upravit výchozí autentikátor ze skeletonu. Pro ověření studenta jsem si napsal vlastní (napsal je možná silné slovo, spíš zkopíroval původní a trochu upravil funkci authenticate).
No a teď mám problém, že když userovi nastavím svůj autentikátor a zavolám $user->login
tak mi laděnka vyhodí chybu: Argument 1 passed to TestAuthenticator::__construct() must be an instance of Nette\Database\Connection

Tomu rozumím, muj autentikator neví, jak se dostat k databázi a v konstruktoru očekává, že se to dozví.
Ale problém, je že nevím, jak to zapsat.

Zkoušel jsem hledat v kodu, jak se o db dozví ten výchozí autentikator, ale nenašel jsem to.
Vím, že se tam nějak dostane z configurace, ale nevím jak a kdy. Celé je to pro mě strašně magické :-(

Ukázka kódu:

public function TestLoginFormSubmitted(UI\Form $form) {
   if ($form['send']->isSubmittedBy()) {
         try {
            $user = $this->getUser();
            $ta=new TestAuthenticator(Sem asi patří odkaz na db);
            $user->setAuthenticator($ta);
            $values = $form->getValues();
            $user->login($this->idtestu, $values->VstupniKod);
            $this->redirect('Test:ZobrazTest',$this->idtestu);
        } catch (NS\AuthenticationException $e) {
            $form->addError('Tak tohle heslo to není!');
        }
    }
    $this->redirect('default');
 }
Felix
Nette Core | 1247
+
0
-

Doporucuju pouzit MultiAuthenticator Vojty Dobese.

Pokud bys chtel nejaky hotfix, tak musis udelat takto:

// pisu z hlavy, tak nejak...
$ta=new TestAuthenticator($this->context->nette->database->default);
Šaman
Člen | 2666
+
0
-

Ten původní se to dozví pomocí autowiringu. Ve zkratce to znamená, že pokud nějakou službu vytváříš v DI kontejneru, tak tento kontejner jí sám předá parametr požadované třídy/rozhraní. Pokud takovou třídu vytváříš ručně, musíš (zcela legitimně, není to žádný hack) předat ten parametr (třeba $connection) ručně. No a teď je otázka, jak ho dostat. Pokud jej vytváříš v presenteru, tak pomocí inject metod, pokud v nějaké vlastní modelové třídě, tak ideálně přes konstruktor.
V nejhorším případě (to už je prohřešek proti DI) to vytáhneš z $contextu.

edmund
Člen | 28
+
0
-

Díky za odpovědi, zkusím to podle toho nějak vymyslet.