[Form] added method guessPattern
to FormTypeGuesserInterface
rephrase changelog
This commit is contained in:
parent
b0a6956bdc
commit
f7200e479c
@ -277,6 +277,7 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||
* [BC BREAK] renamed "field_*" theme blocks to "form_*" and "field_widget" to
|
||||
"input"
|
||||
* ValidatorTypeGuesser now guesses "collection" for array type constraint
|
||||
* added method `guessPattern` to FormTypeGuesserInterface to guess which pattern to use in the HTML5 attribute "pattern"
|
||||
|
||||
### HttpFoundation
|
||||
|
||||
|
@ -115,7 +115,7 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessMinLength($class, $property)
|
||||
public function guessPattern($class, $property)
|
||||
{
|
||||
$ret = $this->getMetadata($class);
|
||||
if ($ret && $ret[0]->hasField($property) && !$ret[0]->hasAssociation($property)) {
|
||||
|
@ -124,7 +124,7 @@ class PropelTypeGuesser implements FormTypeGuesserInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessMinLength($class, $property)
|
||||
public function guessPattern($class, $property)
|
||||
{
|
||||
if ($column = $this->getColumn($class, $property)) {
|
||||
switch ($column->getType()) {
|
||||
|
@ -46,14 +46,14 @@ class PropelTypeGuesserTest extends Propel1TestCase
|
||||
|
||||
public function testGuessMinLengthWithText()
|
||||
{
|
||||
$value = $this->guesser->guessMinLength(self::CLASS_NAME, 'value');
|
||||
$value = $this->guesser->guessPattern(self::CLASS_NAME, 'value');
|
||||
|
||||
$this->assertNull($value);
|
||||
}
|
||||
|
||||
public function testGuessMinLengthWithFloat()
|
||||
{
|
||||
$value = $this->guesser->guessMinLength(self::CLASS_NAME, 'price');
|
||||
$value = $this->guesser->guessPattern(self::CLASS_NAME, 'price');
|
||||
|
||||
$this->assertNotNull($value);
|
||||
$this->assertNull($value->getValue());
|
||||
|
31
src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php
Normal file → Executable file
31
src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php
Normal file → Executable file
@ -68,12 +68,12 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessMinLength($class, $property)
|
||||
public function guessPattern($class, $property)
|
||||
{
|
||||
$guesser = $this;
|
||||
|
||||
return $this->guess($class, $property, function (Constraint $constraint) use ($guesser) {
|
||||
return $guesser->guessMinLengthForConstraint($constraint);
|
||||
return $guesser->guessPatternForConstraint($constraint);
|
||||
});
|
||||
}
|
||||
|
||||
@ -205,32 +205,35 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses a field's minimum length based on the given constraint
|
||||
*
|
||||
* Guesses a field's pattern based on the given constraint
|
||||
*
|
||||
* @param Constraint $constraint The constraint to guess for
|
||||
*
|
||||
* @return Guess The guess for the minimum length
|
||||
* @return Guess The guess for the pattern
|
||||
*/
|
||||
public function guessMinLengthForConstraint(Constraint $constraint)
|
||||
public function guessPatternForConstraint(Constraint $constraint)
|
||||
{
|
||||
switch (get_class($constraint)) {
|
||||
case 'Symfony\Component\Validator\Constraints\MinLength':
|
||||
return new ValueGuess($constraint->limit, Guess::HIGH_CONFIDENCE);
|
||||
return new ValueGuess(sprintf('.{%s,}', (string) $constraint->limit), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\SizeLength':
|
||||
return new ValueGuess($constraint->min, Guess::HIGH_CONFIDENCE);
|
||||
return new ValueGuess(sprintf('.{%s,%s}', (string) $constraint->min, (string) $constraint->max), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Regex':
|
||||
return new ValueGuess($constraint->pattern, Guess::HIGH_CONFIDENCE );
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Min':
|
||||
return new ValueGuess(sprintf('.{%s,}', strlen((string) $constraint->limit)), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Size':
|
||||
return new ValueGuess(sprintf('.{%s,%s}', strlen((string) $constraint->min), strlen((string) $constraint->max)), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Type':
|
||||
if (in_array($constraint->type, array('double', 'float', 'numeric', 'real'))) {
|
||||
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Min':
|
||||
return new ValueGuess(strlen((string) $constraint->limit), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Size':
|
||||
return new ValueGuess(strlen((string) $constraint->min), Guess::LOW_CONFIDENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ class FormFactory implements FormFactoryInterface
|
||||
/**
|
||||
* Returns a form builder for a property of a class.
|
||||
*
|
||||
* If any of the 'max_length', 'required' and type options can be guessed,
|
||||
* If any of the 'max_length', 'required', 'pattern' and type options can be guessed,
|
||||
* and are not provided in the options argument, the guessed value is used.
|
||||
*
|
||||
* @param string $class The fully qualified class name
|
||||
@ -327,27 +327,26 @@ class FormFactory implements FormFactoryInterface
|
||||
|
||||
$typeGuess = $this->guesser->guessType($class, $property);
|
||||
$maxLengthGuess = $this->guesser->guessMaxLength($class, $property);
|
||||
$minLengthGuess = $this->guesser->guessMinLength($class, $property);
|
||||
$requiredGuess = $this->guesser->guessRequired($class, $property);
|
||||
$patternGuess = $this->guesser->guessPattern($class, $property);
|
||||
|
||||
$type = $typeGuess ? $typeGuess->getType() : 'text';
|
||||
|
||||
$maxLength = $maxLengthGuess ? $maxLengthGuess->getValue() : null;
|
||||
$minLength = $minLengthGuess ? $minLengthGuess->getValue() : null;
|
||||
$minLength = $minLength ?: 0;
|
||||
$pattern = $patternGuess ? $patternGuess->getValue() : null;
|
||||
|
||||
if (null !== $maxLength) {
|
||||
$options = array_merge(array('max_length' => $maxLength), $options);
|
||||
}
|
||||
|
||||
if ($minLength > 0) {
|
||||
$options = array_merge(array('pattern' => '.{'.$minLength.','.$maxLength.'}'), $options);
|
||||
}
|
||||
|
||||
if ($requiredGuess) {
|
||||
$options = array_merge(array('required' => $requiredGuess->getValue()), $options);
|
||||
}
|
||||
|
||||
if (null !== $pattern) {
|
||||
$options = array_merge(array('pattern' => $pattern), $options);
|
||||
}
|
||||
|
||||
// user options may override guessed options
|
||||
if ($typeGuess) {
|
||||
$options = array_merge($typeGuess->getOptions(), $options);
|
||||
|
@ -40,6 +40,9 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessType($class, $property)
|
||||
{
|
||||
return $this->guess(function ($guesser) use ($class, $property) {
|
||||
@ -47,6 +50,9 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessRequired($class, $property)
|
||||
{
|
||||
return $this->guess(function ($guesser) use ($class, $property) {
|
||||
@ -54,6 +60,9 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessMaxLength($class, $property)
|
||||
{
|
||||
return $this->guess(function ($guesser) use ($class, $property) {
|
||||
@ -61,10 +70,13 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
|
||||
});
|
||||
}
|
||||
|
||||
public function guessMinLength($class, $property)
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function guessPattern($class, $property)
|
||||
{
|
||||
return $this->guess(function ($guesser) use ($class, $property) {
|
||||
return $guesser->guessMinLength($class, $property);
|
||||
return $guesser->guessPattern($class, $property);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,18 @@ interface FormTypeGuesserInterface
|
||||
function guessMaxLength($class, $property);
|
||||
|
||||
/**
|
||||
* Returns a guess about the field's minimum length
|
||||
* Returns a guess about the field's pattern
|
||||
*
|
||||
* - When you have a min value, you guess a min length of this min (LOW_CONFIDENCE) , lines below
|
||||
* - If this value is a float type, this is wrong so you guess null with MEDIUM_CONFIDENCE to override the previous guess.
|
||||
* Example:
|
||||
* You want a float greater than 5, 4.512313 is not valid but length(4.512314) > length(5)
|
||||
* @link https://github.com/symfony/symfony/pull/3927
|
||||
*
|
||||
* @param string $class The fully qualified class name
|
||||
* @param string $property The name of the property to guess for
|
||||
*
|
||||
* @return Guess A guess for the field's minimum length
|
||||
* @return Guess A guess for the field's required pattern
|
||||
*/
|
||||
function guessMinLength($class, $property);
|
||||
|
||||
function guessPattern($class, $property);
|
||||
}
|
||||
|
@ -491,6 +491,39 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('builderInstance', $builder);
|
||||
}
|
||||
|
||||
public function testCreateBuilderUsesPatternIfFound()
|
||||
{
|
||||
$this->guesser1->expects($this->once())
|
||||
->method('guessPattern')
|
||||
->with('Application\Author', 'firstName')
|
||||
->will($this->returnValue(new ValueGuess(
|
||||
'/[a-z]/',
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
)));
|
||||
|
||||
$this->guesser2->expects($this->once())
|
||||
->method('guessPattern')
|
||||
->with('Application\Author', 'firstName')
|
||||
->will($this->returnValue(new ValueGuess(
|
||||
'/[a-zA-Z]/',
|
||||
Guess::HIGH_CONFIDENCE
|
||||
)));
|
||||
|
||||
$factory = $this->createMockFactory(array('createNamedBuilder'));
|
||||
|
||||
$factory->expects($this->once())
|
||||
->method('createNamedBuilder')
|
||||
->with('text', 'firstName', null, array('pattern' => '/[a-zA-Z]/'))
|
||||
->will($this->returnValue('builderInstance'));
|
||||
|
||||
$builder = $factory->createBuilderForProperty(
|
||||
'Application\Author',
|
||||
'firstName'
|
||||
);
|
||||
|
||||
$this->assertEquals('builderInstance', $builder);
|
||||
}
|
||||
|
||||
public function testCreateNamedBuilderFromParentBuilder()
|
||||
{
|
||||
$type = new FooType();
|
||||
@ -541,18 +574,18 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$factory->createNamedBuilder($type, "text", "value", array("unknown" => "opt"));
|
||||
}
|
||||
|
||||
public function testFormTypeCreatesDefaultValueForEmptyDataOption()
|
||||
{
|
||||
$factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension()));
|
||||
|
||||
$form = $factory->createNamedBuilder(new AuthorType(), 'author')->getForm();
|
||||
$form->bind(array('firstName' => 'John', 'lastName' => 'Smith'));
|
||||
|
||||
$author = new Author();
|
||||
$author->firstName = 'John';
|
||||
$author->setLastName('Smith');
|
||||
|
||||
$this->assertEquals($author, $form->getData());
|
||||
public function testFieldTypeCreatesDefaultValueForEmptyDataOption()
|
||||
{
|
||||
$factory = new FormFactory(array(new \Symfony\Component\Form\Extension\Core\CoreExtension()));
|
||||
|
||||
$form = $factory->createNamedBuilder(new AuthorType(), 'author')->getForm();
|
||||
$form->bind(array('firstName' => 'John', 'lastName' => 'Smith'));
|
||||
|
||||
$author = new Author();
|
||||
$author->firstName = 'John';
|
||||
$author->setLastName('Smith');
|
||||
|
||||
$this->assertEquals($author, $form->getData());
|
||||
}
|
||||
|
||||
private function createMockFactory(array $methods = array())
|
||||
|
Reference in New Issue
Block a user