Program flow u odeslání formuláře (nefunkční redirect)
- Dtx
- Člen | 17
Zdravím,
mám problém s redirectem pomocí $this->redirect(..) po odeslání formuláře. Postupoval jsem podle quickstartu, kód mám tedy velmi podobný:
Vytvoření formuláře – createComponentEditnoteForm()
protected function createComponentEditnoteForm($name)
{
$note = $this->getCurrentNote();
$form = new AppForm($this, $name);
$form->addText('name', 'Nadpis', 80)
->addRule(Form::FILLED, 'Vyplňte nadpis.')
->setDefaultValue($note->name);
$form->addHidden('id')
->setDefaultValue($this->request->params['id']);
$form->addSubmit('submitter', 'Uložit');
$form->onSubmit[] = array($this, 'processEditnoteForm');
return $form;
}
Zpracování odeslaného formuláře – processEditnoteForm()
public function processEditnoteForm(AppForm $form)
{
if($form->isSubmitted() && $form->isValid()) {
$values = $form->getValues();
$notes = new Notes();
$notes->id = $values['id'];
$notes->name = $values['name'];
$notes->owner_id = $this->user->getIdentity()->id;
$notes->save();
}
$this->redirect('Notes:list'); // Toto vyhodi vyjimku
}
Metody render a action:
public function actionEdit()
{
$this->template->form_editnote = $this->createComponentEditnoteForm('editnote');
}
public function renderEdit()
{
$this->template->note = $this->getCurrentNote();
}
Ten redirect na konci metody processEditnoteForm() vyhodí výjimku Cannot set HTTP code after HTTP headers have been sent (output started at ../app/AdminModule/presenters/NotesPresenter.php:131).
Zmiňovaný řádek 131 se vyskytuje v metodě createComponentEditnoteForm() a konkrétně obsahuje toto:
$form->addText('name', 'Nadpis', 80)
->addRule(Form::FILLED, 'Vyplňte nadpis.')
->setDefaultValue($note->name);
Může mi někdo prosím vysvětlit, jaktože se to po odeslání formu, kdy se má provést redirect, znova dostane do metody pro vykreslení tohoto formuláře? Zřejmě toto vykreslení způsobuje ten *Headers allready sent *error. Zřejmě mám v návrhu něco špatně? V tom případě prosím o navedení na správnou cestu.
- TomasTB
- Člen | 13
Schovej si laděnku, nebo si zobraz zdrojak stranky, pravdepodobne tam budes mit nejaky notices … ty oprav a bude ti fungovat presmerovani. Mas to dokonce napsano v hlasce.
Cannot set HTTP code after HTTP headers have been sent (output started at ../app/AdminModule/presenters/NotesPresenter.php:131).
- Dtx
- Člen | 17
No, chápu, že je před tím zavoláním metody $this->redirect() vyblit nějaký výstup do prohlížeče, což způsobuje tuto chybu. Jak jsme již uvedl, ten výpis provádí metoda createComponentEditnoteForm(). Měl jsem za to, že se po odeslání formuláře zavolá rovnou metoda processEditnoteForm(). Ale bohužel se tak zjevně neděje, a volá se znovu výše uvedená metoda pro vykreslení formuláře a teprve poté metoda pro zrpacování formuláře. Tady prostě něco nehraje O_o
Když to metody createComponentEditnoteForm() dám podmínku, aby se formulář vytvářel jen pokud není nic v _POSTu, tak to prozměnu s úplně stejnou chybou, tentokrát ale označující jiný řádek v metodě pro zpracování formuláře. Toto už je pro mě ale naprosto nepochopitelné, protože na odkazovaném řádku se nachází přiřazení hodnoty z odeslaného formuláře do objektu, který by měl být následně uložen.
Jedná se o řádek v této metodě:
public function processEditnoteForm(AppForm $form)
{
$form->setDefaults(array(
'publish' => new DateTime()
));
if($form->isSubmitted() && $form->isValid()) {
$values = $form->getValues();
$notes = new Notes();
$notes->id = $values['id']; // ### TENTO RADEK JE OZNACEN, ZE POSLAL NECO NA VYSTUP
$notes->name = $values['name'];
$notes->text = $values['text'];
$notes->publish = Date("Y-m-d 00:00:00", strtotime($values['publish']));
$notes->owner_id = $this->user->getIdentity()->id;
$notes->save();
}
$this->redirect('Notes:list');
//$this->redir(WEB_URL . 'admin/notes');
}
Pokud ten řádek zakomentím, přeskočí chyba o řádek dále, takže prostě toto přiřazení hodnoty z formuláře do objektu zřejmě něco vypisuje.. nebo už nevím :|
- Dtx
- Člen | 17
Mezeru jsem hledal, neúspěšně. Ten projektík obsahuje jen pár souborů, takže jsem snad žádnou nepřehlédl.
Zdroják tohoto presenteru je na http://pastebin.com/AxTDwvaC
Ty zavináče pošprtám, ale tohle by mělo (snad) fungovat i bez nich, nebo je ten tutoš, podle kterýho jsem to dělal, na nic.
- Dtx
- Člen | 17
Ano, vypisuje. Chybu, že neexistuje index ‚id‘, atd.. Ten neexistuje,
protože jsem dal vytvoření formuláře do podmínky na !$_POST. Takže to
jsem vrátil zpět. A už jsem přišel na chybu. Ono je totiž asi (určitě)
správně, že se po odeslání formu znova zavolá
createComponentEditnoteForm(). Já v této metodě ale mám
vlastní metodu
$note = getCurrentNote(); v kteréžto loaduju aktuální
poznámku podle ID zadaného v url. Jenže url po odeslání formuláře už
vypadá jinak a ID se v něm nevyskytuje, což vyhodí chybu, tedy výstup do
prohlížeče a Headers jsou hnedle sent :) Tak se omlouvám za svou hysterii,
chyba byla samozřejmě mezi mou klávesnicí a židlí.
Editoval Dtx (14. 12. 2010 12:41)