Refactored Form system to get simple error handling and a clearer

interface
This commit is contained in:
franck
2013-07-16 16:34:47 +02:00
parent d250e0c660
commit e8bf47b929
26 changed files with 626 additions and 220 deletions

View File

@@ -43,10 +43,9 @@ class Customer implements EventSubscriberInterface
$request = $event->getRequest();
$customerForm = new CustomerCreation($request);
$form = $customerForm->getForm();
$customerCreation = new CustomerCreation($request);
$form = $customerCreation->getForm();
if ($request->isMethod("post")) {
$form->bind($request);
@@ -68,18 +67,18 @@ class Customer implements EventSubscriberInterface
$data["country"],
$data["email"],
$data["password"],
$request->getSession()->get("lang")
$request->getSession()->getLang()
);
} catch (\PropelException $e) {
Tlog::getInstance()->error(sprintf('error during creating customer on action/createCustomer with message "%s"', $e->getMessage()));
$event->setFormError($form);
$event->setFormError($customerCreation);
}
//Customer is create, he is automatically connected
} else {
$event->setFormError($form);
$event->setFormError($customerCreation);
}
}
@@ -117,10 +116,10 @@ class Customer implements EventSubscriberInterface
);
} catch(\PropelException $e) {
Tlog::getInstance()->error(sprintf('error during modifying customer on action/modifyCustomer with message "%s"', $e->getMessage()));
$event->setFormError($form);
$event->setFormError($customerModification);
}
} else {
$event->setFormError($form);
$event->setFormError($customerModification);
}
}

View File

@@ -34,6 +34,7 @@ use Thelia\Core\Security\Exception\AuthenticationTokenNotFoundException;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\SecurityContext;
use Thelia\Tools\URL;
/**
*
@@ -93,7 +94,7 @@ class BaseAdminController extends ContainerAware
// User is not authenticated, and templates requires authentication -> redirect to login page
// (see Thelia\Core\Template\Smarty\Plugins\Security)
return new RedirectResponse($this->generateUrl('admin/login')); // FIXME shoud be a parameter
return new RedirectResponse(URL::absoluteUrl('admin/login')); // FIXME shoud be a parameter
}
}
@@ -155,32 +156,6 @@ class BaseAdminController extends ContainerAware
return $this->getFormFactory()->createBuilder("form");
}
/**
* Generates a URL from the given parameters.
*
* @param string $route The name of the route
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The generated URL
*
* @see UrlGeneratorInterface
*/
protected function generateUrl($path, array $parameters = array())
{
$base = ConfigQuery::read("base_url", "/").$path; //FIXME
$queryString = '';
foreach($parameters as $name => $value) {
$queryString = sprintf("%s=%s&", urlencode($name), urlencode($value));
}
if ('' !== $queryString = rtrim($queryString, "&")) $queryString = '?' . $queryString;
return $base . $queryString;
}
/**
* Forwards the request to another controller.
*

View File

@@ -32,16 +32,14 @@ use Thelia\Core\Security\Token\TokenInterface;
use Thelia\Core\Security\Authentication\AdminUsernamePasswordFormAuthenticator;
use Thelia\Model\AdminLog;
use Thelia\Core\Security\Exception\AuthenticationException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Thelia\Tools\URL;
class SessionController extends BaseAdminController {
public function showLoginAction()
{
$form = $this->getLoginForm();
return $this->render("login.html", array(
"form" => $form->createView()
));
return $this->render("login.html");
}
public function checkLogoutAction()
@@ -49,12 +47,12 @@ class SessionController extends BaseAdminController {
$this->getSecurityContext()->clear();
// Go back to login page.
return $this->redirect($this->generateUrl('admin/login'));
return $this->redirect(URL::absoluteUrl('admin/login'));
}
public function checkLoginAction()
{
$form = $this->getLoginForm();
$form = new AdminLogin($this->getRequest());
$request = $this->getRequest();
@@ -69,8 +67,17 @@ class SessionController extends BaseAdminController {
// Log authentication success
AdminLog::append("Authentication successufull", $request, $user);
// Get the success URL to redirect the user to
$successUrl = $form->getForm()->get('success_url')->getData();
if (null == $successUrl) $successUrl = 'admin/home';
// Redirect to home page - FIXME: requested URL, if we come from another page ?
return $this->redirect($this->generateUrl('admin'));
return $this->redirect(URL::absoluteUrl($successUrl));
}
catch (ValidatorException $ex) {
$message = "Missing or invalid information. Please check your input.";
}
catch (AuthenticationException $ex) {
@@ -80,17 +87,18 @@ class SessionController extends BaseAdminController {
$message = "Login failed. Please check your username and password.";
}
// Display the login form again
// Store the form in session (see Form Smlarty plugin to find usage of this parameter)
$request->getSession()->setErrorFormName($form->getName());
if (empty($failureUrl)) {
// Display the login form again, with an error message if required
return $this->render("login.html", array(
"form" => $authenticator->getLoginForm()->createView(),
"message" => $message
));
}
protected function getLoginForm()
{
$adminLogin = new AdminLogin($this->getRequest());
return $adminLogin->getForm();
else {
// Redirect to the provided URL
return $this->redirect(URL::absoluteUrl($failureUrl));
}
}
}

View File

@@ -27,7 +27,7 @@
<forms>
<form name="thelia.customer.creation" class="Thelia\Form\CustomerCreation"/>
<form name="thelia.customer.modification" class="Thelia\Form\CustomerModification"/>
<form name="thelia.admin_login" class="Thelia\Form\AdminLogin"/>
<form name="thelia.admin.login" class="Thelia\Form\AdminLogin"/>
</forms>
@@ -120,6 +120,10 @@
<tag name="thelia.parser.register_plugin"/>
</service>
<service id="smarty.url.module" class="Thelia\Core\Template\Smarty\Plugins\UrlGenerator" >
<tag name="thelia.parser.register_plugin"/>
</service>
<service id="smarty.plugin.security" class="Thelia\Core\Template\Smarty\Plugins\Security" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="thelia.securityContext" />

View File

@@ -25,6 +25,7 @@ namespace Thelia\Core\Event;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Form\BaseForm;
/**
*
* Class thrown on Thelia.action event
@@ -47,7 +48,7 @@ abstract class ActionEvent extends Event
*/
protected $action;
protected $form;
protected $form = null;
/**
*
@@ -78,17 +79,30 @@ abstract class ActionEvent extends Event
return $this->request;
}
public function setFormError($form)
/**
* 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();
}
public function getForm()
/**
* @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

@@ -50,9 +50,7 @@ class ControllerListener implements EventSubscriberInterface
$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"]);
$request->getSession()->setErrorFormName($actionEvent->getFormError()->getName());
}
}

View File

@@ -25,6 +25,7 @@ namespace Thelia\Core\HttpFoundation\Session;
use Symfony\Component\HttpFoundation\Session\Session as BaseSession;
use Thelia\Core\Security\User\UserInterface;
use Thelia\Form\BaseForm;
class Session extends BaseSession {
@@ -39,28 +40,52 @@ class Session extends BaseSession {
return substr($this->getLocale(), 0, 2);
}
public function setCustomerUser(UserInterface $user) {
public function setCustomerUser(UserInterface $user)
{
$this->set('customer_user', $user);
}
public function getCustomerUser() {
public function getCustomerUser()
{
return $this->get('customer_user');
}
public function clearCustomerUser() {
public function clearCustomerUser()
{
return $this->remove('customer_user');
}
public function setAdminUser(UserInterface $user) {
public function setAdminUser(UserInterface $user)
{
$this->set('admin_user', $user);
}
public function getAdminUser() {
public function getAdminUser()
{
return $this->get('admin_user');
}
public function clearAdminUser() {
public function clearAdminUser()
{
return $this->remove('admin_user');
}
/**
* @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');
}
}

View File

@@ -29,17 +29,15 @@ use Symfony\Component\Form\Form;
use Thelia\Core\Security\UserProvider\AdminUserProvider;
use Thelia\Core\Security\Authentication\UsernamePasswordFormAuthenticator;
use Thelia\Form\AdminLogin;
class AdminUsernamePasswordFormAuthenticator extends UsernamePasswordFormAuthenticator {
public function __construct(Request $request, Form $loginForm) {
public function __construct(Request $request, AdminLogin $loginForm) {
parent::__construct(
$request,
$loginForm,
new AdminUserProvider(),
array(
'username_field_name', 'email'
)
new AdminUserProvider()
);
}
}

View File

@@ -30,11 +30,14 @@ use Thelia\Form\CustomerLogin;
class CustomerUsernamePasswordFormAuthenticator extends UsernamePasswordFormAuthenticator {
public function __construct(Request $request, AdminLogin $loginForm) {
public function __construct(Request $request, CustomerLogin $loginForm) {
parent::__construct(
$request,
$loginForm,
new AdminUserProvider(),
new CustomerUserProvider(),
array(
'username_field_name', 'email'
)
);
}
}

View File

@@ -29,6 +29,8 @@ use Thelia\Core\Security\UserProvider\UserProviderInterface;
use Symfony\Component\Form\Form;
use Thelia\Core\Security\Exception\WrongPasswordException;
use Thelia\Core\Security\Exception\UsernameNotFoundException;
use Symfony\Component\Validator\Exception\ValidatorException;
use Thelia\Form\BaseForm;
class UsernamePasswordFormAuthenticator implements AuthenticatorInterface {
@@ -37,10 +39,12 @@ class UsernamePasswordFormAuthenticator implements AuthenticatorInterface {
protected $userProvider;
protected $options;
protected $baseLoginForm;
public function __construct(Request $request, Form $loginForm, UserProviderInterface $userProvider, array $options = array()) {
public function __construct(Request $request, BaseForm $loginForm, UserProviderInterface $userProvider, array $options = array()) {
$this->request = $request;
$this->loginForm = $loginForm;
$this->baseLoginForm = $loginForm;
$this->loginForm = $this->baseLoginForm->getForm();
$this->userProvider = $userProvider;
$defaults = array(
@@ -54,19 +58,21 @@ class UsernamePasswordFormAuthenticator implements AuthenticatorInterface {
$this->loginForm->bind($this->request);
}
public function getLoginForm() {
return $this->loginForm;
}
/**
* @return string the username value
*/
public function getUsername() {
return $this->loginForm->get($this->options['username_field_name'])->getData();
}
/**
* @see \Thelia\Core\Security\Authentication\AuthenticatorInterface::getAuthentifiedUser()
*/
public function getAuthentifiedUser() {
if ($this->request->isMethod($this->options['required_method'])) {
if ($this->loginForm->isValid()) {
if (! $this->loginForm->isValid()) throw new ValidatorException("Form is not valid.");
// Retreive user
$username = $this->getUsername();
@@ -83,9 +89,7 @@ class UsernamePasswordFormAuthenticator implements AuthenticatorInterface {
return $user;
}
}
else {
throw new \RuntimeException("Invalid method.");
}
}
}

View File

@@ -109,12 +109,53 @@ class SecurityContext {
{
if ($this->isAuthenticated() === true) {
echo "TODO: check roles and permissions !";
$user = $this->getUser();
// TODO : check roles and permissions
// Check if user's roles matches required roles
$userRoles = $user->getRoles();
$roleFound = false;
foreach($userRoles as $role) {
if (in_array($role, $roles)) {
$roleFound = true;
break;
}
}
if ($roleFound) {
if (empty($permissions)) {
return true;
}
// Get permissions from profile
// $userPermissions = $user->getPermissions();
echo "TODO: Finalize permissions system !";
$userPermissions = array('*'); // FIXME !
$permissionsFound = true;
// User have all permissions ?
if (in_array('*', $userPermissions))
return true;
// Check that user's permissions matches required permissions
foreach($permissions as $permission) {
if (! in_array($permission, $userPermissions)) {
$permissionsFound = false;
break;
}
}
return $permissionsFound;
}
}
return false;
}

View File

@@ -47,7 +47,8 @@ class Auth extends BaseLoop
{
return new ArgumentCollection(
Argument::createAnyTypeArgument('roles', null, true),
Argument::createAnyTypeArgument('permissions')
Argument::createAnyTypeArgument('permissions'),
Argument::createAnyTypeArgument('context', 'front', false)
);
}
@@ -72,17 +73,21 @@ class Auth extends BaseLoop
*/
public function exec(&$pagination)
{
$context = $this->getContext();
$roles = $this->_explode($this->getRoles());
$permissions = $this->_explode($this->getPermissions());
$loopResult = new LoopResult();
try {
$this->securityContext->isGranted($roles, $permissions == null ? array() : $permissions);
$this->securityContext->setContext($context);
if (true === $this->securityContext->isGranted($roles, $permissions == null ? array() : $permissions)) {
// Create an empty row: loop is no longer empty :)
$loopResult->addRow(new LoopResultRow());
}
}
catch (\Exception $ex) {
// Not granted, loop is empty
}

View File

@@ -25,6 +25,7 @@ namespace Thelia\Core\Template\Smarty\Assets;
use Thelia\Core\Template\Assets\AsseticHelper;
use Thelia\Model\ConfigQuery;
use Thelia\Tools\URL;
class SmartyAssetsManager
{
@@ -72,7 +73,7 @@ class SmartyAssetsManager
$url = $this->assetic_manager->asseticize(
$asset_dir.'/'.$asset_file,
$this->web_root."/".$this->path_relative_to_web_root,
ConfigQuery::read('base_url', '/') . $this->path_relative_to_web_root,
URL::absoluteUrl($this->path_relative_to_web_root),
$assetType,
$filters,
$debug

View File

@@ -58,7 +58,6 @@ class Form implements SmartyPluginInterface
{
protected $request;
protected $form;
protected $formDefinition = array();
public function __construct(Request $request)
@@ -87,67 +86,74 @@ class Form implements SmartyPluginInterface
throw new \InvalidArgumentException("Missing 'name' parameter in form arguments");
}
$instance = $this->getInstance($params['name']);
$form = $instance->getForm();
$instance = $this->createInstance($params['name']);
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);
// Check if session contains our form
$errorForm = $this->request->getSession()->getErrorFormName();
if ($errorForm == $instance->getName()) {
// Bind form with current request to get error messages and field values.
$instance->getForm()->bind($this->request);
// Remove the form from the session
$this->request->getSession()->clearErrorFormName();
}
$template->assign("form", $form->createView());
} else {
$instance->createView();
$template->assign("form", $instance);
}
else {
return $content;
}
}
public function formRender($params, $content, \Smarty_Internal_Template $template, &$repeat)
public function renderFormField($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
if ($repeat) {
$form = $params["form"];
$formFieldView = $this->getFormFieldView($params);
if (! $form instanceof \Symfony\Component\Form\FormView) {
throw new \InvalidArgumentException("form parameter in form_field block must be an instance of
Symfony\Component\Form\FormView");
$template->assign("options", $formFieldView->vars);
$template->assign("name", $formFieldView->vars["full_name"]);
$template->assign("value", $formFieldView->vars["value"]);
$template->assign("label", $formFieldView->vars["label"]);
$errors = $formFieldView->vars["errors"];
$template->assign("error", empty($errors) ? false : true);
if (! empty($errors)) {
$this->assignFieldErrorVars($template, $errors);
}
$template->assign("options", $form->vars);
$template->assign("name", $form->vars["full_name"]);
$template->assign("value", $form->vars["value"]);
$template->assign("label", $form->vars["label"]);
$template->assign("error", empty($form->vars["errors"]) ? false : true);
$attr = array();
foreach ($form->vars["attr"] as $key => $value) {
foreach ($formFieldView->vars["attr"] as $key => $value) {
$attr[] = sprintf('%s="%s"', $key, $value);
}
$template->assign("attr", implode(" ", $attr));
$form->setRendered();
} else {
$formFieldView->setRendered();
}
else {
return $content;
}
}
public function formRenderHidden($params, \Smarty_Internal_Template $template)
public function renderHiddenFormField($params, \Smarty_Internal_Template $template)
{
$form = $params["form"];
$field = '<input type="hidden" name="%s" value="%s">';
if (! $form instanceof \Symfony\Component\Form\FormView) {
throw new \InvalidArgumentException("form parameter in form_field_hidden function must be an instance of
Symfony\Component\Form\FormView");
}
$instance = $this->getInstanceFromParams($params);
$formView = $instance->getView();
$return = "";
foreach ($form->getIterator() as $row) {
foreach ($formView->getIterator() as $row) {
if ($this->isHidden($row) && $row->isRendered() === false) {
$return .= sprintf($field, $row->vars["full_name"], $row->vars["value"]);
}
@@ -156,53 +162,79 @@ class Form implements SmartyPluginInterface
return $return;
}
protected function isHidden(FormView $formView)
{
return array_search("hidden", $formView->vars["block_prefixes"]);
}
public function formEnctype($params, \Smarty_Internal_Template $template)
{
$form = $params["form"];
$instance = $this->getInstanceFromParams($params);
if (! $form instanceof \Symfony\Component\Form\FormView) {
throw new \InvalidArgumentException("form parameter in form_enctype function must be an instance of
Symfony\Component\Form\FormView");
}
$formView = $instance->getForm();
if ($form->vars["multipart"]) {
if ($formView->vars["multipart"]) {
return sprintf('%s="%s"',"enctype", "multipart/form-data");
}
}
public function formError($params, $content, \Smarty_Internal_Template $template, &$repeat)
{
$formFieldView = $this->getFormFieldView($params);
$form = $params["form"];
if (! $form instanceof \Symfony\Component\Form\FormView) {
throw new \InvalidArgumentException("form parameter in form_error block must be an instance of
Symfony\Component\Form\FormView");
}
$errors = $formFieldView->vars["errors"];
if (empty($form->vars["errors"])) {
if (empty($errors)) {
return "";
}
if ($repeat) {
$error = $form->vars["errors"];
$template->assign("message", $error[0]->getMessage());
$template->assign("parameters", $error[0]->getMessageParameters());
$template->assign("pluralization", $error[0]->getMessagePluralization());
} else {
$this->assignFieldErrorVars($template, $errors);
}
else {
return $content;
}
}
public function getInstance($name)
protected function assignFieldErrorVars(\Smarty_Internal_Template $template, array $errors)
{
$template->assign("message", $errors[0]->getMessage());
$template->assign("parameters", $errors[0]->getMessageParameters());
$template->assign("pluralization", $errors[0]->getMessagePluralization());
}
protected function isHidden(FormView $formView)
{
return array_search("hidden", $formView->vars["block_prefixes"]);
}
protected function getFormFieldView($params) {
$instance = $this->getInstanceFromParams($params);
if (! isset($params['field']))
throw new \InvalidArgumentException("'field' parameter is missing");
$fieldName = $params['field'];
if (empty($instance->getView()[$fieldName]))
throw new \InvalidArgumentException(sprintf("Field name '%s' not found in form %s", $fieldName, $instance->getName()));
return $instance->getView()[$fieldName];
}
protected function getInstanceFromParams($params) {
if (empty($params['form'])) {
throw new \InvalidArgumentException("Missing 'form' parameter in form arguments");
}
$instance = $params["form"];
if (! $instance instanceof \Thelia\Form\BaseForm) {
throw new \InvalidArgumentException(sprintf("form parameter in form_field block must be an instance of
\Thelia\Form\BaseForm, instance of %s found", get_class($instance)));
}
return $instance;
}
protected function createInstance($name)
{
if (!isset($this->formDefinition[$name])) {
throw new ElementNotFoundException(sprintf("%s form does not exists", $name));
@@ -210,7 +242,6 @@ class Form implements SmartyPluginInterface
$class = new \ReflectionClass($this->formDefinition[$name]);
return $class->newInstance(
$this->request,
"form"
@@ -224,8 +255,8 @@ class Form implements SmartyPluginInterface
{
return array(
new SmartyPluginDescriptor("block", "form", $this, "generateForm"),
new SmartyPluginDescriptor("block", "form_field", $this, "formRender"),
new SmartyPluginDescriptor("function", "form_field_hidden", $this, "formRenderHidden"),
new SmartyPluginDescriptor("block", "form_field", $this, "renderFormField"),
new SmartyPluginDescriptor("function", "form_hidden_fields", $this, "renderHiddenFormField"),
new SmartyPluginDescriptor("function", "form_enctype", $this, "formEnctype"),
new SmartyPluginDescriptor("block", "form_error", $this, "formError")
);

View File

@@ -0,0 +1,59 @@
<?php
use Thelia\Tools\URL;
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
use Thelia\Tools\URL;
class UrlGenerator implements SmartyPluginInterface
{
/**
* Process url generator function
*
* @param array $params
* @param unknown $smarty
* @return string no text is returned.
*/
public function generateUrlFunction($params, &$smarty)
{
// the path to process
$path =trim($params['path']);
return URL::absoluteUrl($path);
}
/**
* Define the various smarty plugins hendled by this class
*
* @return an array of smarty plugin descriptors
*/
public function getPluginDescriptors()
{
return array(
new SmartyPluginDescriptor('function', 'url', $this, 'generateUrlFunction')
);
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Choice;
@@ -32,7 +31,7 @@ class AdminLogin extends BaseForm {
protected function buildForm()
{
$this->form
$this->formBuilder
->add("username", "text", array(
"constraints" => array(
new NotBlank(),
@@ -44,12 +43,15 @@ class AdminLogin extends BaseForm {
new NotBlank()
)
))
->add("remember_me", "checkbox")
->add("remember_me", "checkbox", array(
'value' => 'yes'
))
->add("success_url", "text")
;
}
public function getName()
{
return "admin_login";
return "adminLogin";
}
}

View File

@@ -36,9 +36,14 @@ abstract class BaseForm {
/**
* @var \Symfony\Component\Form\FormFactoryInterface
*/
protected $formBuilder;
/**
* @var \Symfony\Component\Form\Form
*/
protected $form;
public $name;
private $view = null;
public function __construct(Request $request, $type= "form", $data = array(), $options = array())
{
@@ -48,7 +53,7 @@ abstract class BaseForm {
$options["attr"]["thelia_name"] = $this->getName();
}
$this->form = Forms::createFormFactoryBuilder()
$this->formBuilder = Forms::createFormFactoryBuilder()
->addExtension(new HttpFoundationExtension())
->addExtension(
new CsrfExtension(
@@ -63,9 +68,19 @@ abstract class BaseForm {
->createNamedBuilder($this->getName(), $type, $data, $options);
;
$this->buildForm();
$this->form = $this->formBuilder->getForm();
}
public function createView() {
$this->view = $this->form->createView();
}
public function getView() {
if ($this->view === null) throw new \LogicException("View was not created. Please call BaseForm::createView() first.");
return $this->view;
}
/**
@@ -73,13 +88,13 @@ abstract class BaseForm {
*/
public function getForm()
{
return $this->form->getForm();
return $this->form;
}
/**
*
* 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 :
* Form this you have to call add method on $this->formBuilder attribute :
*
* $this->form->add("name", "text")
* ->add("email", "email", array(

View File

@@ -33,7 +33,7 @@ class CustomerCreation extends BaseForm
protected function buildForm()
{
$this->form
$this->formBuilder
->add("firstname", "text", array(
"constraints" => array(
new Constraints\NotBlank()

View File

@@ -32,7 +32,7 @@ class CustomerLogin extends BaseForm {
protected function buildForm()
{
$this->form
$this->formBuilder
->add("username", "text", array(
"constraints" => array(
new NotBlank(),

View File

@@ -52,7 +52,7 @@ class CustomerModification extends BaseForm {
protected function buildForm()
{
$this->form
$this->formBuilder
->add("firstname", "text", array(
"constraints" => array(
new Constraints\NotBlank()

View File

@@ -0,0 +1,57 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Tools;
use Thelia\Model\ConfigQuery;
class URL
{
/**
* Returns the Absolute URL for a given path relative to web root
*
* @param string $path the relative path
* @param mixed $parameters An array of parameters
* @param Boolean|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
*
* @return string The generated URL
*/
public static function absoluteUrl($path, array $parameters = array())
{
// Already absolute ?
if (substr($path, 0, 4) != 'http')
$base = ConfigQuery::read('base_url', '/') . ltrim($path, '/');
else
$base = $path;
$queryString = '';
foreach($parameters as $name => $value) {
$queryString = sprintf("%s=%s&", urlencode($name), urlencode($value));
}
if ('' !== $queryString = rtrim($queryString, "&")) $queryString = '?' . $queryString;
return $base . $queryString;
}
}

View File

@@ -236,3 +236,161 @@ hr {
.border-radius;
.box-shadow;
}
// -- Allow inline forms validation states ------------------------------------
.form-inline .warning .control-label,
.form-inline .warning .help-block,
.form-inline .warning .help-inline {
color: #c09853;
}
.form-inline .warning .checkbox,
.form-inline .warning .radio,
.form-inline .warning input,
.form-inline .warning select,
.form-inline .warning textarea {
color: #c09853;
}
.form-inline .warning input,
.form-inline .warning select,
.form-inline .warning textarea {
border-color: #c09853;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.form-inline .warning input:focus,
.form-inline .warning select:focus,
.form-inline .warning textarea:focus {
border-color: #a47e3c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
}
.form-inline .warning .input-prepend .add-on,
.form-inline .warning .input-append .add-on {
color: #c09853;
background-color: #fcf8e3;
border-color: #c09853;
}
.form-inline .error .control-label,
.form-inline .error .help-block,
.form-inline .error .help-inline {
color: #b94a48;
}
.form-inline .error .checkbox,
.form-inline .error .radio,
.form-inline .error input,
.form-inline .error select,
.form-inline .error textarea {
color: #b94a48;
}
.form-inline .error input,
.form-inline .error select,
.form-inline .error textarea {
border-color: #b94a48;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.form-inline .error input:focus,
.form-inline .error select:focus,
.form-inline .error textarea:focus {
border-color: #953b39;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
}
.form-inline .error .input-prepend .add-on,
.form-inline .error .input-append .add-on {
color: #b94a48;
background-color: #f2dede;
border-color: #b94a48;
}
.form-inline .success .control-label,
.form-inline .success .help-block,
.form-inline .success .help-inline {
color: #468847;
}
.form-inline .success .checkbox,
.form-inline .success .radio,
.form-inline .success input,
.form-inline .success select,
.form-inline .success textarea {
color: #468847;
}
.form-inline .success input,
.form-inline .success select,
.form-inline .success textarea {
border-color: #468847;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.form-inline .success input:focus,
.form-inline .success select:focus,
.form-inline .success textarea:focus {
border-color: #356635;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
}
.form-inline .success .input-prepend .add-on,
.form-inline .success .input-append .add-on {
color: #468847;
background-color: #dff0d8;
border-color: #468847;
}
.form-inline .info .control-label,
.form-inline .info .help-block,
.form-inline .info .help-inline {
color: #3a87ad;
}
.form-inline .info .checkbox,
.form-inline .info .radio,
.form-inline .info input,
.form-inline .info select,
.form-inline .info textarea {
color: #3a87ad;
}
.form-inline .info input,
.form-inline .info select,
.form-inline .info textarea {
border-color: #3a87ad;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.form-inline .info input:focus,
.form-inline .info select:focus,
.form-inline .info textarea:focus {
border-color: #2d6987;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
}
.form-inline .info .input-prepend .add-on,
.form-inline .info .input-append .add-on {
color: #3a87ad;
background-color: #d9edf7;
border-color: #3a87ad;
}

View File

@@ -1,4 +1,4 @@
{check_auth context="admin" roles="ADMIN"}
{check_auth context="admin" roles="ADMIN" login_url="login"}
{$page_title={intl l='Home'}}
{include file='includes/header.inc.html'}

View File

@@ -13,28 +13,36 @@
<div class="hero-unit">
<h1>{intl l='Thelia Back Office'}</h1>
{form name="thelia.admin.login" success_url="home" error_url="login"}
<form action="checklogin" method="post" class="well form-inline" {form_enctype form=$form}>
{if isset($message)}<div class="alert alert-error">{$message}</div>{/if}
{form_field_hidden form=$form}
{form_hidden_fields form=$form}
{form_field form=$form.username}
{form_error form=$form.username}{$message}{/form_error}
<input type="text" class="input" placeholder="{intl l='E-mail address'}" name="{$name}" />
{form_field form=$form field='success_url'}
<input type="hidden" name="{$name}" value="{url path='admin'}" /> {* redirect to /admin *}
{/form_field}
{form_field form=$form.password}
{form_error form=$form.password}{$message}{/form_error}
<input type="password" class="input" placeholder="{intl l='Password'}" name="{$name}" />
{form_field form=$form field='username'}
<span {if $error}class="error"{/if}>
<input type="text" class="input" placeholder="{intl l='User name'}" name="{$name}" value="{$value}" {$attr} />
</span>
{/form_field}
{form_field form=$form.remember_me}
<label class="checkbox"> <input type="checkbox" name="remember" value="yes" /> {intl l='Remember me'}</label>
{form_field form=$form field='password'}
<span {if $error}class="error"{/if}>
<input type="password" class="input" placeholder="{intl l='Password'}" name="{$name}" {$attr} />
</span>
{/form_field}
{form_field form=$form field='remember_me'}
<label class="checkbox"> <input type="checkbox" name="{$name}" value="{$value}" {$attr} {if $options.checked}checked="checked"{/if}/> {intl l='Remember me'}</label>
{/form_field}
<span class="pull-right"><button type="submit" class="btn btn-primary">{intl l='Login'} <i class="icon-play icon-white"></i></button></span>
</form>
{/form}
</div>
{module_include location='index_middle'}

View File

@@ -3,10 +3,10 @@
{form name="thelia.customer.creation"}
<form method="post" action="index_dev.php?action=createCustomer&view=connexion" {form_enctype form=$form} >
{form_field_hidden form=$form}
{form_hidden_fields form=$form}
{form_field form=$form.title}
{form_error form=$form.title}
{form_field form=$form field="title"}
{form_error form=$form field="title"}
{$message}
{/form_error}
@@ -19,64 +19,64 @@
<br />
{/form_field}
{form_field form=$form.firstname}
{form_error form=$form.firstname}
{form_field form=$form field="firstname"}
{form_error form=$form field="firstname"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.lastname}
{form_error form=$form.lastname}
{form_field form=$form field="lastname"}
{form_error form=$form field="lastname"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.address1}
{form_error form=$form.address1}
{form_field form=$form field="address1"}
{form_error form=$form field="address1"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.address2}
{form_error form=$form.address2}
{form_field form=$form field="address2"}
{form_error form=$form field="address2"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.address3}
{form_error form=$form.address3}
{form_field form=$form field="address3"}
{form_error form=$form field="address3"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.zipcode}
{form_error form=$form.zipcode}
{form_field form=$form field="zipcode"}
{form_error form=$form field="zipcode"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.city}
{form_error form=$form.city}
{form_field form=$form field="city"}
{form_error form=$form field="city"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr} > <br />
{/form_field}
{form_field form=$form.country}
{form_error form=$form.country}
{form_field form=$form field="country"}
{form_error form=$form field="country"}
{$message}
{/form_error}
@@ -89,43 +89,43 @@
<br />
{/form_field}
{form_field form=$form.phone}
{form_error form=$form.phone}
{form_field form=$form field="phone"}
{form_error form=$form field="phone"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
{form_field form=$form.cellphone}
{form_error form=$form.cellphone}
{form_field form=$form field="cellphone"}
{form_error form=$form field="cellphone"}
{$message}
{/form_error}
<label> <span>{intl l="{$label}"} : </span></label><input type="text" name="{$name}" value="{$value}" {$attr}> <br />
{/form_field}
{form_field form=$form.email}
{form_error form=$form.email}
{form_field form=$form field="email"}
{form_error form=$form field="email"}
{#message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="email" name="{$name}" value="{$value}" {$attr} ><br />
{/form_field}
{form_field form=$form.email_confirm}
{form_error form=$form.email_confirm}
{form_field form=$form field="email_confirm"}
{form_error form=$form field="email_confirm"}
{#message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="email" name="{$name}" {$attr} ><br />
{/form_field}
{form_field form=$form.password}
{form_error form=$form.password}
{form_field form=$form field="password"}
{form_error form=$form field="password"}
{#message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="password" name="{$name}" {$attr} ><br />
{/form_field}
{form_field form=$form.password_confirm}
{form_error form=$form.password_confirm}
{form_field form=$form field="password_confirm"}
{form_error form=$form field="password_confirm"}
{#message}
{/form_error}
<label><span>{intl l="{$label}"}</span></label><input type="password" name="{$name}" {$attr} ><br />

View File

@@ -1,7 +1,8 @@
{include file="includes/header.html"}
<div>
{loop type="auth" name="auth_test" roles="CUSTOMER"}
{loop type="auth" name="auth_test" context="front" roles="CUSTOMER"}
<p>Customer is authentified :-)</p>
{/loop}