Registrace – odeslání dat o uživateli do databáze

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

Dobrý den,

jsem začátečník a potřeboval bych poradit ohledně registrace uživatelů. Jedu podle quickstarteru , ale potřeboval bych upravit kód tak aby se mohli uživatelé registrovat. Ale nějak nevím jak poslat získaná data do databáze. Děkuji za radu.

Vytvořil jsem si tedy v databázi tabulku uživatelů Users.. Dále pak RegistrationPresenter, který obsahuje tento kód:

<?php

namespace App\Presenters;

use Nette\Security\User,
  Nette\Application\UI,
    Nette\Application\UI\Form as Form,
    Nette\Diagnostics\Debugger as Ndebug;

class RegistrationPresenter extends BasePresenter
{
    private $users;


    public function renderRegister(){
    }

    protected function createComponentRegistrationForm()
    {
        $form = new Form;
        $form->addText('name', 'Jméno');
        $form->addText('email', 'E-mail: *', 35)
                ->setEmptyValue('@')
                ->addRule(Form::FILLED, 'Vyplňte Váš email')
                ->addCondition(Form::FILLED)
                ->addRule(Form::EMAIL, 'Neplatná emailová adresa');
        $form->addPassword('password', 'Heslo: *', 20)
                ->setOption('description', 'Alespoň 6 znaků')
                ->addRule(Form::FILLED, 'Vyplňte Vaše heslo')
                ->addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaků.', 6);
        $form->addPassword('password2', 'Heslo znovu: *', 20)
                ->addConditionOn($form['password'], Form::VALID)
                ->addRule(Form::FILLED, 'Heslo znovu')
                ->addRule(Form::EQUAL, 'Hesla se neshodují.', $form['password']);
        $form->addSubmit('send', 'Registrovat');
        $form->onSuccess[] = callback($this, 'registrationFormSucceeded');
        return $form;
    }
    public function registrationFormSucceeded(UI\Form $form) {
    $values = $form->getValues();
	// získám hodnoty ale nevím jak dál
        $this->flashMessage('Registrace se zdařila.');
        $this->redirect('Sign:in');
    }
}
}
?>

Vytvořil jsem si v modelu Users.php:

<?php

namespace App\Model;

use Nette,
	Nette\Utils\Strings,
	Nette\Security\Passwords;

class Users extends \Nette\Object {

    private $database;
    private $table = "users";
    public static $user_salt = "AEcx199opQ";
/**
 * Users management.
 */
public function register($data) {
    unset($data["password2"]);
    $data["role"] = "guest";
    $data["password"] = sha1($data["password"] . self::$user_salt);
    return $this-> //nevím co dál
}
?>
Lukeluha
Člen | 130
+
0
-

Zaregistruj si třídu Users jako službu a pak pomocí DI tuto třídu vlož do presenteru. Poté jen zavoláš metodu register a předáš jí data z formuláře. Přečti si tady, tadytady

A pochvala za to, že se to nesnažíš dělat v presenteru, tato logika patří správně do modelu :)

Ještě jak si ten tvůj příspěvek čtu znovu, tak vidím, že nevíš ani jak pracovat s db. Na to si přečti tento, tento, tento a tento článek.

Editoval Lukeluha (26. 4. 2015 18:27)

duff123
Člen | 7
+
0
-

Díky za odpověď :) Zaregistroval jsem tedy třídu Users jako službu v config.neon…

<?php
services:
    - Users
?>

A pak ji vložím do presenteru…

<?php
private $users;

public function injectUsers(Users $user)
{
    $this->users = $user;
	//bude tu $user ?
}
?>

A pak ji budu nějak volat… Zatím správně ?

Editoval duff123 (26. 4. 2015 19:00)

David Kudera
Člen | 455
+
0
-

V konfiguraci ti chybí celý namespace pro Users. A taky by jsi neměl používat sha1, není to zrovna nejbezpečnější… Raději použij postup z nette sandboxu tady ;-)

Editoval David Kudera (26. 4. 2015 21:04)

Lukeluha
Člen | 130
+
0
-

Jak říká @DavidKudera – v configu nemáš celý namespace Users, mělo by být App\Model\Users. Dále je pak best practise v presenterech používat injektování pomocí @inject notace. Co se týče hashovacího algoritmu, pokud začínáš, sha1 pro začátek určitě stačí (navíc když hesla ještě solíš), pokud bys pak už dělal aplikace, které je potřeba mít super zabezpečené, tak určitě použít něco pokročilejšího, jako v sandboxu.

duff123
Člen | 7
+
0
-

Tak jsem to zkusil takhle:
Laďenka mi háže: Undefined variable: userManager

<?php

namespace App\Presenters;

use Nette\Security\User,
    Nette\Application\UI\Form as Form;

class RegistrationPresenter extends BasePresenter
{
    private $users;
    /**
    * @var \App\Model\UserManager
    * @inject
    */
    public $userManager;

    public function renderRegister(){
    }

    protected function createComponentRegistrationForm()
    {
        $form = new Form;
        $form->addText('name', 'Jméno');
        $form->addText('email', 'E-mail: *', 35)
                ->setEmptyValue('@')
                ->addRule(Form::FILLED, 'Vyplňte Váš email')
                ->addCondition(Form::FILLED)
                ->addRule(Form::EMAIL, 'Neplatná emailová adresa');
        $form->addPassword('password1', 'Heslo: *', 20)
                ->setOption('description', 'Alespoň 6 znaků')
                ->addRule(Form::FILLED, 'Vyplňte Vaše heslo')
                ->addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaků.', 6);
        $form->addPassword('password2', 'Heslo znovu: *', 20)
                ->addConditionOn($form['password1'], Form::VALID)
                ->addRule(Form::FILLED, 'Heslo znovu')
                ->addRule(Form::EQUAL, 'Hesla se neshodují.', $form['password1']);
        $form->addSubmit('send', 'Registrovat');
        $form->onSuccess[] = callback($this, 'registrationFormSucceeded');
        return $form;
    }

    // volá se po úspěšném odeslání formuláře
    public function registrationFormSucceeded(UI\Form $form) {
    $values = $form->getValues();
     if($values->password1 == $values->password2){
                    $user = new $this->$userManager;      //undefined variable
                    $user->add($values->username, $values->password1, $values->name);
        $this->flashMessage('Registrace se zdařila, jo!');
        $this->redirect('Sign:in');
        }
        else {
                    $this->flashMessage('Nepodařilo se, hesla se neshodují!');
    }
    }
}
?>

Editoval duff123 (27. 4. 2015 12:26)

David Kudera
Člen | 455
+
0
-

Takhle:

$user = $this->userManager;
David Kudera
Člen | 455
+
0
-

A ještě ověření shody hesel už máš v pravidlech na formuláři, takže na to nemusíš psát další podmínku při success ;-)

Jan Suchánek
Člen | 404
+
0
-

Na „Nepodařilo se, hesla se neshodují!“ máš blbě:

	// Zkus se mrknout do dokumentace
	$form->addPassword('passwordVerify', 'Heslo pro kontrolu:')
	->setRequired('Zadejte prosím heslo ještě jednou pro kontrolu')
	->addRule(Form::EQUAL, 'Hesla se neshodují', $form['password']);

Na jiné validace použij $form->onValidate[] nebo funkcí zavěšenou přímo na daný prvek nebo na $form->onClick[];

Edit: sakra už mě někdo předběhl :)

Editoval jenicek (27. 4. 2015 12:42)

duff123
Člen | 7
+
0
-

Díky, teď po odeslání formuláře mi to hodí chybu v laděnce…

Argument 1 passed to App\Model\UserManager::__construct() must be an instance of Nette\Database\Context, none given, called in C:\wamp\www\nette-blog\sandbox\app\presenters\RegistrationPresenter.php on line 46 and defined

<?php
23:        /** @var Nette\Database\Context */
24:        private $database;
25:
26:
27:        public function __construct(Nette\Database\Context $database)
28:        {
29:            $this->database = $database;
30:        }
?>
David Kudera
Člen | 455
+
0
-

Zkus smazat cache

duff123
Člen | 7
+
0
-

Nepomohlo mi to … Mám špatně nastavenou službu UserManager ? a snažím se dostat do RegistrationPresenter?

services
App\Model\UserManager

Editoval duff123 (27. 4. 2015 13:32)

David Kudera
Člen | 455
+
0
-

Nezkoušíš tam náhodou v tom presenteru vytvářet novou instanci té třídy? Máš si ji jen nechat injectnout a vytváření instancí služeb nechat na nette samotném

duff123
Člen | 7
+
0
-

Přesně tak, děkuju ti moc :)