From fabeab182234c2581b393d0c51c9c52de2cb09ab Mon Sep 17 00:00:00 2001 From: franck Date: Wed, 24 Jul 2013 17:31:20 +0200 Subject: [PATCH] An errorred form is now passed to the Form smarty plugin through the parser context instead of the session --- core/lib/Thelia/Action/Customer.php | 42 ++++++++++----- .../Admin/Controller/BaseAdminController.php | 11 ++++ .../Admin/Controller/SessionController.php | 20 +++---- core/lib/Thelia/Config/Resources/config.xml | 2 + core/lib/Thelia/Core/Event/ActionEvent.php | 29 ---------- .../Core/EventListener/ControllerListener.php | 4 -- .../Core/HttpFoundation/Session/Session.php | 20 ------- .../Thelia/Core/Template/ParserContext.php | 34 +++++++++++- .../Core/Template/Smarty/Plugins/Form.php | 23 ++++---- core/lib/Thelia/Form/BaseForm.php | 54 +++++++++++++++++++ templates/admin/default/login.html | 2 +- templates/default/connexion.html | 7 +-- templates/default/login.html | 6 +-- 13 files changed, 160 insertions(+), 94 deletions(-) diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 4339ba4e3..53d9a4c69 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -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. } diff --git a/core/lib/Thelia/Admin/Controller/BaseAdminController.php b/core/lib/Thelia/Admin/Controller/BaseAdminController.php index e13f10da2..b5fe2a71b 100755 --- a/core/lib/Thelia/Admin/Controller/BaseAdminController.php +++ b/core/lib/Thelia/Admin/Controller/BaseAdminController.php @@ -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. * diff --git a/core/lib/Thelia/Admin/Controller/SessionController.php b/core/lib/Thelia/Admin/Controller/SessionController.php index 115f9700c..71a3c0106 100755 --- a/core/lib/Thelia/Admin/Controller/SessionController.php +++ b/core/lib/Thelia/Admin/Controller/SessionController.php @@ -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"); } } \ No newline at end of file diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 94cae432a..e16801286 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -102,6 +102,8 @@ + + %thelia.parser.forms% diff --git a/core/lib/Thelia/Core/Event/ActionEvent.php b/core/lib/Thelia/Core/Event/ActionEvent.php index 486b80ee8..42ac5db96 100755 --- a/core/lib/Thelia/Core/Event/ActionEvent.php +++ b/core/lib/Thelia/Core/Event/ActionEvent.php @@ -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; - } } diff --git a/core/lib/Thelia/Core/EventListener/ControllerListener.php b/core/lib/Thelia/Core/EventListener/ControllerListener.php index 3ae9c77bb..63fead7ce 100755 --- a/core/lib/Thelia/Core/EventListener/ControllerListener.php +++ b/core/lib/Thelia/Core/EventListener/ControllerListener.php @@ -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()); - } } } diff --git a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php index ac684f6c6..a57428c73 100755 --- a/core/lib/Thelia/Core/HttpFoundation/Session/Session.php +++ b/core/lib/Thelia/Core/HttpFoundation/Session/Session.php @@ -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) diff --git a/core/lib/Thelia/Core/Template/ParserContext.php b/core/lib/Thelia/Core/Template/ParserContext.php index b1574d156..e5c682e37 100644 --- a/core/lib/Thelia/Core/Template/ParserContext.php +++ b/core/lib/Thelia/Core/Template/ParserContext.php @@ -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() diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index db71484ed..cdabebb13 100755 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -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; diff --git a/core/lib/Thelia/Form/BaseForm.php b/core/lib/Thelia/Form/BaseForm.php index cebdd1f0b..81864121e 100755 --- a/core/lib/Thelia/Form/BaseForm.php +++ b/core/lib/Thelia/Form/BaseForm.php @@ -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 */ diff --git a/templates/admin/default/login.html b/templates/admin/default/login.html index 782073640..eb8a890f6 100755 --- a/templates/admin/default/login.html +++ b/templates/admin/default/login.html @@ -16,7 +16,7 @@ {form name="thelia.admin.login" success_url="home" error_url="login"}
- {if isset($message)}
{$message}
{/if} + {if #form_error}
#form_error_message
{/if} {form_hidden_fields form=$form} diff --git a/templates/default/connexion.html b/templates/default/connexion.html index e8a88e655..b4c391825 100755 --- a/templates/default/connexion.html +++ b/templates/default/connexion.html @@ -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)}
{$customer_creation_error_message}
{/if} + {if #form_error}
#form_error_message
{/if} + {form_hidden_fields form=$form} diff --git a/templates/default/login.html b/templates/default/login.html index 7f79a3b53..0041fd80c 100644 --- a/templates/default/login.html +++ b/templates/default/login.html @@ -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)}
{$customer_login_error_message}
{/if} + {if #form_error}
#form_error_message
{/if} {form_hidden_fields form=$form}