Skip to content

Commit

Permalink
[Form] Extracted validation logic of form. Fields can now contain mul…
Browse files Browse the repository at this point in the history
…tiple validators
  • Loading branch information
Bernhard Schussek committed Mar 20, 2011
1 parent 2d0096f commit b620dc6
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 64 deletions.
16 changes: 11 additions & 5 deletions Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Field implements FieldInterface
private $normTransformer;
private $clientTransformer;
private $transformationSuccessful = true;
private $validator;
private $validators;
private $renderer;
private $readOnly = false;
private $dispatcher;
Expand All @@ -74,15 +74,21 @@ class Field implements FieldInterface
public function __construct($name, EventDispatcherInterface $dispatcher,
RendererInterface $renderer, DataTransformerInterface $clientTransformer = null,
DataTransformerInterface $normTransformer = null,
FieldValidatorInterface $validator = null, $required = false,
array $validators = array(), $required = false,
$readOnly = false, array $attributes = array())
{
foreach ($validators as $validator) {
if (!$validator instanceof FieldValidatorInterface) {
throw new UnexpectedTypeException($validator, 'Symfony\Component\Form\Validator\FieldValidatorInterface');
}
}

$this->name = (string)$name;
$this->dispatcher = $dispatcher;
$this->renderer = $renderer;
$this->clientTransformer = $clientTransformer;
$this->normTransformer = $normTransformer;
$this->validator = $validator;
$this->validators = $validators;
$this->required = $required;
$this->readOnly = $readOnly;
$this->attributes = $attributes;
Expand Down Expand Up @@ -276,8 +282,8 @@ public function bind($clientData)
$event = new DataEvent($this, $clientData);
$this->dispatcher->dispatch(Events::postBind, $event);

if ($this->validator) {
$this->validator->validate($this);
foreach ($this->validators as $validator) {
$validator->validate($this);
}
}

Expand Down
14 changes: 8 additions & 6 deletions FieldBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FieldBuilder

private $theme;

private $validator;
private $validators = array();

private $attributes = array();

Expand Down Expand Up @@ -139,14 +139,16 @@ public function getRequired()
return $this->required;
}

public function setValidator(FieldValidatorInterface $validator)
public function addValidator(FieldValidatorInterface $validator)
{
$this->validator = $validator;
$this->validators[] = $validator;

return $this;
}

public function getValidator()
public function getValidators()
{
return $this->validator;
return $this->validators;
}

/**
Expand Down Expand Up @@ -286,7 +288,7 @@ public function getInstance()
$this->buildRenderer(),
$this->getClientTransformer(),
$this->getNormTransformer(),
$this->getValidator(),
$this->getValidators(),
$this->getRequired(),
$this->getReadOnly(),
$this->getAttributes()
Expand Down
47 changes: 7 additions & 40 deletions Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ class Form extends Field implements \IteratorAggregate, FormInterface
* Contains the names of bound values who don't belong to any fields
* @var array
*/
private $extraFields = array();
private $extraData = array();

private $dataMapper;

public function __construct($name, EventDispatcherInterface $dispatcher,
RendererInterface $renderer, DataTransformerInterface $clientTransformer = null,
DataTransformerInterface $normalizationTransformer = null,
DataMapperInterface $dataMapper, FieldValidatorInterface $validator = null,
DataMapperInterface $dataMapper, array $validators = null,
$required = false, $readOnly = false, array $attributes = array())
{
$dispatcher->addListener(array(
Expand All @@ -76,7 +76,7 @@ public function __construct($name, EventDispatcherInterface $dispatcher,
$this->dataMapper = $dataMapper;

parent::__construct($name, $dispatcher, $renderer, $clientTransformer,
$normalizationTransformer, $validator, $required, $readOnly,
$normalizationTransformer, $validators, $required, $readOnly,
$attributes);
}

Expand Down Expand Up @@ -177,13 +177,13 @@ public function filterBoundClientData(FilterDataEvent $event)
}
}

$this->extraFields = array();
$this->extraData = array();

foreach ($data as $name => $value) {
if ($this->has($name)) {
$this->fields[$name]->bind($value);
} else {
$this->extraFields[] = $name;
$this->extraData[$name] = $value;
}
}

Expand All @@ -195,15 +195,9 @@ public function filterBoundClientData(FilterDataEvent $event)
$event->setData($data);
}

/**
* Returns whether this form was bound with extra fields
*
* @return Boolean
*/
public function isBoundWithExtraFields()
public function getExtraData()
{
// TODO: integrate the field names in the error message
return count($this->extraFields) > 0;
return $this->extraData;
}

/**
Expand Down Expand Up @@ -329,33 +323,6 @@ public function bindRequest(Request $request)
$this->bind($data);
}

/**
* Returns whether the maximum POST size was reached in this request.
*
* @return Boolean
*/
public function isPostMaxSizeReached()
{
if ($this->isRoot() && isset($_SERVER['CONTENT_LENGTH'])) {
$length = (int) $_SERVER['CONTENT_LENGTH'];
$max = trim(ini_get('post_max_size'));

switch (strtolower(substr($max, -1))) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$max *= 1024;
case 'm':
$max *= 1024;
case 'k':
$max *= 1024;
}

return $length > $max;
}

return false;
}

/**
* Validates the data of this form
*
Expand Down
2 changes: 1 addition & 1 deletion FormBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public function getInstance()
$this->getClientTransformer(),
$this->getNormTransformer(),
$this->getDataMapper(),
$this->getValidator(),
$this->getValidators(),
$this->getRequired(),
$this->getReadOnly(),
$this->getAttributes()
Expand Down
10 changes: 0 additions & 10 deletions Resources/config/validation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@
<property name="fields">
<constraint name="Valid" />
</property>
<getter property="boundWithExtraFields">
<constraint name="AssertFalse">
<option name="message">This form should not contain extra fields</option>
</constraint>
</getter>
<getter property="postMaxSizeReached">
<constraint name="AssertFalse">
<option name="message">The uploaded file was too large. Please try to upload a smaller file</option>
</constraint>
</getter>
</class>

<class name="Symfony\Component\Form\RepeatedField">
Expand Down
2 changes: 1 addition & 1 deletion Type/CsrfType.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function configure(FieldBuilder $builder, array $options)

$builder
->setData($csrfProvider->generateCsrfToken($pageId))
->setValidator(new CallbackValidator(
->addValidator(new CallbackValidator(
function (FieldInterface $field) use ($csrfProvider, $pageId) {
if (!$csrfProvider->isCsrfTokenValid($pageId, $field->getData())) {
// FIXME this error is currently not displayed
Expand Down
2 changes: 1 addition & 1 deletion Type/FieldType.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function configure(FieldBuilder $builder, array $options)
->setData($options['data'])
->setRenderer(new DefaultRenderer($this->theme, $options['template']))
->addRendererPlugin(new FieldPlugin())
->setValidator(new DelegatingValidator($this->validator));
->addValidator(new DelegatingValidator($this->validator));

if ($options['trim']) {
$builder->addEventSubscriber(new TrimListener());
Expand Down
2 changes: 2 additions & 0 deletions Type/FormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\Form\CsrfProvider\CsrfProviderInterface;
use Symfony\Component\Form\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Renderer\Plugin\FormPlugin;
use Symfony\Component\Form\Validator\FormValidator;
use Symfony\Component\EventDispatcher\EventDispatcher;

class FormType extends AbstractType
Expand All @@ -32,6 +33,7 @@ public function configure(FieldBuilder $builder, array $options)
{
$builder->setAttribute('virtual', $options['virtual'])
->addRendererPlugin(new FormPlugin())
->addValidator(new FormValidator())
->setDataClass($options['data_class'])
->setDataMapper(new PropertyPathMapper(
$options['data_class'],
Expand Down
44 changes: 44 additions & 0 deletions Validator/FormValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?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\Validator;

use Symfony\Component\Form\FieldInterface;
use Symfony\Component\Form\FieldError;

class FormValidator implements FieldValidatorInterface
{
public function validate(FieldInterface $form)
{
if (count($form->getExtraData()) > 0) {
$form->addError(new FieldError('This form should not contain extra fields'));
}

if ($form->isRoot() && isset($_SERVER['CONTENT_LENGTH'])) {
$length = (int) $_SERVER['CONTENT_LENGTH'];
$max = trim(ini_get('post_max_size'));

switch (strtolower(substr($max, -1))) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$max *= 1024;
case 'm':
$max *= 1024;
case 'k':
$max *= 1024;
}

if ($length > $max) {
$form->addError(new FieldError('The uploaded file was too large. Please try to upload a smaller file'));
}
}
}
}

0 comments on commit b620dc6

Please sign in to comment.