Prazdna stranka po zavolani loginu

- daan
 - Člen | 7
 
Dobry den.
Vcera som si na roote zacal citat serial o tomto frameworku a rozhodol som sa, ze ho v niektorych projektoch zacnem pouzivat.
Pre ziskanie skusenosti som si povedal, ze si vytvorim vlastny login form a pomocou nette sa prihlasim do admin rozhrania. (admin.php)
Form vyzera takto:
<?php
switch($_GET["action"])
  {
    case "login":
      include("login.php");
    break;
  }
$form = new Form;
$form ->addText('name','ID: ');
$form ->addPassword('pass','password: ');
$form ->getElementPrototype()->action('index.php?action=login');
$form ->addSubmit('login', 'login');
echo $form;
?>
a jeho spracovanie
login.php:
<?php
require '../framewrks/nette/Nette/loader.php';
require 'auth.php';
$username = $_POST["name"];
$password = $_POST["pass"];
$user = Environment::getUser();
$user->setAuthenticationHandler(new MyAuthenticator);
$user->setExpiration('+ 15 minutes');
try {
        $user->authenticate($username, $password);
        Environment::getHttpResponse()->redirect('admin.php');
} catch (AuthenticationException $e) {
        echo 'Chyba: ', $e->getMessage();
}
echo $user->isAuthenticated() ? 'ano' : 'nie'
?>
auth.php:
<?php
class MyAuthenticator extends Object implements IAuthenticator
{
    public function authenticate(array $credentials)
    {
        $username = $credentials[self::USERNAME];
        $password = sha1($credentials[self::PASSWORD] . $credentials[self::USERNAME]);
        $row = dibi::fetch('SELECT id, pass FROM kuserz WHERE login=%s', $username);
        if (!$row) {
            throw new AuthenticationException("User '$username' not found.", self::IDENTITY_NOT_FOUND);
        }
        if ($row->password !== $password) {
            throw new AuthenticationException("Invalid password.", self::INVALID_CREDENTIAL);
        }
        return new Identity($row->id);
    }
}
?>
Problem je, ze vzdy po odoslani formulara sa objavi prazdna stranka
index.php?action=login so ziadnym vypisom.
Bez ohladu na to, ci som nieco do formulara napisal/nenapisal, alebo napisal
nespravne.
Je mozne za mi unika iba malickost, alebo som nieco nespravne pochopil, ale ako hovorim zacal som iba vcera, no nette sa mi paci a rad by som v nom pokracoval dalej.
Dakujem za pomoc. :)

- _Martin_
 - Generous Backer | 679
 
Ahoj, tak tedy:
- Zapni si Laděnku příkazem 
Debug::enable();, který umístíš hned za načtení frameworku – možná je zde nějaká výjimka nebo i noticka (které máš zjevně vypnuté, jinak bys věděl, žeswitch($_GET["action"])může být přístup k nedefinované proměnné). - Přepracuj kód tak, aby se přihlašování vykonávalo až po odeslání
	formuláře (v tvém případě by se aplikace pokusila přihlašovat i při
	prázdném formuláři) a aby jsi vůbec formulář používal na ošetření
	zadávaných dat (použitím 
$username = $_POST["name"];jsi Nette formuláře degradoval na pouhé vypsání XHTML kódu). 
$form = new Form;
$form ->addText('name','ID: ');
$form ->addPassword('pass','password: ');
$form ->getElementPrototype()->action('?action=login');
$form ->addSubmit('login', 'login');
// jestliže byl formulář odeslán
if ($form->isSubmitted()) {
    // a jestliže jsou všechny položky vyplněny správně
    if ($form->isValid()) {
        $values = $form->getValues();
	// přihlášení
	$username = $values['name'];
	$password = $values['pass'];
	...
	// nakonec (v případě úspěšného přihlášení) by mělo následovat přesměrování
    }
}
echo $form;
- Až se víc seznámíš s formuláři, můžeš použít i validaci (například že vyplnit jméno a heslo je povinné).
 

- daan
 - Člen | 7
 
- jj, debug mam enabled este na zaciatku indexu, teda o nieco vyssie nez kod, ktory som pastol sem.
 - Rozumiem. O funkciach isSubmitted a isValid som vedel, myslel som vsak, ze sa daju alternovat klasickou PHP metodou, ktoru pouzivam. (t.j. POST udajov do premennych a nacitanie osobitneho login scriptu v momente, ked prebehne odoslanie formulara)
 
Prerobil som to teda do nette, tak ako ste mi to opisali, no moj problem pretvava v rovnakej podobe.
index.php vyzera takto
<?php
$form = new Form;
$form ->addText('name','ID: ');
$form ->addPassword('pass','password: ');
$form ->addSubmit('login', 'login');
if ($form->isSubmitted())
  {
    if ($form->isValid())
      {
        $values = $form->getValues();
        $username = $values['name'];
        $password = $values['pass'];
        require 'auth.php';
        $user = Environment::getUser();
        // zaregistrujeme autentizační handler
        $user->setAuthenticationHandler(new MyAuthenticator);
        // nastavíme expiraci
        $user->setExpiration('+ 15 minutes');
        try
          {
             $user->authenticate($username, $password);
             Environment::getHttpResponse()->redirect('admin.php');
          }
        catch (AuthenticationException $e)
          {
            echo 'Chyba: ', $e->getMessage();
          }
            }
    }
echo $form;
?>
a auth.php sa nezmenilo.
Ja si myslim, ze chyba by mohla byt niekde tam (auth.php), resp. celkom dobre nerozumiem tejto casti
<?php
$username = $credentials[self::USERNAME];
$password = sha1($credentials[self::PASSWORD] . $credentials[self::USERNAME]);
?>
Prihlasovacie udaje sme uz pomocou getValues() do tychto premennych nacitali, tak co sa robi tu? Co reprezentuje premenna $credentials?

- _Martin_
 - Generous Backer | 679
 
Zvláštní, použil jsem přesně ten kód, co jsi teď postnul a vše funguje. Pravda ovšem, že jsem odmazal řádek s použitím dibi, neb jsem nechtěl tvořit databázi. Nicméně, ten dotaz nevypadá, že by oplýval nějakou chybou.
Můžeš mi ještě napsat, jakou verzi Nette (včetně revize v případě verze 0.9) a PHP používáš? Já zkoušel verzi 0.9 revize 332 na PHP 5.2.6.

- _Martin_
 - Generous Backer | 679
 
To jsem z toho blázen zkusil jsem revizi 293 a funguje to. Nemůže být chyba v nějakém kódu „okolo“? Zkus udělat jen tyhle dva soubory (přesně zkopíruj, žádné úpravy), jesti ti to bude fungovat:
// index.php
<?php
require 'Nette/loader.php';
Debug::enable();
$form = new Form;
$form ->addText('name','ID: ');
$form ->addPassword('pass','password: ');
$form ->addSubmit('login', 'login');
if ($form->isSubmitted()) {
	if ($form->isValid()) {
		$values = $form->getValues();
		$username = $values['name'];
		$password = $values['pass'];
		require 'auth.php';
		$user = Environment::getUser();
		// zaregistrujeme autentizační handler
		$user->setAuthenticationHandler(new MyAuthenticator);
		// nastavíme expiraci
		$user->setExpiration('+ 15 minutes');
		try {
			 $user->authenticate($username, $password);
			 Environment::getHttpResponse()->redirect('admin.php');
		} catch (AuthenticationException $e) {
			echo 'Chyba: ', $e->getMessage();
		}
	}
}
echo $form;
// auth.php
class MyAuthenticator extends Object implements IAuthenticator
{
	public function authenticate(array $credentials)
	{
		$username = $credentials[self::USERNAME];
		$password = sha1($credentials[self::PASSWORD] . $credentials[self::USERNAME]);
		$row = (object) array(
			'id' => 5,
			'username' => 'pepa',
			'password' => 'd0d1a46636021ba10a2022904f7388f1155e708d', // heslo je abc123
		);
		if (!$row) {
			throw new AuthenticationException("User '$username' not found.", self::IDENTITY_NOT_FOUND);
		}
		if ($row->password !== $password) {
			throw new AuthenticationException("Invalid password.", self::INVALID_CREDENTIAL);
		}
		return new Identity($row->id);
	}
}
				
- daan
 - Člen | 7
 
Tak to sem blazen i ja, ponevac som tie kody skusil a po stlaceni tlacidla login dostanem cistu bielu obrazovku pre akykolvek stav. Jedina zmena bola, ze som nahradil
<?php
require 'Nette/loader.php'
?>
s
<?php
require '../framewrks/nette/Nette/loader.php'
?>
co je moja lokacia nette frameworku.
EDIT: Mam nastavene aj zobrazovanie chyb v samotnom PHP.
EDIT 2: Prave sa pozeram na examples priamo v nette adresari a to iste sa deje aj pri odskusani basic-example.php
Miesto zobrazenia „Form was submitted and successfully validated“ dostanem bielu obrazovku.
Editoval daan (10. 6. 2009 18:42)

- _Martin_
 - Generous Backer | 679
 
Aj PHP 5.2.9 jsem stáhl a vše OK, to už mi hlava nebere, jdeme ořezávat – zkus samotné:
<?php
require '../framewrks/nette/Nette/loader.php';
Debug::enable();
$form = new Form;
$form ->addText('name','ID: ');
$form ->addPassword('pass','password: ');
$form ->addSubmit('login', 'login');
if ($form->isSubmitted()) {
	if ($form->isValid()) {
		$values = $form->getValues();
		echo 'Byl odeslan a je validni.';
		Debug::dump($values);
	} else {
		echo 'Byl odeslan, ale neni validni.';
	}
} else {
	echo 'Nebyl odeslan.';
}
echo $form;
Edit: ještě mě napadá, zkusil jsi Requirements Checker?
Editoval _Martin_ (10. 6. 2009 18:44)

- Patrik Votoček
 - Člen | 2221
 
A máš načtené dibi? nebo máš RobotLoader před tím než
voláš dibi::fetch…? Btw pokud používáš RobotLoader tak zkus
hodit za inicializaci $loader->rebuild(); jestli laděnka
nevyhodí nějákou chybu…

- _Martin_
 - Generous Backer | 679
 
daan napsal(a):
Class ‚dibi‘ not found
Používáš Nette RobotLoader?
ANO:
- zkontroluj, zda skenuješ i adresář, ve kterém je dibi umístěné
 
NE:
- buď načti soubor s dibi třídou ručně
 - nebo použij RobotLoader:
 
$loader = new RobotLoader();
$loader->addDirectory('cesta/ke/slozce/s/knihovnami');
$loader->register();
Složka s knihovnami může obsahovat složku Nette s Nette Frameworkem a složku dibi s (jak jinak) dibi, případně jakékoliv další knihovny (třeba nějaké části ze Zend Frameworku, vlastní knihovny, Texy,…).
Předpokládám, že v Nette ještě nevyužíváš funkci pro tvrobu MVC/MVP aplikace, takže ještě RobotLoader neznáš a neznáš ani soubor bootstrap.php – až se s ním seznámíš, zjistíš, že skenované cesty pro RobotLoader se dají nastavit i lehce jinak.