diff --git a/core/lib/Thelia/Action/Customer.php b/core/lib/Thelia/Action/Customer.php index 48c2a2e0e..7a26d40b6 100755 --- a/core/lib/Thelia/Action/Customer.php +++ b/core/lib/Thelia/Action/Customer.php @@ -25,6 +25,9 @@ namespace Thelia\Action; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Thelia\Core\Event\ActionEvent; +use Thelia\Core\Event\TheliaEvents; +use Thelia\Form\BaseForm; +use Thelia\Form\CustomerCreation; class Customer implements EventSubscriberInterface { @@ -32,6 +35,26 @@ class Customer implements EventSubscriberInterface public function create(ActionEvent $event) { + $event->getDispatcher()->dispatch(TheliaEvents::BEFORE_CREATECUSTOMER, $event); + + $request = $event->getRequest(); + + $customerForm = new CustomerCreation($request); + + $form = $customerForm->getForm(); + + + if ($request->isMethod("post")) { + $form->bind($request); + + if ($form->isValid()) { + echo "ok"; exit; + } else { + $event->setFormError($form); + } + } + + $event->getDispatcher()->dispatch(TheliaEvents::AFTER_CREATECUSTOMER, $event); } public function modify(ActionEvent $event) diff --git a/core/lib/Thelia/Admin/Controller/AdminController.php b/core/lib/Thelia/Admin/Controller/AdminController.php index bb5536c7e..91b6123b8 100755 --- a/core/lib/Thelia/Admin/Controller/AdminController.php +++ b/core/lib/Thelia/Admin/Controller/AdminController.php @@ -50,11 +50,9 @@ class AdminController extends BaseAdminController { protected function getLoginForm() { - $form = $this->getFormBuilder(); + $adminLogin = new AdminLogin($this->getRequest()); - $adminLogin = new AdminLogin(); - - return $adminLogin->buildForm($form, array())->getForm(); + return $adminLogin->getForm(); } public function lostAction() diff --git a/core/lib/Thelia/Admin/Controller/BaseAdminController.php b/core/lib/Thelia/Admin/Controller/BaseAdminController.php index 3aa0e9281..1c193a966 100755 --- a/core/lib/Thelia/Admin/Controller/BaseAdminController.php +++ b/core/lib/Thelia/Admin/Controller/BaseAdminController.php @@ -79,16 +79,4 @@ class BaseAdminController extends ContainerAware return $parser; } - - public function getFormFactory() - { - return BaseForm::getFormFactory($this->getRequest(), ConfigQuery::read("form.secret.admin", md5(__DIR__))); - } - - public function getFormBuilder() - { - return $this->getFormFactory()->createBuilder("form"); - } - - } \ 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 d1e6569fa..4eb0217ae 100755 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -23,6 +23,7 @@
+ diff --git a/core/lib/Thelia/Core/Event/ActionEvent.php b/core/lib/Thelia/Core/Event/ActionEvent.php index b2d1d7b77..32074c559 100755 --- a/core/lib/Thelia/Core/Event/ActionEvent.php +++ b/core/lib/Thelia/Core/Event/ActionEvent.php @@ -47,6 +47,8 @@ abstract class ActionEvent extends Event */ protected $action; + protected $form; + /** * * @param \Symfony\Component\HttpFoundation\Request $request @@ -75,4 +77,21 @@ abstract class ActionEvent extends Event { return $this->request; } + + public function setFormError($form) + { + $this->form = $form; + $this->stopPropagation(); + } + + public function getForm() + { + return $this->form; + } + + public function hasFormError() + { + return $this->form !== null; + } + } diff --git a/core/lib/Thelia/Core/Event/TheliaEvents.php b/core/lib/Thelia/Core/Event/TheliaEvents.php index 3ffac068f..8f44d7fb5 100755 --- a/core/lib/Thelia/Core/Event/TheliaEvents.php +++ b/core/lib/Thelia/Core/Event/TheliaEvents.php @@ -47,4 +47,8 @@ final class TheliaEvents * Send before starting thelia inclusion */ const INCLUSION = "thelia.include"; + + const BEFORE_CREATECUSTOMER = "action.before_createcustomer"; + + const AFTER_CREATECUSTOMER = "action.after_createcustomer"; } diff --git a/core/lib/Thelia/Core/EventListener/ControllerListener.php b/core/lib/Thelia/Core/EventListener/ControllerListener.php index 607c2a44d..93c827c09 100755 --- a/core/lib/Thelia/Core/EventListener/ControllerListener.php +++ b/core/lib/Thelia/Core/EventListener/ControllerListener.php @@ -46,7 +46,14 @@ class ControllerListener implements EventSubscriberInterface if (false !== $action = $request->get("action")) { //search corresponding action $event = new ActionEventFactory($request, $action, $event->getKernel()->getContainer()->getParameter("thelia.actionEvent")); - $dispatcher->dispatch("action.".$action, $event->createActionEvent()); + $actionEvent = $event->createActionEvent(); + $dispatcher->dispatch("action.".$action, $actionEvent); + + if ($actionEvent->hasFormError()) { + $request->getSession()->set("form_error", true); + $request->getSession()->set("form_name", $actionEvent->getForm()->createView() + ->vars["attr"]["thelia_name"]); + } } } diff --git a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php index d1ef26244..2ff6be8e3 100644 --- a/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php +++ b/core/lib/Thelia/Core/Template/Smarty/Plugins/Form.php @@ -30,6 +30,30 @@ use Thelia\Core\Template\Smarty\SmartyPluginDescriptor; use Thelia\Core\Template\Smarty\SmartyPluginInterface; use Thelia\Log\Tlog; +/** + * + * Plugin for smarty defining blocks and functions for using Form display. + * + * blocks : + * - {form name="myForm"} ... {/form} => find form named myForm, + * create an instance and assign this instanciation into smarty variable. Form must be declare into + * config using tag + * + * - {form_field form=$form.fieldName} {/form_field} This block find info into the Form field containing by + * the form paramter. This field must be an instance of FormView. fieldName is the name of your field. This block + * can output these info : + * * $name => name of yout input + * * $value => value for your input + * * $label => label for your input + * * $error => boolean for know if there is error for this field + * * $attr => all your attribute for your input (define when you construct programmatically you form) + * + * - {form_error form=$form.fieldName} ... {/form_error} Display this block if there are errors on this field. + * fieldName is the name of your field + * + * Class Form + * @package Thelia\Core\Template\Smarty\Plugins + */ class Form implements SmartyPluginInterface { @@ -63,13 +87,18 @@ class Form implements SmartyPluginInterface throw new \InvalidArgumentException("Missing 'name' parameter in form arguments"); } - $form = BaseForm::getFormFactory($this->request); - $formBuilder = $form->createBuilder('form'); - $instance = $this->getInstance($params['name']); - $instance = $instance->buildForm($formBuilder, array()); + $form = $instance->getForm(); - $template->assign("form", $instance->getForm()->createView()); + if ( + true === $this->request->getSession()->get("form_error", false) && + $this->request->getSession()->get("form_name") == $instance->getName()) + { + $form->bind($this->request); + $this->request->getSession()->set("form_error", false); + } + + $template->assign("form", $form->createView()); } else { return $content; } @@ -179,8 +208,13 @@ class Form implements SmartyPluginInterface throw new ElementNotFoundException(sprintf("%s form does not exists", $name)); } + $class = new \ReflectionClass($this->formDefinition[$name]); - return new $this->formDefinition[$name]; + + return $class->newInstance( + $this->request, + "form" + ); } /** diff --git a/core/lib/Thelia/Form/AdminLogin.php b/core/lib/Thelia/Form/AdminLogin.php index 2bd2debac..33810f771 100644 --- a/core/lib/Thelia/Form/AdminLogin.php +++ b/core/lib/Thelia/Form/AdminLogin.php @@ -23,16 +23,15 @@ namespace Thelia\Form; -use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; -class AdminLogin extends AbstractType { +class AdminLogin extends BaseForm { - public function buildForm(FormBuilderInterface $builder, array $options) + protected function buildForm() { - return $builder + $this->form ->add("username", "text", array( "constraints" => array( new NotBlank(), @@ -42,13 +41,9 @@ class AdminLogin extends AbstractType { ->add("password", "password"); } - /** - * Returns the name of this type. - * - * @return string The name of this type - */ public function getName() { return "admin_login"; } + } \ No newline at end of file diff --git a/core/lib/Thelia/Form/BaseForm.php b/core/lib/Thelia/Form/BaseForm.php index da6689f24..3a6d69cb3 100644 --- a/core/lib/Thelia/Form/BaseForm.php +++ b/core/lib/Thelia/Form/BaseForm.php @@ -30,32 +30,78 @@ use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension; use Symfony\Component\Form\Extension\Csrf\CsrfExtension; use Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider; use Symfony\Component\Validator\Validation; +use Thelia\Form\Extension\NameFormExtension; use Thelia\Model\ConfigQuery; -class BaseForm { - +abstract class BaseForm { /** - * @param Request $request - * @return \Symfony\Component\Form\FormFactoryInterface + * @var \Symfony\Component\Form\FormFactoryInterface */ - public static function getFormFactory(Request $request, $secret = null) + protected $form; + + public $name; + + public function __construct(Request $request, $type= "form", $data = array(), $options = array()) { $validator = Validation::createValidator(); - $form = Forms::createFormFactoryBuilder() + if(!isset($options["attr"]["name"])) { + $options["attr"]["thelia_name"] = $this->getName(); + } + + $this->form = Forms::createFormFactoryBuilder() ->addExtension(new HttpFoundationExtension()) ->addExtension( new CsrfExtension( new SessionCsrfProvider( $request->getSession(), - $secret ?: ConfigQuery::read("form.secret", md5(__DIR__)) + isset($options["secret"]) ? $options["secret"] : ConfigQuery::read("form.secret", md5(__DIR__)) ) ) ) ->addExtension(new ValidatorExtension($validator)) - ->getFormFactory(); + ->getFormFactory() + ->createNamedBuilder($this->getName(), $type, $data, $options); + ; - return $form; + + + $this->buildForm(); } + + /** + * @return \Symfony\Component\Form\Form + */ + public function getForm() + { + return $this->form->getForm(); + } + + /** + * + * in this function you add all the fields you need for your Form. + * Form this you have to call add method on $this->form attribute : + * + * $this->form->add("name", "text") + * ->add("email", "email", array( + * "attr" => array( + * "class" => "field" + * ), + * "label" => "email", + * "constraints" => array( + * new NotBlank() + * ) + * ) + * ) + * ->add('age', 'integer'); + * + * @return null + */ + abstract protected function buildForm(); + + /** + * @return string the name of you form. This name must be unique + */ + abstract public function getName(); } diff --git a/core/lib/Thelia/Form/CustomerCreation.php b/core/lib/Thelia/Form/CustomerCreation.php index 120be2f41..a8490fc43 100644 --- a/core/lib/Thelia/Form/CustomerCreation.php +++ b/core/lib/Thelia/Form/CustomerCreation.php @@ -24,31 +24,70 @@ namespace Thelia\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Validator\Constraints; +use Thelia\Model\ConfigQuery; -class CustomerCreation extends AbstractType +class CustomerCreation extends BaseForm { - public function buildForm(FormBuilderInterface $builder, array $options) + protected function buildForm() { - return $builder->add("name", "text") + $this->form + ->add("firstname", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => "firstname" + )) + ->add("lastname", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => "lastname" + )) ->add("email", "email", array( - "attr" => array( - "class" => "field" - ), - "label" => "email" + "constraints" => array( + new Constraints\NotBlank(), + new Constraints\Email() + ), + "label" => "email" + )) + ->add("address1", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => "address" + )) + ->add("address2", "text", array( + "label" => "Address Line 2" + )) + ->add("address3", "text", array( + "label" => "Address Line 3" + )) + ->add("zipcode", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => "zipcode" + )) + ->add("country", "text", array( + "constraints" => array( + new Constraints\NotBlank() + ), + "label" => "country" + )) + ->add("password", "password", array( + "constraints" => array( + new Constraints\Length(array("min" => ConfigQuery::read("password.length", 4))) ) - ) - ->add('age', 'integer'); + )) + + ; } - /** - * Returns the name of this type. - * - * @return string The name of this type - */ public function getName() { - return "customer creation"; + return "customerCreation"; } } \ No newline at end of file diff --git a/templates/smarty-sample/connexion.html b/templates/smarty-sample/connexion.html new file mode 100644 index 000000000..d16aa52e9 --- /dev/null +++ b/templates/smarty-sample/connexion.html @@ -0,0 +1,73 @@ +{include file="includes/header.html"} + +{form name="thelia.customer.creation"} + + + {form_field_hidden form=$form} + {form_field form=$form.firstname} + {form_error form=$form.firstname} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.lastname} + {form_error form=$form.lastname} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.address1} + {form_error form=$form.address1} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.address2} + {form_error form=$form.address2} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.address3} + {form_error form=$form.address3} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.zipcode} + {form_error form=$form.zipcode} + {$message} + {/form_error} + +
+ {/form_field} + + {form_field form=$form.country} + {form_error form=$form.country} + {$message} + {/form_error} + + + +
+ {/form_field} + + + +{/form} + +{include file="includes/footer.html"} \ No newline at end of file diff --git a/templates/smarty-sample/index.html b/templates/smarty-sample/index.html index 57cbd928a..d7c2b2e62 100755 --- a/templates/smarty-sample/index.html +++ b/templates/smarty-sample/index.html @@ -7,22 +7,8 @@ An image from asset directory :
{intl l='An internationalized string'}
-{form name="thelia.customer.creation"} -
- {form_field_hidden form=$form} - {form_field form=$form.email} - {intl l="{$label}"} : - {/form_field} - {form_field form=$form.name} - {intl l='name'} : - {/form_field} - {form_field form=$form.age} - {intl l='age'} : - {/form_field} -
-{/form}
jQuery data: