Odeslání formuláře přímo do modelu ($form->onSuccess[])

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

Dobrý den,
při vytváření formuláře na změnu hesla jsem narazil na jeden problém. Formulář první projde validací:

$form->onValidate[]

a potom chci provést samotnou změnu hesla v databázi, jenže když dám:

$form->onSuccess[] = $this->some_model->changePassword($form->getValues()->password)

vyhodí to chybu se špatným callbackem. Vytvářet navíc jednu funkci která jen hodí hodnotu do modelu se mi nechce a volat funkci z modelu při validaci mi přijde divné. Taky by mě zajímalo jak by se dal zobrazit error když se při ukládaní hesla něco „posere“.

Presenter

protected function createComponentPasswordSettings()
	{
		$form = new UI\Form;
		$form->setTranslator($this->translator);

		$form->addProtection("Request timed out, please try again!", 180);

		$form->addPassword('oldpassword','Old password');

		$form->addPassword('newpassword','New password');

		$form->addPassword('verification','Repeat password');


		$form->addSubmit('submit','Save');
		$form->addButton('reset','Reset')
			  ->setAttribute('type','reset');

		$form->onValidate[] = $this->validatePasswordSettings;
		$form->onSuccess[] = $this->account->changePassword;
		return $form;
	}

	public function validatePasswordSettings($form)
	{
		$values = $form->getValues();
		$user = $this->getUser()->identity->data;

		if (crypt($values->oldpassword, $user['password']) != $user['password'])
			$form->addError($this->translator->translate("Old password does not match current password!"));

		if (!preg_match("/[0-9]{2,}/", $values->newpassword) ||	// contains at least two numbers
		    !preg_match("/[A-Z]+/", $values->newpassword) ||		// contains at least one capital letter
		    strlen($values->newpassword) < 8)				// is at least 8 characters long
			$form->addError($this->translator->translate ("Safe password should contain at least 8 characters 2 numbers and 1 capital letter!"));

		if ($values->newpassword !== $values->verification)
			$form->addError($this->translator->translate ("Verification does not match new password you entered below!"));
	}
saimons
Člen | 293
+
0
-

Me to cele pripada takove divne navrzene, vsechny ty validace, ktere provadis muzes napsat primo k jednotlivym prvkum formulare pres ->addRule(Form::PATTERN,..), i treba porovnani spravnosti zadaneho noveho hesla. Je to popsane v dokumentaci a potom take v presenteru porovnavat stare heslo, je take divne. Staci to predat do modelu a tam si predas tridu User a vyhodnotis. Stejne budes potrebovat tyto data pro praci s DB. Mit stare heslo v $this->getUser()->identity je jeste zvlastneji, to by se melo nacist z DB v modelu.

Filip Procházka
Moderator | 4668
+
0
-

Vytvářet navíc jednu funkci která jen hodí hodnotu do modelu se mi nechce

Smůla, budeš muset. Když nic jiného, tak minimálně closuru.

$form->onSuccess[] = function ($form) {
	$this->someModel->changePassword($form->getValues()->password);
};

Samozřejmě to vyžaduje PHP >= 5.4

VojtaSim
Člen | 55
+
0
-

Filip Procházka napsal(a):

$form->onSuccess[] = function ($form) {
	$this->someModel->changePassword($form->getValues()->password);
};

To už vypadá lépe, PHP 5.4 je u mě na localhostu i na hostingu standart takže není problém.
Díky za radu ;-)

hAssassin
Člen | 293
+
0
-

@Filip Procházka > proc >= 5.4? Nejsou closury uz v 5.3?

@VojtaSim > jak uz bylo receno, mas to nejaky divny. proc mas onValidate a onSuccess? Nestacilo by jen onSuccess a z neho pak dotazovat na model a pripadne vyhazovat chyby? Samotnou validaci, opet uz bylo receno, nech primo na formulari, ne?

integer
Člen | 6
+
0
-

hAssassin napsal(a):

@Filip Procházka > proc >= 5.4? Nejsou closury uz v 5.3?

Problem je v tom $this uvnitr, to podporuje az 5.4

Marek Šneberger
Člen | 130
+
0
-

integer napsal(a):
Problem je v tom $this uvnitr, to podporuje az 5.4

$that = $this;
$form->onSuccess[] = function ($form) use ($that) {
  $that->someModel->changePassword($form->getValues()->password);
};
hAssassin
Člen | 293
+
0
-

@integer > jo sem slepej, diky :-)

VojtaSim
Člen | 55
+
0
-

@saimons >
@hAssassin > jak by jste udělali validaci aby se prvky newpassword a verification rovnaly. V dokumentaci jsem našel jen ->addConditionOn ve které se můžu odkazovat jiné prvky formuláře, ale to je jen podmínka ne pravidlo, které by hodilo chybu.

Editoval VojtaSim (22. 4. 2013 6:46)

Šaman
Člen | 2666
+
0
-
<?php
$form->addPassword('passwordVerify', 'Heslo pro kontrolu:')
    ->setRequired('Zadejte prosím heslo ještě jednou pro kontrolu')
    ->addRule(Form::EQUAL, 'Hesla se neshodují', $form['password']);
?>

Je to v dokumentaci, kousek nad tímto.

VojtaSim
Člen | 55
+
0
-

Šaman napsal(a):

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

Je nějak možné do toho přidat šifrování? e.g. když porovnávám staré heslo s heslem v databázi, které získám z modelu?

->addRule(Form::EQUAL, 'Super hláška!', $this->account->getPassword());

Editoval VojtaSim (22. 4. 2013 14:39)

saimons
Člen | 293
+
0
-

Myslim, ze by to slo nejak pres vlastni validace: https://doc.nette.org/cs/forms#…, ale ja osobne bych to resil v modelu.

VojtaSim
Člen | 55
+
0
-

Ještě jeden dotaz. Nemohl jsem nikde najít opak metody addError() pro přidání úspěšného hlášení. Používat nějak proměnné v šabloně nebo je na to taky nějaká metoda?

saimons
Člen | 293
+
0
-

Ja teda jak pro spravne, tak i zaporne zpravy pouzivam $this->flashMessage(‚Šptně.‘);, jako druhy parametr muzes urcit tridu pro CSS.