Formulář – validace na prvek v databázi

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

Ahoj potřebuji ověřit prvek formuláře (username) s databází. Zkouším pomocí validace srovnání s existujícím prvkem: ->addRule($form::NOT_EQUAL… ale jako prvek s kterým chci prvek porovnat je username umístěno v databázi, pokud se přímo do pravidla pokusím selectovat prvky z databáze to není zřejmě podporováno. Chtěl bych to udělat přes vlastní validační pravidlo validateSignInForm
, ale utíká mi jak můžu načíst username vložené do formuláře a porovnat ho s databází a v případě shody rovnou vypsat chybu nebo to udělat tak, že bych měl vytvořenou ještě jednu metodu, kde by se ověřilo username z formuláře s databází a poté se buď vypsala chyba nebo se hodnota vrátila k validaci do ->addRule($form::NOT_EQUAL, ‚Uživatel existuje‘, **PRVEK K OVĚŘENÍ S DB);*

Nebo pokud by jste mě odkázali na nějaký příklad práce formuláře s databází. Jsem v tu začátečník, děkuji za každý tip.

<?php

namespace App\Presenters;

use Nette,
    App\Model,
    Nette\Application\UI\Form;

/**
 * Homepage presenter.
 */
class HomepagePresenter extends BasePresenter {

    /** @var Nette\Database\Context */
    // navaze spojeni s databazi
    private $database;

    public function __construct(Nette\Database\Context $database) {
        $this->database = $database;
    }

    protected function createComponentCommentForm() {
        $form = new Form();
        $form->addText('username', 'Uživatelské jméno:')
                ->setRequired('Zadejte prosím jméno')
                ->setOption('description', 'Alespoň 6 znaků')
                ->addRule($form::NOT_EQUAL, 'Uživatel existuje', **PRVEK K OVĚŘENÍ S DB**);
        $form->addHidden('attribute')
                ->setDefaultValue('Password');
        $form->addText('fname', 'Jméno:')
                ->setRequired('Zadejte své jméno');
        $form->addText('lname', 'Příjmení:')
                ->setRequired('Zadejte své přijmení');
        $form->addPassword('value', 'Heslo:')
                ->setRequired('Zvolte si heslo')
                ->addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaky', 3);
        $form->addText('email', 'Email:')
                ->setEmptyValue('@')
                ->setType('email')
                ->addCondition($form::FILLED)
                ->setrequired('Zadejte Váš email')
                ->addRule($form::EMAIL, 'Zadejte platnou emailovou adresu')
                ->addRule($form::NOT_EQUAL, 'Emailová adresa je již registrována', **DRUHÝ PRVEK K OVĚŘENÍ S DB**);

        $form->addSubmit('send', 'Registrovat');
        $form->onSuccess[] = array($this, 'commentFormSucceeded');
        return $form;
    }

    public function commentFormSucceeded($form, $values) {
        //if($form['username']==);
        $this->database->table('radcheck')->insert(array(
            'username' => $values->username,
            'attribute' => $values->attribute,
            'value' => $values->value,
            'fname' => $values->fname,
            'lname' => $values->lname,
            'email' => $values->email,
        ));
        $this->flashMessage('Děkujeme za registraci', 'success');
        $this->redirect('this');
    }

    // OVĚŘIT username z formulare
	// TUHLE METODU MÁM JEN ODNĚKUD ZKOPÍROVANOU, TAKŽE NENÍ ANI DÁLE ŘEŠENA, ZKOUŠEL JSEM
	// SPOUSTY ŘEŠENÍ A U TÉTO JSEM ZKONČIL

    public function validateSignInForm($form) {
        $values = $form->getValues(TRUE);

        $overUsername = $this->database->query('SELECT * FROM radcheck WHERE username=? limit 1', $values['username'])->fetch();

        if ($overUsername===TRUE) { // validační podmínka
            $form->addError('Tato kombinace není možná.');
        }
        return $this->overUs = $values['username'];


    }

    //callback('CustomFormValidators::isInDatabase')

}
David Matějka
Moderator | 6445
+
+1
-

napis si vlastni validator:

->addRule(function ($control) {
	$username = $control->value;
	//tady provedes dotaz atd.

	return ...; //true kdyz uzivatelske jmeno je volne, jinak false
}, 'Uživatel existuje');
tomat
Člen | 16
+
0
-

Super díky za typ, takže můžu psát dotaz přímo do validace to jsem právě nevěděl jestli to lze, dík

tomat
Člen | 16
+
+1
-

Tak vyřešeno, přidávám svoje řešení kdyby se někomu hodilo:

->addRule(function ($control) {
                    $username = $control->value;
                    $shoda = $this->database->query('SELECT * FROM radcheck WHERE username=? limit 1', $username)->fetch();

                    if (!empty($shoda)) {
                        return FALSE;
                    } else {
                        return TRUE;
                    }
                }, 'Uživatel existuje')
Pavel Kravčík
Člen | 1196
+
0
-

@tomat: Můžeš si to i vytáhnout do funkce, což je pak čitelnější. V podstatě je to to samé, ale neměl bys psát dotazy rovnou do presenteru – v budoucnu se za to budeš nenávidět. :)

	->addRule(callback($this, 'isUsernameAvailable'), 'Uživatel existuje');
	public function isUsernameAvailable($control)
{
    return !$this->uzivatelModel->nameExist($name->control);
}
Mysteria
Člen | 797
+
+2
-
->addRule(function ($control) {
                    $username = $control->value;
                    $shoda = $this->database->query('SELECT * FROM radcheck WHERE username=? limit 1', $username)->fetch();

                    if (!empty($shoda)) {
                        return FALSE;
                    } else {
                        return TRUE;
                    }
                }, 'Uživatel existuje')

vs

->addRule(function ($control) {
	return !$this->database->query('SELECT username FROM radcheck WHERE username = ? LIMIT 1', $control->value)->fetch();
}, 'Uživatel existuje')
Pavel Kravčík
Člen | 1196
+
0
-

@Mysteria: Round 1. Fight!

greeny
Člen | 405
+
0
-

@Mysteria

->addRule(function ($control) {
    return !$this->userRepository->getByUsername($control->value);
}, 'Uživatel existuje')

nebo

->addRule(function ($control) {
    return !$this->userRepository->isUsernameRegistered($control->value);
}, 'Uživatel existuje')

Btw v některých starších verzích PHPčka nešlo používat $this v closure, takže ještě:

$self = $this;
// ...
->addRule(function ($control) use ($self) {
    return !$self->// ...
}, 'Uživatel existuje')
tomat
Člen | 16
+
0
-

No pěkný zkracovačky :) s programováním začínám a potřeboval jsem si zkusit v Nette alespoň ten formulář, takže jsem to zatím psal vše do jednoho souboru, ale vidím že v Nette to jde dost urychlit :)