Program flow u odeslání formuláře (nefunkční redirect)

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

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.

natrim
Člen | 73
+
0
-

místo

<?php
$this->template->form_editnote = $this->createComponentEditnoteForm('editnote');
?>

použij

<?php
    $this->template->form_editnote = $this['editnoteForm'];
?>

nebo

<?php
    $this->template->form_editnote = $this->getComponent('editnoteForm');
?>
Dtx
Člen | 17
+
0
-

Zajímavé, určitě to zkrátí zápis kódu. Díky za tip, nicméně to neřeší můj problém s redirectem :|

Aurielle
Člen | 1281
+
0
-

Není to „zajímavé“, protože to krátí zápis. Nesprávně to používáš a proto máš použít array přístup nebo getComponent.

Dtx
Člen | 17
+
0
-

Já jsem asi měl uvést, že jsem oba doporučované příklady vyzkoušel (jak array, tak getComponent), ale stále to vypisuje stejnou chybu. Takže problém bude asi jinde(?)

TomasTB
Člen | 13
+
0
-

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).

natrim
Člen | 73
+
0
-

Nemohl by jsi někam upnout celej ten příklad kterej ti nefunguje? Takto je težké poznat v čem jimém by mohl být problém.

Možná pokud jsi na 0.9 tak zavináče

Nebo jestli jsi někde nenechal mezeru, která se vypíše.

Dtx
Člen | 17
+
0
-

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
+
0
-

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.

natrim
Člen | 73
+
0
-

nevypisuje ci nehlasi neco ta trida ‚Notes‘ ?

Dtx
Člen | 17
+
0
-

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)

natrim
Člen | 73
+
0
-

ok hlavne ze si na to prisel .)

ps: pokud si das $id do render i action jako to mas u toho handleDelete tak budes mit to id dostupne i po odeslani formulare

Dtx
Člen | 17
+
0
-

Super, to předávání id jsem právě chtěl vyřešit nějak „důstojněji“, díky za radu!