[Form][FrameworkBundle] Implemented FormFactory and added it to the DI container
This commit is contained in:
parent
fea37a3e95
commit
8f8f53d631
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Adds all services with the tag "form.field_factory_guesser" as argument
|
||||
* to the "form.field_factory" service
|
||||
*
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
|
||||
*/
|
||||
class AddFieldFactoryGuessersPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('form.field_factory')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$guessers = array_map(function($id) {
|
||||
return new Reference($id);
|
||||
}, array_keys($container->findTaggedServiceIds('form.field_factory.guesser')));
|
||||
|
||||
$definition = $container->getDefinition('form.field_factory');
|
||||
$arguments = $definition->getArguments();
|
||||
$arguments[0] = $guessers;
|
||||
$definition->setArguments($arguments);
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\HttpFoundation\RequestMatcher;
|
||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
|
||||
/**
|
||||
* FrameworkExtension.
|
||||
@ -42,6 +43,23 @@ class FrameworkExtension extends Extension
|
||||
$loader->load('web.xml');
|
||||
}
|
||||
|
||||
if (!$container->hasDefinition('form.factory')) {
|
||||
$loader->load('form.xml');
|
||||
}
|
||||
|
||||
if (isset($config['csrf_protection'])) {
|
||||
foreach (array('enabled', 'field_name', 'field-name', 'secret') as $key) {
|
||||
if (isset($config['csrf_protection'][$key])) {
|
||||
$container->setParameter('form.csrf_protection.'.strtr($key, '-', '_'),
|
||||
$config['csrf_protection'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['i18n']) && $config['i18n']) {
|
||||
FormContext::setLocale(\Locale::get());
|
||||
}
|
||||
|
||||
if (isset($config['ide'])) {
|
||||
switch ($config['ide']) {
|
||||
case 'textmate':
|
||||
@ -60,12 +78,6 @@ class FrameworkExtension extends Extension
|
||||
$container->setParameter('debug.file_link_format', $pattern);
|
||||
}
|
||||
|
||||
foreach (array('csrf_secret', 'csrf-secret') as $key) {
|
||||
if (isset($config[$key])) {
|
||||
$container->setParameter('csrf_secret', $config[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$container->hasDefinition('event_dispatcher')) {
|
||||
$loader = new XmlFileLoader($container, array(__DIR__.'/../Resources/config', __DIR__.'/Resources/config'));
|
||||
$loader->load('services.xml');
|
||||
@ -149,7 +161,8 @@ class FrameworkExtension extends Extension
|
||||
'Symfony\\Component\\EventDispatcher\\EventDispatcher',
|
||||
'Symfony\\Bundle\\FrameworkBundle\\EventDispatcher',
|
||||
|
||||
'Symfony\\Component\\Form\\FormConfiguration',
|
||||
'Symfony\\Component\\Form\\FormContext',
|
||||
'Symfony\\Component\\Form\\FormContextInterface',
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddFieldFactoryGuessersPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RegisterKernelListenersPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddSecurityVotersPass;
|
||||
@ -23,7 +24,6 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
@ -37,28 +37,27 @@ class FrameworkBundle extends Bundle
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
if ($this->container->has('error_handler')) {
|
||||
$this->container->get('error_handler');
|
||||
}
|
||||
$container = $this->container;
|
||||
|
||||
FormConfiguration::clearDefaultCsrfSecrets();
|
||||
|
||||
if ($this->container->hasParameter('csrf_secret')) {
|
||||
FormConfiguration::addDefaultCsrfSecret($this->container->getParameter('csrf_secret'));
|
||||
FormConfiguration::enableDefaultCsrfProtection();
|
||||
if ($container->has('error_handler')) {
|
||||
$container->get('error_handler');
|
||||
}
|
||||
|
||||
// the session ID should always be included in the CSRF token, even
|
||||
// if default CSRF protection is not enabled
|
||||
if ($this->container->has('session')) {
|
||||
$container = $this->container;
|
||||
FormConfiguration::addDefaultCsrfSecret(function () use ($container) {
|
||||
if ($container->has('form.default_context') && $container->has('session')) {
|
||||
$addSessionId = function () use ($container) {
|
||||
// automatically starts the session when the CSRF token is
|
||||
// generated
|
||||
$container->get('session')->start();
|
||||
|
||||
return $container->get('session')->getId();
|
||||
});
|
||||
};
|
||||
|
||||
// $container->getDefinition('form.default_context')
|
||||
// ->addMethodCall('addCsrfSecret', array($addSessionId));
|
||||
//
|
||||
// var_dump($container->getDefinition('form.default_context'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,6 +72,7 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new RegisterKernelListenersPass());
|
||||
$container->addCompilerPass(new TemplatingPass());
|
||||
$container->addCompilerPass(new AddConstraintValidatorsPass());
|
||||
$container->addCompilerPass(new AddFieldFactoryGuessersPass());
|
||||
$container->addCompilerPass(new AddClassesToCachePass());
|
||||
$container->addCompilerPass(new TranslatorPass());
|
||||
}
|
||||
|
62
src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml
Normal file
62
src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://www.symfony-project.org/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
|
||||
<parameter key="form.field_factory.class">Symfony\Component\Form\FieldFactory\FieldFactory</parameter>
|
||||
<parameter key="form.field_factory.validator_guesser.class">Symfony\Component\Form\FieldFactory\ValidatorFieldFactoryGuesser</parameter>
|
||||
<parameter key="form.default_context.class">Symfony\Component\Form\FormContext</parameter>
|
||||
<parameter key="form.csrf_protection.enabled">true</parameter>
|
||||
<parameter key="form.csrf_protection.field_name">_token</parameter>
|
||||
<parameter key="form.csrf_protection.secret">secret</parameter>
|
||||
<parameter key="form.validation_groups">Default</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
|
||||
<!-- FormFactory -->
|
||||
<service id="form.factory" class="%form.factory.class%">
|
||||
<argument type="service" id="form.default_context" />
|
||||
</service>
|
||||
|
||||
<!-- FieldFactory -->
|
||||
<service id="form.field_factory" class="%form.field_factory.class%" public="false">
|
||||
<!-- All services with tag "form.field_factory.guesser" are inserted here by AddFieldFactoryGuessersPass -->
|
||||
</service>
|
||||
|
||||
<!-- ValidatorFieldFactoryGuesser -->
|
||||
<service id="form.field_factory.validator_guesser" class="%form.field_factory.validator_guesser.class%" public="false">
|
||||
<tag name="form.field_factory.guesser" />
|
||||
<argument type="service" id="validator.mapping.class_metadata_factory" />
|
||||
</service>
|
||||
|
||||
<!-- FormContext -->
|
||||
<service id="form.default_context" class="%form.default_context.class%">
|
||||
<argument type="service" id="service_container" />
|
||||
<call method="validator">
|
||||
<argument type="service" id="validator" />
|
||||
</call>
|
||||
<call method="validationGroups">
|
||||
<argument>%form.validation_groups%</argument>
|
||||
</call>
|
||||
<call method="fieldFactory">
|
||||
<argument type="service" id="form.field_factory" />
|
||||
</call>
|
||||
<call method="csrfProtection">
|
||||
<argument>%form.csrf_protection.enabled%</argument>
|
||||
</call>
|
||||
<call method="csrfFieldName">
|
||||
<argument>%form.csrf_protection.field_name%</argument>
|
||||
</call>
|
||||
<call method="csrfSecrets">
|
||||
<argument type="collection">
|
||||
<argument>%form.csrf_protection.secret%</argument>
|
||||
</argument>
|
||||
</call>
|
||||
</service>
|
||||
|
||||
</services>
|
||||
</container>
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
@ -9,8 +11,6 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\ValueTransformer\ValueTransformerInterface;
|
||||
use Symfony\Component\Form\ValueTransformer\TransformationFailedException;
|
||||
|
||||
@ -74,7 +74,7 @@ class Field extends Configurable implements FieldInterface
|
||||
$this->addOption('normalization_transformer');
|
||||
|
||||
$this->key = (string)$key;
|
||||
$this->locale = FormConfiguration::getDefaultLocale();
|
||||
$this->locale = FormContext::getLocale();
|
||||
|
||||
parent::__construct($options);
|
||||
|
||||
|
@ -40,6 +40,7 @@ class FieldFactory implements FieldFactoryInterface
|
||||
throw new UnexpectedTypeException($guesser, 'FieldFactoryGuesserInterface');
|
||||
}
|
||||
}
|
||||
|
||||
$this->guessers = $guessers;
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,11 @@ use Symfony\Component\Form\Exception\FormException;
|
||||
* is generated on the fly.
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
|
||||
*/
|
||||
class Form extends FieldGroup
|
||||
{
|
||||
protected $validator = null;
|
||||
protected $validationGroups = null;
|
||||
|
||||
private $csrfSecret = null;
|
||||
private $csrfFieldName = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -53,11 +50,15 @@ class Form extends FieldGroup
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
if (FormConfiguration::isDefaultCsrfProtectionEnabled()) {
|
||||
$this->enableCsrfProtection();
|
||||
}
|
||||
|
||||
$this->addOption('csrf_protection');
|
||||
$this->addOption('csrf_field_name', '_token');
|
||||
$this->addOption('csrf_secrets', array(__FILE__.php_uname()));
|
||||
$this->addOption('field_factory');
|
||||
$this->addOption('validation_groups');
|
||||
|
||||
if (isset($options['validation_groups'])) {
|
||||
$options['validation_groups'] = (array)$options['validation_groups'];
|
||||
}
|
||||
|
||||
parent::__construct($name, $options);
|
||||
|
||||
@ -66,26 +67,16 @@ class Form extends FieldGroup
|
||||
if (null !== $data) {
|
||||
$this->setPropertyPath(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the validation groups for this form.
|
||||
*
|
||||
* @param array|string $validationGroups
|
||||
*/
|
||||
public function setValidationGroups($validationGroups)
|
||||
{
|
||||
$this->validationGroups = null === $validationGroups ? $validationGroups : (array) $validationGroups;
|
||||
}
|
||||
// Enable CSRF protection, if necessary
|
||||
if ($this->getOption('csrf_protection')) {
|
||||
$field = new HiddenField($this->getOption('csrf_field_name'), array(
|
||||
'property_path' => null,
|
||||
));
|
||||
$field->setData($this->generateCsrfToken($this->getOption('csrf_secrets')));
|
||||
|
||||
/**
|
||||
* Returns the validation groups for this form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValidationGroups()
|
||||
{
|
||||
return $this->validationGroups;
|
||||
$this->add($field);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,6 +90,46 @@ class Form extends FieldGroup
|
||||
return $this->getOption('field_factory');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validator used by the form
|
||||
*
|
||||
* @return ValidatorInterface The validator instance
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validation groups validated by the form
|
||||
*
|
||||
* @return array A list of validation groups or null
|
||||
*/
|
||||
public function getValidationGroups()
|
||||
{
|
||||
return $this->getOption('validation_groups');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name used for the CSRF protection field
|
||||
*
|
||||
* @return string The field name
|
||||
*/
|
||||
public function getCsrfFieldName()
|
||||
{
|
||||
return $this->getOption('csrf_field_name');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the secret values used for the CSRF protection
|
||||
*
|
||||
* @return array A list of string valuesf
|
||||
*/
|
||||
public function getCsrfSecrets()
|
||||
{
|
||||
return $this->getOption('csrf_secrets');
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the form with values and files.
|
||||
*
|
||||
@ -132,7 +163,7 @@ class Form extends FieldGroup
|
||||
throw new FormException('A validator is required for binding. Forgot to pass it to the constructor of the form?');
|
||||
}
|
||||
|
||||
if ($violations = $this->validator->validate($this, $this->getValidationGroups())) {
|
||||
if ($violations = $this->validator->validate($this, $this->getOption('validation_groups'))) {
|
||||
// TODO: test me
|
||||
foreach ($violations as $violation) {
|
||||
$propertyPath = new PropertyPath($violation->getPropertyPath());
|
||||
@ -172,20 +203,19 @@ class Form extends FieldGroup
|
||||
*
|
||||
* @return string A token string
|
||||
*/
|
||||
protected function generateCsrfToken($secret)
|
||||
protected function generateCsrfToken(array $secrets)
|
||||
{
|
||||
$secret .= get_class($this);
|
||||
$defaultSecrets = FormConfiguration::getDefaultCsrfSecrets();
|
||||
$implodedSecrets = get_class($this);
|
||||
|
||||
foreach ($defaultSecrets as $defaultSecret) {
|
||||
if ($defaultSecret instanceof \Closure) {
|
||||
$defaultSecret = $defaultSecret();
|
||||
foreach ($secrets as $secret) {
|
||||
if ($secret instanceof \Closure) {
|
||||
$secret = $secret();
|
||||
}
|
||||
|
||||
$secret .= $defaultSecret;
|
||||
$implodedSecrets .= $secret;
|
||||
}
|
||||
|
||||
return md5($secret);
|
||||
return md5($implodedSecrets);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,65 +223,7 @@ class Form extends FieldGroup
|
||||
*/
|
||||
public function isCsrfProtected()
|
||||
{
|
||||
return $this->has($this->getCsrfFieldName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables CSRF protection for this form.
|
||||
*/
|
||||
public function enableCsrfProtection($csrfFieldName = null, $csrfSecret = null)
|
||||
{
|
||||
if (!$this->isCsrfProtected()) {
|
||||
if (null === $csrfFieldName) {
|
||||
$csrfFieldName = FormConfiguration::getDefaultCsrfFieldName();
|
||||
}
|
||||
|
||||
if (null === $csrfSecret) {
|
||||
$csrfSecret = md5(__FILE__.php_uname());
|
||||
}
|
||||
|
||||
$field = new HiddenField($csrfFieldName, array(
|
||||
'property_path' => null,
|
||||
));
|
||||
$field->setData($this->generateCsrfToken($csrfSecret));
|
||||
$this->add($field);
|
||||
|
||||
$this->csrfFieldName = $csrfFieldName;
|
||||
$this->csrfSecret = $csrfSecret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables CSRF protection for this form.
|
||||
*/
|
||||
public function disableCsrfProtection()
|
||||
{
|
||||
if ($this->isCsrfProtected()) {
|
||||
$this->remove($this->getCsrfFieldName());
|
||||
|
||||
$this->csrfFieldName = null;
|
||||
$this->csrfSecret = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSRF field name used in this form
|
||||
*
|
||||
* @return string The CSRF field name
|
||||
*/
|
||||
public function getCsrfFieldName()
|
||||
{
|
||||
return $this->csrfFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CSRF secret used in this form
|
||||
*
|
||||
* @return string The CSRF secret
|
||||
*/
|
||||
public function getCsrfSecret()
|
||||
{
|
||||
return $this->csrfSecret;
|
||||
return $this->has($this->getOption('csrf_field_name'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +236,10 @@ class Form extends FieldGroup
|
||||
if (!$this->isCsrfProtected()) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->get($this->getCsrfFieldName())->getDisplayedData() === $this->generateCsrfToken($this->getCsrfSecret());
|
||||
$actual = $this->get($this->getOption('csrf_field_name'))->getDisplayedData();
|
||||
$expected = $this->generateCsrfToken($this->getOption('csrf_secrets'));
|
||||
|
||||
return $actual === $expected;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,128 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/**
|
||||
* FormConfiguration holds the default configuration for forms (CSRF, locale, ...).
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class FormConfiguration
|
||||
{
|
||||
protected static $defaultCsrfSecrets = array();
|
||||
protected static $defaultCsrfProtection = false;
|
||||
protected static $defaultCsrfFieldName = '_token';
|
||||
|
||||
protected static $defaultLocale = null;
|
||||
|
||||
/**
|
||||
* Sets the default locale for newly created forms.
|
||||
*
|
||||
* @param string $defaultLocale
|
||||
*/
|
||||
static public function setDefaultLocale($defaultLocale)
|
||||
{
|
||||
self::$defaultLocale = $defaultLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default locale for newly created forms.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function getDefaultLocale()
|
||||
{
|
||||
return isset(self::$defaultLocale) ? self::$defaultLocale : \Locale::getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables CSRF protection for all new forms.
|
||||
*/
|
||||
static public function enableDefaultCsrfProtection()
|
||||
{
|
||||
self::$defaultCsrfProtection = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Csrf protection for all forms is enabled.
|
||||
*/
|
||||
static public function isDefaultCsrfProtectionEnabled()
|
||||
{
|
||||
return self::$defaultCsrfProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables Csrf protection for all forms.
|
||||
*/
|
||||
static public function disableDefaultCsrfProtection()
|
||||
{
|
||||
self::$defaultCsrfProtection = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the CSRF field name used in all new CSRF protected forms.
|
||||
*
|
||||
* @param string $name The CSRF field name
|
||||
*/
|
||||
static public function setDefaultCsrfFieldName($name)
|
||||
{
|
||||
self::$defaultCsrfFieldName = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default CSRF field name.
|
||||
*
|
||||
* @return string The CSRF field name
|
||||
*/
|
||||
static public function getDefaultCsrfFieldName()
|
||||
{
|
||||
return self::$defaultCsrfFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default CSRF secrets to be used in all new CSRF protected forms.
|
||||
*
|
||||
* @param array $secrets
|
||||
*/
|
||||
static public function setDefaultCsrfSecrets(array $secrets)
|
||||
{
|
||||
self::$defaultCsrfSecrets = $secrets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds CSRF secrets to be used in all new CSRF protected forms.
|
||||
*
|
||||
* @param string $secret
|
||||
*/
|
||||
static public function addDefaultCsrfSecret($secret)
|
||||
{
|
||||
self::$defaultCsrfSecrets[] = $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the default CSRF secrets.
|
||||
*/
|
||||
static public function clearDefaultCsrfSecrets()
|
||||
{
|
||||
self::$defaultCsrfSecrets = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default CSRF secrets.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function getDefaultCsrfSecrets()
|
||||
{
|
||||
return self::$defaultCsrfSecrets;
|
||||
}
|
||||
}
|
235
src/Symfony/Component/Form/FormContext.php
Normal file
235
src/Symfony/Component/Form/FormContext.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Component\Form\FieldFactory\FieldFactoryInterface;
|
||||
use Symfony\Component\Validator\ValidatorInterface;
|
||||
|
||||
/**
|
||||
* Default implementaton of FormContextInterface
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
|
||||
*/
|
||||
class FormContext implements FormContextInterface
|
||||
{
|
||||
/**
|
||||
* The locale used by new forms
|
||||
* @var string
|
||||
*/
|
||||
protected static $locale = 'en';
|
||||
|
||||
/**
|
||||
* The validator used in the new form
|
||||
* @var ValidatorInterface
|
||||
*/
|
||||
protected $validator = null;
|
||||
|
||||
/**
|
||||
* The validation group(s) validated in the new form
|
||||
* @var string|array
|
||||
*/
|
||||
protected $validationGroups = null;
|
||||
|
||||
/**
|
||||
* The field factory used for automatically creating fields in the form
|
||||
* @var FieldFactoryInterface
|
||||
*/
|
||||
protected $fieldFactory = null;
|
||||
|
||||
/**
|
||||
* The secret strings used for CSRF protection
|
||||
* @var array
|
||||
*/
|
||||
protected $csrfSecrets = null;
|
||||
|
||||
/**
|
||||
* Whether the new form should be CSRF protected
|
||||
* @var boolean
|
||||
*/
|
||||
protected $csrfProtection = false;
|
||||
|
||||
/**
|
||||
* The field name used for the CSRF protection
|
||||
* @var string
|
||||
*/
|
||||
protected $csrfFieldName = '_token';
|
||||
|
||||
/**
|
||||
* Globally sets the locale for new forms and fields
|
||||
*
|
||||
* @param string $locale A valid locale, such as "en", "de_DE" etc.
|
||||
*/
|
||||
public static function setLocale($locale)
|
||||
{
|
||||
self::$locale = $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale used for new forms and fields
|
||||
*
|
||||
* @return string A valid locale, such as "en", "de_DE" etc.
|
||||
*/
|
||||
public static function getLocale()
|
||||
{
|
||||
return self::$locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function validator(ValidatorInterface $validator)
|
||||
{
|
||||
$this->validator = $validator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function validationGroups($validationGroups)
|
||||
{
|
||||
$this->validationGroups = null === $validationGroups ? $validationGroups : (array) $validationGroups;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function fieldFactory(FieldFactoryInterface $fieldFactory)
|
||||
{
|
||||
$this->fieldFactory = $fieldFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function csrfProtection($enabled)
|
||||
{
|
||||
$this->csrfProtection = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function csrfFieldName($name)
|
||||
{
|
||||
$this->csrfFieldName = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function csrfSecrets(array $secrets)
|
||||
{
|
||||
$this->csrfSecrets = $secrets;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getForm($name, $data = null)
|
||||
{
|
||||
return new Form(
|
||||
$name,
|
||||
$data,
|
||||
$this->validator,
|
||||
array(
|
||||
'csrf_protection' => $this->csrfProtection,
|
||||
'csrf_field_name' => $this->csrfFieldName,
|
||||
'csrf_secrets' => $this->csrfSecrets,
|
||||
'validation_groups' => $this->validationGroups,
|
||||
'field_factory' => $this->fieldFactory,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addCsrfSecret($secret)
|
||||
{
|
||||
$this->csrfSecrets[] = $secret;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validator used in the new form
|
||||
*
|
||||
* @return ValidatorInterface The validator instance
|
||||
*/
|
||||
public function getValidator()
|
||||
{
|
||||
return $this->validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validation groups validated by the new form
|
||||
*
|
||||
* @return string|array One or more validation groups
|
||||
*/
|
||||
public function getValidationGroups()
|
||||
{
|
||||
return $this->validationGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field factory used by the new form
|
||||
*
|
||||
* @return FieldFactoryInterface The field factory instance
|
||||
*/
|
||||
public function getFieldFactory()
|
||||
{
|
||||
return $this->fieldFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the new form will be CSRF protected
|
||||
*
|
||||
* @return boolean Whether the form will be CSRF protected
|
||||
*/
|
||||
public function isCsrfProtectionEnabled()
|
||||
{
|
||||
return $this->csrfProtection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field name used for CSRF protection in the new form
|
||||
*
|
||||
* @return string The CSRF field name
|
||||
*/
|
||||
public function getCsrfFieldName()
|
||||
{
|
||||
return $this->csrfFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the secret values used for CSRF protection in the new form
|
||||
*
|
||||
* @return array A list of secret string values
|
||||
*/
|
||||
public function getCsrfSecrets()
|
||||
{
|
||||
return $this->csrfSecrets;
|
||||
}
|
||||
}
|
100
src/Symfony/Component/Form/FormContextInterface.php
Normal file
100
src/Symfony/Component/Form/FormContextInterface.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Component\Form\FieldFactory\FieldFactoryInterface;
|
||||
use Symfony\Component\Validator\ValidatorInterface;
|
||||
|
||||
/**
|
||||
* Stores settings for creating a new form and creates forms
|
||||
*
|
||||
* The methods in this class are chainable, i.e. they return the form context
|
||||
* object itself. When you have finished configuring the new form, call
|
||||
* getForm() to create the form.
|
||||
*
|
||||
* <code>
|
||||
* $form = $context
|
||||
* ->locale('en_US')
|
||||
* ->validationGroups('Address')
|
||||
* ->getForm('author');
|
||||
* </code>
|
||||
*
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
|
||||
*/
|
||||
interface FormContextInterface
|
||||
{
|
||||
/**
|
||||
* Sets the validator used for validating the form
|
||||
*
|
||||
* @param ValidatorInterface $validator The validator instance
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function validator(ValidatorInterface $validator);
|
||||
|
||||
/**
|
||||
* Sets the validation groups validated by the form
|
||||
*
|
||||
* @param string|array $validationGroups One or more validation groups
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function validationGroups($validationGroups);
|
||||
|
||||
/**
|
||||
* Sets the field factory used for automatically creating fields in the form
|
||||
*
|
||||
* @param FieldFactoryInterface $fieldFactory The field factory instance
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function fieldFactory(FieldFactoryInterface $fieldFactory);
|
||||
|
||||
/**
|
||||
* Enables or disables CSRF protection for the form
|
||||
*
|
||||
* @param boolean $enabled Whether the form should be CSRF protected
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function csrfProtection($enabled);
|
||||
|
||||
/**
|
||||
* Sets the field name used for CSRF protection in the form
|
||||
*
|
||||
* @param string $name The CSRF field name
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function csrfFieldName($name);
|
||||
|
||||
/**
|
||||
* Sets the CSRF secrets to be used in the form
|
||||
*
|
||||
* @param array $secrets A list of secret values
|
||||
* @return FormContextInterface This object
|
||||
*/
|
||||
function csrfSecrets(array $secrets);
|
||||
|
||||
/**
|
||||
* Adds another CSRF secrets without removing the existing CSRF secrets
|
||||
*
|
||||
* @param string $secret A secret value
|
||||
* @return FormContextInterface This object
|
||||
* @see csrfSecrets()
|
||||
*/
|
||||
function addCsrfSecret($secret);
|
||||
|
||||
/**
|
||||
* Creates a new form with the settings stored in this context
|
||||
*
|
||||
* @param string $name The name for the form
|
||||
* @param array|object $data The data displayed and modified by the form
|
||||
* @return Form The new form
|
||||
*/
|
||||
function getForm($name, $data = null);
|
||||
}
|
175
src/Symfony/Component/Form/FormFactory.php
Normal file
175
src/Symfony/Component/Form/FormFactory.php
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Component\Form\FieldFactory\FieldFactoryInterface;
|
||||
use Symfony\Component\Validator\ValidatorInterface;
|
||||
|
||||
/**
|
||||
* Creates and configures new form objects
|
||||
*
|
||||
* The default configuration of form objects can be passed to the constructor
|
||||
* as a FormContextInterface object. Call getForm() to create new form objects.
|
||||
*
|
||||
* <code>
|
||||
* $defaultContext = new FormContext();
|
||||
* $defaultContext->locale('en_US');
|
||||
* $defaultContext->csrfProtection(true);
|
||||
* $factory = new FormFactory($defaultContext);
|
||||
*
|
||||
* $form = $factory->getForm('author');
|
||||
* </code>
|
||||
*
|
||||
* You can also override the default configuration by calling any of the
|
||||
* methods in this class. These methods return a FormContextInterface object
|
||||
* on which you can override further settings or call getForm() to create
|
||||
* a form.
|
||||
*
|
||||
* <code>
|
||||
* $form = $factory
|
||||
* ->locale('de_DE')
|
||||
* ->csrfProtection(false)
|
||||
* ->getForm('author');
|
||||
* </code>
|
||||
*
|
||||
* FormFactory instances should be cached and reused in your application.
|
||||
*
|
||||
* @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
|
||||
*/
|
||||
class FormFactory implements FormContextInterface
|
||||
{
|
||||
/**
|
||||
* Holds the context with the default configuration
|
||||
* @var FormContextInterface
|
||||
*/
|
||||
protected $defaultContext;
|
||||
|
||||
/**
|
||||
* Sets the given context as default context
|
||||
*
|
||||
* @param FormContextInterface $defaultContext A preconfigured context
|
||||
*/
|
||||
public function __construct(FormContextInterface $defaultContext = null)
|
||||
{
|
||||
$this->defaultContext = null === $defaultContext ? new FormContext() : $defaultContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the validator of the default context and returns the new context
|
||||
*
|
||||
* @param ValidatorInterface $validator The new validator instance
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function validator(ValidatorInterface $validator)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->validator($validator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the validation groups of the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param string|array $validationGroups One or more validation groups
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function validationGroups($validationGroups)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->validationGroups($validationGroups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the field factory of the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param FieldFactoryInterface $fieldFactory A field factory instance
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function fieldFactory(FieldFactoryInterface $fieldFactory)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->fieldFactory($fieldFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the CSRF protection setting of the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param boolean $enabled Whether the form should be CSRF protected
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function csrfProtection($enabled)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->csrfProtection($enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the CSRF field name setting of the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param string $name The field name to use for CSRF protection
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function csrfFieldName($name)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->csrfFieldName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the CSRF secrets setting of the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param array $secrets The secrets to use for CSRF protection
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function csrfSecrets(array $secrets)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->csrfSecrets($secrets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new CSRF secret to the ones in the default context and returns
|
||||
* the new context
|
||||
*
|
||||
* @param string $secret The secret to add to the secrets used for
|
||||
* CSRF protection
|
||||
* @return FormContextInterface The preconfigured form context
|
||||
*/
|
||||
public function addCsrfSecret($secret)
|
||||
{
|
||||
$context = clone $this->defaultContext;
|
||||
|
||||
return $context->addCsrfSecret($secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new form with the settings stored in the default context
|
||||
*
|
||||
* @param string $name The name for the form
|
||||
* @param array|object $data The data displayed and modified by the form
|
||||
* @return Form The new form
|
||||
*/
|
||||
public function getForm($name, $data = null)
|
||||
{
|
||||
return $this->defaultContext->getForm($name, $data);
|
||||
}
|
||||
}
|
@ -12,13 +12,13 @@
|
||||
namespace Symfony\Tests\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\CountryField;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
|
||||
class CountryFieldTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCountriesAreSelectable()
|
||||
{
|
||||
FormConfiguration::setDefaultLocale('de_AT');
|
||||
FormContext::setLocale('de_AT');
|
||||
|
||||
$field = new CountryField('country');
|
||||
$choices = $field->getOtherChoices();
|
||||
|
@ -14,13 +14,13 @@ namespace Symfony\Tests\Component\Form;
|
||||
require_once __DIR__ . '/DateTimeTestCase.php';
|
||||
|
||||
use Symfony\Component\Form\DateField;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
|
||||
class DateFieldTest extends DateTimeTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
FormConfiguration::setDefaultLocale('de_AT');
|
||||
FormContext::setLocale('de_AT');
|
||||
}
|
||||
|
||||
public function testBind_fromInput_dateTime()
|
||||
|
@ -19,7 +19,7 @@ require_once __DIR__ . '/Fixtures/RequiredOptionsField.php';
|
||||
use Symfony\Component\Form\ValueTransformer\ValueTransformerInterface;
|
||||
use Symfony\Component\Form\PropertyPath;
|
||||
use Symfony\Component\Form\FieldError;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
use Symfony\Component\Form\ValueTransformer\TransformationFailedException;
|
||||
use Symfony\Tests\Component\Form\Fixtures\Author;
|
||||
use Symfony\Tests\Component\Form\Fixtures\TestField;
|
||||
@ -147,7 +147,7 @@ class FieldTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testLocaleIsPassedToValueTransformer()
|
||||
{
|
||||
FormConfiguration::setDefaultLocale('de_DE');
|
||||
FormContext::setLocale('de_DE');
|
||||
|
||||
$transformer = $this->getMock('Symfony\Component\Form\ValueTransformer\ValueTransformerInterface');
|
||||
$transformer->expects($this->exactly(1))
|
||||
|
@ -15,7 +15,7 @@ require_once __DIR__ . '/Fixtures/Author.php';
|
||||
require_once __DIR__ . '/Fixtures/TestField.php';
|
||||
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
use Symfony\Component\Form\Field;
|
||||
use Symfony\Component\Form\HiddenField;
|
||||
use Symfony\Component\Form\FieldGroup;
|
||||
@ -68,10 +68,11 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
FormConfiguration::disableDefaultCsrfProtection();
|
||||
FormConfiguration::setDefaultCsrfSecrets(array());
|
||||
$this->validator = $this->createMockValidator();
|
||||
$this->form = new Form('author', new Author(), $this->validator);
|
||||
$this->form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => false,
|
||||
'csrf_secrets' => array(),
|
||||
));
|
||||
}
|
||||
|
||||
public function testConstructInitializesObject()
|
||||
@ -84,19 +85,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
new TestSetDataBeforeConfigureForm($this, 'author', new Author(), $this->validator);
|
||||
}
|
||||
|
||||
public function testIsCsrfProtected()
|
||||
{
|
||||
$this->assertFalse($this->form->isCsrfProtected());
|
||||
|
||||
$this->form->enableCsrfProtection();
|
||||
|
||||
$this->assertTrue($this->form->isCsrfProtected());
|
||||
|
||||
$this->form->disableCsrfProtection();
|
||||
|
||||
$this->assertFalse($this->form->isCsrfProtected());
|
||||
}
|
||||
|
||||
public function testNoCsrfProtectionByDefault()
|
||||
{
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
@ -104,60 +92,72 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertFalse($form->isCsrfProtected());
|
||||
}
|
||||
|
||||
public function testDefaultCsrfProtectionCanBeEnabled()
|
||||
public function testCsrfProtectionCanBeEnabled()
|
||||
{
|
||||
FormConfiguration::enableDefaultCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
));
|
||||
|
||||
$this->assertTrue($form->isCsrfProtected());
|
||||
}
|
||||
|
||||
public function testGeneratedCsrfSecretByDefault()
|
||||
{
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form->enableCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
));
|
||||
|
||||
$this->assertTrue(strlen($form->getCsrfSecret()) >= 32);
|
||||
$secrets = $form->getCsrfSecrets();
|
||||
|
||||
$this->assertEquals(1, count($secrets));
|
||||
$this->assertTrue(strlen($secrets[0]) >= 32);
|
||||
}
|
||||
|
||||
public function testDefaultCsrfSecretsCanBeAdded()
|
||||
public function testCsrfSecretsCanBeSet()
|
||||
{
|
||||
FormConfiguration::addDefaultCsrfSecret('foobar');
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
'csrf_field_name' => '_token',
|
||||
'csrf_secrets' => array('foobar', 'secret'),
|
||||
));
|
||||
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form->enableCsrfProtection('_token', 'secret');
|
||||
|
||||
$this->assertEquals(md5('secret'.get_class($form).'foobar'), $form['_token']->getData());
|
||||
$this->assertEquals(md5(get_class($form).'foobarsecret'), $form['_token']->getData());
|
||||
}
|
||||
|
||||
public function testDefaultCsrfSecretsCanBeAddedAsClosures()
|
||||
public function testCsrfSecretsCanBeSetAsClosures()
|
||||
{
|
||||
FormConfiguration::addDefaultCsrfSecret(function () {
|
||||
$closure = function () {
|
||||
return 'foobar';
|
||||
});
|
||||
};
|
||||
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form->enableCsrfProtection('_token', 'secret');
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
'csrf_field_name' => '_token',
|
||||
'csrf_secrets' => array($closure, 'secret'),
|
||||
));
|
||||
|
||||
$this->assertEquals(md5('secret'.get_class($form).'foobar'), $form['_token']->getData());
|
||||
$this->assertEquals(md5(get_class($form).'foobarsecret'), $form['_token']->getData());
|
||||
}
|
||||
|
||||
public function testDefaultCsrfFieldNameCanBeSet()
|
||||
public function testCsrfFieldNameCanBeSet()
|
||||
{
|
||||
FormConfiguration::setDefaultCsrfFieldName('foobar');
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form->enableCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
'csrf_field_name' => 'foobar',
|
||||
));
|
||||
|
||||
$this->assertEquals('foobar', $form->getCsrfFieldName());
|
||||
}
|
||||
|
||||
public function testCsrfProtectedFormsHaveExtraField()
|
||||
{
|
||||
$this->form->enableCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
));
|
||||
|
||||
$this->assertTrue($this->form->has($this->form->getCsrfFieldName()));
|
||||
$this->assertTrue($form->has($this->form->getCsrfFieldName()));
|
||||
|
||||
$field = $this->form->get($this->form->getCsrfFieldName());
|
||||
$field = $form->get($form->getCsrfFieldName());
|
||||
|
||||
$this->assertTrue($field instanceof HiddenField);
|
||||
$this->assertGreaterThanOrEqual(32, strlen($field->getDisplayedData()));
|
||||
@ -172,46 +172,61 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testIsCsrfTokenValidPasses()
|
||||
{
|
||||
$this->form->enableCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
));
|
||||
|
||||
$field = $this->form->getCsrfFieldName();
|
||||
$token = $this->form->get($field)->getDisplayedData();
|
||||
$field = $form->getCsrfFieldName();
|
||||
$token = $form->get($field)->getDisplayedData();
|
||||
|
||||
$this->form->bind(array($field => $token));
|
||||
$form->bind(array($field => $token));
|
||||
|
||||
$this->assertTrue($this->form->isCsrfTokenValid());
|
||||
$this->assertTrue($form->isCsrfTokenValid());
|
||||
}
|
||||
|
||||
public function testIsCsrfTokenValidFails()
|
||||
{
|
||||
$this->form->enableCsrfProtection();
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'csrf_protection' => true,
|
||||
));
|
||||
|
||||
$field = $this->form->getCsrfFieldName();
|
||||
$field = $form->getCsrfFieldName();
|
||||
|
||||
$this->form->bind(array($field => 'foobar'));
|
||||
$form->bind(array($field => 'foobar'));
|
||||
|
||||
$this->assertFalse($this->form->isCsrfTokenValid());
|
||||
$this->assertFalse($form->isCsrfTokenValid());
|
||||
}
|
||||
|
||||
public function testValidationGroupsCanBeSet()
|
||||
public function testValidationGroupNullByDefault()
|
||||
{
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$this->assertNull($this->form->getValidationGroups());
|
||||
}
|
||||
|
||||
public function testValidationGroupsCanBeSetToString()
|
||||
{
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'validation_groups' => 'group',
|
||||
));
|
||||
|
||||
$this->assertNull($form->getValidationGroups());
|
||||
$form->setValidationGroups('group');
|
||||
$this->assertEquals(array('group'), $form->getValidationGroups());
|
||||
$form->setValidationGroups(array('group1', 'group2'));
|
||||
}
|
||||
|
||||
public function testValidationGroupsCanBeSetToArray()
|
||||
{
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'validation_groups' => array('group1', 'group2'),
|
||||
));
|
||||
|
||||
$this->assertEquals(array('group1', 'group2'), $form->getValidationGroups());
|
||||
$form->setValidationGroups(null);
|
||||
$this->assertNull($form->getValidationGroups());
|
||||
}
|
||||
|
||||
public function testBindUsesValidationGroups()
|
||||
{
|
||||
$field = $this->createMockField('firstName');
|
||||
$form = new Form('author', new Author(), $this->validator);
|
||||
$form = new Form('author', new Author(), $this->validator, array(
|
||||
'validation_groups' => 'group',
|
||||
));
|
||||
$form->add($field);
|
||||
$form->setValidationGroups('group');
|
||||
|
||||
$this->validator->expects($this->once())
|
||||
->method('validate')
|
||||
@ -225,7 +240,6 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$field = $this->createMockField('firstName');
|
||||
$form = new Form('author', new Author());
|
||||
$form->add($field);
|
||||
$form->setValidationGroups('group');
|
||||
|
||||
$this->setExpectedException('Symfony\Component\Form\Exception\FormException');
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
namespace Symfony\Tests\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\LanguageField;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
|
||||
class LanguageFieldTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCountriesAreSelectable()
|
||||
{
|
||||
FormConfiguration::setDefaultLocale('de_AT');
|
||||
FormContext::setLocale('de_AT');
|
||||
|
||||
$field = new LanguageField('language');
|
||||
$choices = $field->getOtherChoices();
|
||||
|
@ -12,13 +12,13 @@
|
||||
namespace Symfony\Tests\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\LocaleField;
|
||||
use Symfony\Component\Form\FormConfiguration;
|
||||
use Symfony\Component\Form\FormContext;
|
||||
|
||||
class LocaleFieldTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testLocalesAreSelectable()
|
||||
{
|
||||
FormConfiguration::setDefaultLocale('de_AT');
|
||||
FormContext::setLocale('de_AT');
|
||||
|
||||
$field = new LocaleField('language');
|
||||
$choices = $field->getOtherChoices();
|
||||
|
Reference in New Issue
Block a user