2013-06-24 3 views
10

Ich möchte Form Validierungslogik trennen:Symfony 2 - Einzelformularlogik, zeigen Formfehler umleiten nach

public function contactAction() 
{ 
    $form = $this->createForm(new ContactType()); 

    $request = $this->get('request'); 
    if ($request->isMethod('POST')) { 
     $form->submit($request); 
     if ($form->isValid()) { 
      $mailer = $this->get('mailer'); 
      // .. setup a message and send it 

      return $this->redirect($this->generateUrl('_demo')); 
     } 
    } 

    return array('form' => $form->createView()); 
} 

ich in 2 separate Aktionen übersetzen:

public function contactAction() 
{ 
    $form = $this->createForm(new ContactType()); 
    return array('form' => $form->createView()); 
} 

public function contactSendAction() 
{ 
    $form = $this->createForm(new ContactType()); 
    $request = $this->get('request'); 
    if ($request->isMethod('POST')) { 
     $form->submit($request); 
     if ($form->isValid()) { 
      $mailer = $this->get('mailer'); 
      // .. setup a message and send it using 

      return $this->redirect($this->generateUrl('_demo')); 
     } 
    } 
    // errors found - go back 
    return $this->redirect($this->generateUrl('contact')); 
} 

Das Problem ist, dass wenn Fehler im Formular vorhanden sind - nach Formularvalidierung und Weiterleitung wurde das NICHT in der KontaktAktion angezeigt. (wahrscheinlich werden sie nach Umleitung bereits vergessen - Fehlerkontext wird verloren gehen)

Antwort

6

Wenn Sie herausfinden, wie der von CRUD generator generierte Code dies handhabt, sehen Sie, dass eine fehlgeschlagene Formularvalidierung keine Umleitung zurückgibt, sondern stattdessen die gleiche Ansicht wie die GET Methode. Also in Ihrem Beispiel würden Sie einfach:

anstatt die Umleitung zurückgeben. Das bedeutet, dass Sie die Formularfehler nicht wie bei einer Weiterleitung verlieren. Etwas anderes, das der CRUD-Generator hinzufügt, ist die Method requirement, was bedeutet, dass Sie angeben können, dass die ContactSendAction die POST Methode benötigt und daher die zusätzliche if($request->isMethod('POST')){ Anweisung nicht benötigt.

Sie können auch nur ein Array zurück, wenn Sie die Vorlage an anderer Stelle angeben, zum Beispiel Sie die @Template annotation verwenden könnten und dann nur

return array('form' => $form->createView()) 
+0

vielen Dank für Informationen über die Methodenanforderung und die Verwendung der Rückansicht anstelle der Weiterleitung. Aber wenn ich stattdessen view verwende, wird es genauso sein wie es war - 2 Logiken sind nicht mehr getrennt. Gibt es eine Möglichkeit, Redirect zu verwenden und Formularfehler nicht zu verlieren? – pleerock

+0

Umleiten und nicht verlieren Formulardaten scheint nicht die richtige Idee. Sie könnten die Fehler in der Sitzung festlegen und sie dem Formular hinzufügen, aber das ist voller möglicher Fehler. Wovon versuchst du durch die logische Trennung zu kommen? Sie könnten $ this-> contactAction(); 'zurückgeben, wenn Sie das wollten? – Luke

+0

Sorry, mein letzter Kommentar zu return $ this-> contactAction(); war mir spit-balling und nicht gut überlegt – Luke

2

Das ist für mich in Symfony scheint zu funktionieren 2.8:

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class MyController extends Controller { 
    public function templateAction() 
    { 
     $form = $this->createForm(new MyFormType(), $myBoundInstance); 

     if ($session->has('previousRequest')) { 
      $form = $this->createForm(new MyFormType()); 
      $form->handleRequest($session->get('previousRequest')); 
      $session->remove('previousRequest'); 
     } 

     return array(
      'form' => $form->createView(), 
     ); 
    } 

    public function processingAction(Request $request) 
    { 

     $form = $this->createForm(new MyFormType(), $myBoundInstance); 
     $form->handleRequest($request); 

     if ($form->isValid()) { 
      // do some stuff 
      // ... 

      return redirectToNextPage(); 
     } 

     $session->set('previousRequest', $request); 

     // handle errors 
     // ... 

     return redirectToPreviousPage(); 
    } 
} 

Bitte beachten Sie, dass redirectToNextPage und redirectToPreviousPage, sowie MyFormType, Pseudocode sind. Sie müssten diese Bits durch Ihre eigene Logik ersetzen.