Jak nesmazat hodnotu atributu třídy při zavolání onSuccess
- rohlenzi
- Člen | 12
Ahoj,
chtěl bych se zeptat, jestli jde nějak předat parametrem hodnotu skrze metodu
onSuccess. Konkrétně mi tedy jde o to, že při potvrzení druhého
formuláře a následném zavoláním metody onSuccess se nejspíš refreshne
stránka a já ztratím hodnotu uloženou v $this->reviewId, tudíž nemohu
určit do jakého řádku databáze data odeslat.
Algoritmus by měl být takový, že uživatel zadá heslo a díky němu se mu otevře druhý formulář pro napsání recenze, kde následnou recenzi odešle.
<?php
declare(strict_types=1);
namespace App\Presenters;
use Nette;
use Nette\Utils\Random;
use Nette\Application\UI\Form;
use Nette\Database\Explorer;
class ReviewPresenter extends BasePresenter {
private $reviewId;
public function createComponentReviewPass(): Form {
$form = new Form;
$form->setMethod("GET");
$form->addText('pass', 'Heslo..')
->setRequired();
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'reviewPassSucceeded'];
return $form;
}
public function reviewPassSucceeded(array $values): void {
$reviews = $this->database->query('SELECT * FROM review');
foreach ($reviews as $review) {
if ($review->pass == $_GET['pass']) {
$this->reviewId = $review->ID_r;
dump($this->reviewId);
$this->forward('Review:reviewForm');
}
}
}
public function createComponentReviewForm(): Form {
$form = new Form;
$form->addInteger('summary', 'Ohodnoť x z 5 hvězdiček')
->setRequired()
->addRule($form::RANGE, 'Rozmezí musí být 1 - 5', [1, 5]);
$form->addText('description', 'Shrnutí recenze..');
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'reviewSucceeded'];
return $form;
}
public function reviewSucceeded(array $values): void {
$review = $this->database->query('UPDATE review SET', [
'summary' => $values['summary'],
'description' => $values['description']
], 'WHERE ID_r = ?', $this->reviewId);
$this->flashMessage('Recenze byla úspěšně přidána');
//$this->redirect('Homepage:default');
dump($this->reviewId);
}
}
- Kamil Valenta
- Člen | 822
Není dobré předávat heslo GETem. Odešli ho POSTem a výsledek „odemčení“ si poznač do sessiony.
$reviews = $this->database->query('SELECT * FROM review');
foreach ($reviews as $review) {
if ($review->pass == $_GET['pass']) {
Proč rovnou neděláš v selectu WHERE? Raději budeš procházet milion záznamů, aby sis 1 nechal a zbytek zahodil?
- dakur
- Člen | 493
@rohlenzi Neznám signatury action/render metod (tj. jaké parametry
očekávají), ale myslím, že by mělo stačit předat to
$this->reviewId
do forward()
:
$this->forward('Review:reviewForm', ['reviewId' => $this->reviewId]);
forward()
je de facto redirect, akorát takový interní bez
vnějšího efektu (tj. přesměrování) – potřebuje tedy všechny
parametry.
Dále, pokud reviewId
není součástí routy, budeš muset
ještě do toho druhého formuláře přidat hidden field s
reviewId
, které si potom v onSuccess
vytáhneš:
public function createComponentReviewForm(): Form {
$form = new Form;
$form->addInteger('summary', 'Ohodnoť x z 5 hvězdiček')
->setRequired()
->addRule($form::RANGE, 'Rozmezí musí být 1 - 5', [1, 5]);
$form->addText('description', 'Shrnutí recenze..');
$form->addHidden('reviewId', $this->reviewId);
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = [$this, 'reviewSucceeded'];
return $form;
}
public function reviewSucceeded(array $values): void {
$review = $this->database->query('UPDATE review SET', [
'summary' => $values['summary'],
'description' => $values['description']
], 'WHERE ID_r = ?', $values['reviewId']);
$this->flashMessage('Recenze byla úspěšně přidána');
//$this->redirect('Homepage:default');
dump($values['reviewId']);
}
Jinak s tím heslem má @KamilValenta pravdu – jakmile ho máš v URL, může si ho jednak přečíst kdokoliv, kdo se ti koukne přes rameno, a navíc nezapomeň, že navštívené URL adresy zůstávají v historii prohlížeče.
Editoval dakur (11. 6. 2021 7:24)
- Kamil Valenta
- Člen | 822
dakur napsal(a):
public function reviewSucceeded(array $values): void { $review = $this->database->query('UPDATE review SET', [ 'summary' => $values['summary'], 'description' => $values['description'] ], 'WHERE ID_r = ?', $values['reviewId']); $this->flashMessage('Recenze byla úspěšně přidána'); //$this->redirect('Homepage:default'); dump($values['reviewId']); }
Tady ještě pozor, ne vždy (ale neznáme širší kontext) je možné / dobré slepě věřit ID z hiddenu. Pokud např. uživatel může hodnotit jen k některým ID (selektováno bylo v předchozím kroku), zde by mělo být ověření, zda to ID pochází z množiny, ke kterým má uživatel přístup. Protože ID v hiddenu se dá snadno podvrhnout…