An errorred form is now passed to the Form smarty plugin through the parser context instead of the

session
This commit is contained in:
franck
2013-07-24 17:31:20 +02:00
parent 7498c97f49
commit fabeab1822
13 changed files with 160 additions and 94 deletions

View File

@@ -67,9 +67,9 @@ class Customer implements EventSubscriberInterface
$request = $event->getRequest();
$customerCreation = new CustomerCreation($request);
$customerCreationForm = new CustomerCreation($request);
$form = $customerCreation->getForm();
$form = $customerCreationForm->getForm();
if ($request->isMethod("post")) {
@@ -98,7 +98,7 @@ class Customer implements EventSubscriberInterface
$event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECUSTOMER, $event);
// Connect the newly created user,and redirect to the success URL
$this->processSuccessfulLogin($event, $customer, $customerCreation, true);
$this->processSuccessfulLogin($event, $customer, $customerCreationForm, true);
} catch (PropelException $e) {
Tlog::getInstance()->error(sprintf('error during creating customer on action/createCustomer with message "%s"', $e->getMessage()));
@@ -114,9 +114,15 @@ class Customer implements EventSubscriberInterface
$message = "Wrong form method !";
}
$this->parserContext->set('customer_creation_error_message', $message);
// The form has an error
$customerCreationForm->setError(true);
$customerCreationForm->setErrorMessage($message);
$event->setFormError($customerCreation);
// Store the form in the parser context
$this->parserContext->setErrorForm($customerCreationForm);
// Stop event propagation
$event->stopPropagation();
}
public function modify(ActionEvent $event)
@@ -130,6 +136,7 @@ class Customer implements EventSubscriberInterface
$form = $customerModification->getForm();
if ($request->isMethod("post")) {
$form->bind($request);
if ($form->isValid()) {
@@ -172,9 +179,15 @@ class Customer implements EventSubscriberInterface
$message = "Wrong form method !";
}
$this->parserContext->set('customer_change_error_message', $message);
// The form has an error
$customerModification->setError(true);
$customerModification->setErrorMessage($message);
$event->setFormError($customerModification);
// Store the form in the parser context
$this->parserContext->setErrorForm($customerModification);
// Stop event propagation
$event->stopPropagation();
}
@@ -202,14 +215,14 @@ class Customer implements EventSubscriberInterface
{
$request = $event->getRequest();
$form = new CustomerLogin($request);
$customerLoginForm = new CustomerLogin($request);
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $form);
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
try {
$user = $authenticator->getAuthentifiedUser();
$this->processSuccessfulLogin($event, $user, $form);
$this->processSuccessfulLogin($event, $user, $customerLoginForm);
}
catch (ValidatorException $ex) {
$message = "Missing or invalid information. Please check your input.";
@@ -224,11 +237,12 @@ class Customer implements EventSubscriberInterface
$message = sprintf("Unable to process your request. Please try again (%s in %s).", $ex->getMessage(), $ex->getFile());
}
// Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$request->getSession()->setErrorFormName($form->getName());
// The for has an error
$customerLoginForm->setError(true);
$customerLoginForm->setErrorMessage($message);
// Put the message in the ParserContext to make it available to the template
$this->parserContext->set('customer_login_error_message', $message);
// Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$this->parserContext->setErrorForm($customerLoginForm);
// A this point, the same view is displayed again.
}

View File

@@ -36,6 +36,7 @@ use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\SecurityContext;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext;
/**
*
@@ -100,6 +101,16 @@ class BaseAdminController extends ContainerAware
}
}
/**
* Return the parser context,
*
* @return ParserContext
*/
protected function getParserContext($context = false)
{
return $this->container->get('thelia.parser.context');
}
/**
* Return the security context, by default in admin mode.
*

View File

@@ -49,11 +49,11 @@ class SessionController extends BaseAdminController {
public function checkLoginAction()
{
$form = new AdminLogin($this->getRequest());
$adminLoginForm = new AdminLogin($this->getRequest());
$request = $this->getRequest();
$authenticator = new AdminUsernamePasswordFormAuthenticator($request, $form);
$authenticator = new AdminUsernamePasswordFormAuthenticator($request, $adminLoginForm);
try {
$user = $authenticator->getAuthentifiedUser();
@@ -65,7 +65,7 @@ class SessionController extends BaseAdminController {
AdminLog::append("Authentication successuful", $request, $user);
// Redirect to the success URL
return Redirect::exec($form->getSuccessUrl());
return Redirect::exec($adminLoginForm->getSuccessUrl());
}
catch (ValidatorException $ex) {
@@ -87,12 +87,14 @@ class SessionController extends BaseAdminController {
$message = "Unable to process your request. Please try again.";
}
// Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$request->getSession()->setErrorFormName($form->getName());
// Store error information in the form
$adminLoginForm->setError(true);
$adminLoginForm->setErrorMessage($message);
// Display the login form again, with an error message if required
return $this->render("login.html", array(
"message" => $message
));
// Store the form name in session (see Form Smarty plugin to find usage of this parameter)
$this->getParserContext()->setErrorForm($adminLoginForm);
// Display the login form again
return $this->render("login.html");
}
}

View File

@@ -102,6 +102,8 @@
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="request"/>
<argument type="service" id="thelia.parser.context"/>
<call method="setFormDefinition">
<argument>%thelia.parser.forms%</argument>
</call>

View File

@@ -79,33 +79,4 @@ abstract class ActionEvent extends Event
{
return $this->request;
}
/**
* Store a form taht contains error, to pass it to the current session.
*
* @param BaseForm $form
*/
public function setFormError(BaseForm $form)
{
$this->form = $form;
$this->stopPropagation();
}
/**
* @return BaseForm the errored form, or null
*/
public function getFormError()
{
return $this->form;
}
/**
* Check if theis event contains a form with errors
*
* @return boolean
*/
public function hasFormError()
{
return $this->form !== null;
}
}

View File

@@ -49,10 +49,6 @@ class ControllerListener implements EventSubscriberInterface
$event = new ActionEventFactory($request, $action, $event->getKernel()->getContainer()->getParameter("thelia.actionEvent"));
$actionEvent = $event->createActionEvent();
$dispatcher->dispatch("action.".$action, $actionEvent);
if ($actionEvent->hasFormError()) {
$request->getSession()->setErrorFormName($actionEvent->getFormError()->getName());
}
}
}

View File

@@ -77,26 +77,6 @@ class Session extends BaseSession {
return $this->remove('admin_user');
}
// -- Error form -----------------------------------------------------------
/**
* @param string $formName the form name
*/
public function setErrorFormName($formName)
{
$this->set('error_form', $formName);
}
public function getErrorFormName()
{
return $this->get('error_form', null);
}
public function clearErrorFormName()
{
return $this->remove('error_form');
}
// -- Return page ----------------------------------------------------------
public function setReturnToUrl($url)

View File

@@ -26,6 +26,7 @@ namespace Thelia\Core\Template;
use Thelia\Model\ConfigQuery;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Tools\URL;
use Thelia\Form\BaseForm;
/**
* The parser context is an application-wide context, which stores var-value pairs.
* Theses pairs are injected in the parser and becomes available to the templates.
@@ -46,6 +47,28 @@ class ParserContext implements \IteratorAggregate
;
}
// -- Error form -----------------------------------------------------------
/**
* @param BaseForm $form the errored form
*/
public function setErrorForm(BaseForm $form)
{
$this->set('error_form', $form);
}
public function getErrorForm()
{
return $this->get('error_form', null);
}
public function clearErrorForm()
{
return $this->remove('error_form');
}
// -- Internal table manipulation ------------------------------------------
public function set($name, $value)
{
$this->store[$name] = $value;
@@ -53,9 +76,16 @@ class ParserContext implements \IteratorAggregate
return $this;
}
public function get($name)
public function remove($name)
{
return $this->store[$name];
unset($this->store[$name]);
return $this;
}
public function get($name, $default = null)
{
return isset($this->store[$name]) ? $this->store[$name] : $default;
}
public function getIterator()

View File

@@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Log\Tlog;
use Thelia\Core\Template\ParserContext;
/**
*
@@ -58,12 +59,14 @@ class Form implements SmartyPluginInterface
{
protected $request;
protected $parserContext;
protected $formDefinition = array();
public function __construct(Request $request)
public function __construct(Request $request, ParserContext $parserContext)
{
$this->request = $request;
$this->parserContext = $parserContext;
}
public function setFormDefinition($formDefinition)
@@ -88,21 +91,23 @@ class Form implements SmartyPluginInterface
$instance = $this->createInstance($params['name']);
// Check if session contains our form
$errorForm = $this->request->getSession()->getErrorFormName();
// Check if parser context contains our form
$errorForm = $this->parserContext->getErrorForm();
if ($errorForm == $instance->getName()) {
if (null != $errorForm && $errorForm->getName() == $instance->getName()) {
// Bind form with current request to get error messages and field values.
$instance->getForm()->bind($this->request);
// Re-use the errored form
$instance = $errorForm;
// Remove the form from the session
$this->request->getSession()->clearErrorFormName();
$this->parserContext->clearErrorForm();
}
$instance->createView();
$template->assign("form", $instance);
$template->assign("form_error", $instance->hasError() ? true : false);
$template->assign("form_error_message", $instance->getErrorMessage());
}
else {
return $content;

View File

@@ -46,6 +46,18 @@ abstract class BaseForm {
private $view = null;
/**
* true if the form has an error, false otherwise.
* @var boolean
*/
private $has_error = false;
/**
* The form error message.
* @var string
*/
private $error_message = '';
public function __construct(Request $request, $type= "form", $data = array(), $options = array())
{
$validator = Validation::createValidator();
@@ -110,6 +122,48 @@ abstract class BaseForm {
return $this->view;
}
// -- Error and errro message ----------------------------------------------
/**
* Set the error status of the form.
*
* @param boolean $has_error
*/
public function setError($has_error = true)
{
$this->has_error = $has_error;
}
/**
* Get the cuirrent error status of the form.
*
* @return boolean
*/
public function hasError()
{
return $this->has_error;
}
/**
* Set the error message related to global form error
*
* @param unknown $message
*/
public function setErrorMessage($message)
{
$this->error_message = $message;
}
/**
* Get the form error message.
*
* @return string
*/
public function getErrorMessage()
{
return $this->error_message;
}
/**
* @return \Symfony\Component\Form\Form
*/

View File

@@ -16,7 +16,7 @@
{form name="thelia.admin.login" success_url="home" error_url="login"}
<form action="{url path='/admin/checklogin'}" method="post" class="well form-inline" {form_enctype form=$form}>
{if isset($message)}<div class="alert alert-error">{$message}</div>{/if}
{if #form_error}<div class="alert alert-error">#form_error_message</div>{/if}
{form_hidden_fields form=$form}

View File

@@ -21,11 +21,12 @@
{/form_field}
{*
customer_creation_error_message is defined in Customer action processor class,
and passed the parser through the ParserContext service.
The form error status and the form error messages are defined in Customer action,
and passed back to the form plugin through the ParserContext.
*}
{if isset($customer_creation_error_message)}<div class="alert alert-error">{$customer_creation_error_message}</div>{/if}
{if #form_error}<div class="alert alert-error">#form_error_message</div>{/if}
{form_hidden_fields form=$form}

View File

@@ -24,11 +24,11 @@
{/form_field}
{*
customer_login_error_message is defined in Customer action processor class,
and passed the parser through the ParserContext service.
The form error status and the form error messages are defined in Customer action,
and passed back to the form plugin through the ParserContext.
*}
{if isset($customer_login_error_message)}<div class="alert alert-error">{$customer_login_error_message}</div>{/if}
{if #form_error}<div class="alert alert-error">#form_error_message</div>{/if}
{form_hidden_fields form=$form}