Vlastní autentikátor – jak předat odkaz na databázi
- edmund
- Člen | 28
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
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
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.