diff --git a/src/Symfony/Component/Form/CallbackTransformer.php b/src/Symfony/Component/Form/CallbackTransformer.php index b5b7d2dd57..1dfe890027 100644 --- a/src/Symfony/Component/Form/CallbackTransformer.php +++ b/src/Symfony/Component/Form/CallbackTransformer.php @@ -42,7 +42,7 @@ class CallbackTransformer implements DataTransformerInterface * * @param mixed $data The value in the original representation * - * @return mixed The value in the transformed representation + * @return mixed The value in the transformed representation * * @throws UnexpectedTypeException when the argument is not a string * @throws TransformationFailedException when the transformation fails @@ -58,7 +58,7 @@ class CallbackTransformer implements DataTransformerInterface * * @param mixed $data The value in the transformed representation * - * @return mixed The value in the original representation + * @return mixed The value in the original representation * * @throws UnexpectedTypeException when the argument is not of the expected type * @throws TransformationFailedException when the transformation fails diff --git a/src/Symfony/Component/Form/DataTransformerInterface.php b/src/Symfony/Component/Form/DataTransformerInterface.php index 33d9d47ccf..e163322d48 100644 --- a/src/Symfony/Component/Form/DataTransformerInterface.php +++ b/src/Symfony/Component/Form/DataTransformerInterface.php @@ -41,7 +41,7 @@ interface DataTransformerInterface * * @param mixed $value The value in the original representation * - * @return mixed The value in the transformed representation + * @return mixed The value in the transformed representation * * @throws UnexpectedTypeException when the argument is not a string * @throws TransformationFailedException when the transformation fails @@ -68,7 +68,7 @@ interface DataTransformerInterface * * @param mixed $value The value in the transformed representation * - * @return mixed The value in the original representation + * @return mixed The value in the original representation * * @throws UnexpectedTypeException when the argument is not of the expected type * @throws TransformationFailedException when the transformation fails diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php index 9a57cf664e..08e4829350 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/BooleanToStringTransformer.php @@ -43,7 +43,7 @@ class BooleanToStringTransformer implements DataTransformerInterface * * @param Boolean $value Boolean value. * - * @return string String value. + * @return string String value. * * @throws UnexpectedTypeException if the given value is not a Boolean */ @@ -65,7 +65,7 @@ class BooleanToStringTransformer implements DataTransformerInterface * * @param string $value String value. * - * @return Boolean Boolean value. + * @return Boolean Boolean value. * * @throws UnexpectedTypeException if the given value is not a string */ diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php index d4b735554e..0e42baa847 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php @@ -46,7 +46,7 @@ class DataTransformerChain implements DataTransformerInterface * * @param mixed $value The original value * - * @return mixed The transformed value + * @return mixed The transformed value * * @throws Symfony\Component\Form\Exception\TransformationFailedException * @throws Symfony\Component\Form\Exception\UnexpectedTypeException @@ -71,7 +71,7 @@ class DataTransformerChain implements DataTransformerInterface * * @param mixed $value The transformed value * - * @return mixed The reverse-transformed value + * @return mixed The reverse-transformed value * * @throws Symfony\Component\Form\Exception\TransformationFailedException * @throws Symfony\Component\Form\Exception\UnexpectedTypeException diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php index 68bf04802a..cb60211164 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php @@ -53,7 +53,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer * * @param DateTime $dateTime Normalized date. * - * @return array Localized date. + * @return array Localized date. * * @throws UnexpectedTypeException if the given value is not an instance of \DateTime * @throws TransformationFailedException if the output timezone is not supported @@ -108,7 +108,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer * * @param array $value Localized date * - * @return DateTime Normalized date + * @return DateTime Normalized date * * @throws UnexpectedTypeException if the given value is not an array * @throws TransformationFailedException if the value could not bet transformed diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php index 4b44a081ec..fd0ced228f 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php @@ -48,7 +48,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer * * @param DateTime $value A DateTime object * - * @return string A value as produced by PHP's date() function + * @return string A value as produced by PHP's date() function * * @throws UnexpectedTypeException if the given value is not a \DateTime instance * @throws TransformationFailedException if the output timezone is not supported diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php index d4967bbc65..1671f268de 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php @@ -27,7 +27,7 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer * * @param DateTime $value A DateTime object * - * @return integer A timestamp + * @return integer A timestamp * * @throws UnexpectedTypeException if the given value is not an instance of \DateTime * @throws TransformationFailedException if the output timezone is not supported diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index df63ed0f6a..6a835f993f 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php @@ -48,7 +48,7 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransform * * @param number $value Normalized number * - * @return string Localized money string. + * @return string Localized money string. * * @throws UnexpectedTypeException if the given value is not numeric * @throws TransformationFailedException if the value can not be transformed diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php index f05d598f3b..7ee6580c9b 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php @@ -66,7 +66,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface * * @param number $value Normalized value * - * @return number Percentage value + * @return number Percentage value * * @throws UnexpectedTypeException if the given value is not numeric * @throws TransformationFailedException if the value could not be transformed @@ -101,7 +101,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface * * @param number $value Percentage value. * - * @return number Normalized value. + * @return number Normalized value. * * @throws UnexpectedTypeException if the given value is not a string * @throws TransformationFailedException if the value could not be transformed diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToStringTransformer.php index 7e568958d8..084778ee42 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ValueToStringTransformer.php @@ -26,7 +26,7 @@ class ValueToStringTransformer implements DataTransformerInterface * * @param mixed $value Mixed value. * - * @return string String value. + * @return string String value. * * @throws UnexpectedTypeException if the given value is not a string or number */ @@ -48,7 +48,7 @@ class ValueToStringTransformer implements DataTransformerInterface * * @param string $value String value. * - * @return string String value. + * @return string String value. * * @throws UnexpectedTypeException if the given value is not a string */ diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php index 399ca911a0..41edcc0eff 100755 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php @@ -89,7 +89,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface * * @param Constraint $constraint The constraint to guess for * - * @return TypeGuess The guessed field class and options + * @return TypeGuess The guessed field class and options */ public function guessTypeForConstraint(Constraint $constraint) { @@ -178,7 +178,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface * * @param Constraint $constraint The constraint to guess for * - * @return Guess The guess whether the field is required + * @return Guess The guess whether the field is required */ public function guessRequiredForConstraint(Constraint $constraint) { @@ -194,7 +194,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface * * @param Constraint $constraint The constraint to guess for * - * @return Guess The guess for the maximum length + * @return Guess The guess for the maximum length */ public function guessMaxLengthForConstraint(Constraint $constraint) { @@ -282,7 +282,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface * @param mixed $default The default value assumed if no other value * can be guessed. * - * @return Guess The guessed value with the highest confidence + * @return Guess The guessed value with the highest confidence */ protected function guess($class, $property, \Closure $closure, $defaultValue = null) { diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php index 5da4a58cf7..4e7b27c36d 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php @@ -89,11 +89,11 @@ class ViolationMapper } } - $template = $violation->getMessageTemplate(); - $parameters = $violation->getMessageParameters(); - $pluralization = $violation->getMessagePluralization(); - - $this->scope->addError(new FormError($template, $parameters, $pluralization)); + $this->scope->addError(new FormError( + $violation->getMessageTemplate(), + $violation->getMessageParameters(), + $violation->getMessagePluralization() + )); } /** @@ -177,9 +177,9 @@ class ViolationMapper * Reconstructs a property path from a violation path and a form tree. * * @param ViolationPath $violationPath The violation path. - * @param FormInterface $origin The root form of the tree. + * @param FormInterface $origin The root form of the tree. * - * @return RelativePath The reconstructed path. + * @return RelativePath The reconstructed path. */ private function reconstructPath(ViolationPath $violationPath, FormInterface $origin) { @@ -220,10 +220,10 @@ class ViolationMapper // Property path of a mapped form is null // Should not happen, bail out break; - } else { - $propertyPathBuilder->replace($i, 1, $propertyPath); - $i += $propertyPath->getLength(); } + + $propertyPathBuilder->replace($i, 1, $propertyPath); + $i += $propertyPath->getLength(); } } diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php index 7426fc42c3..757229d8a3 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php +++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationPath.php @@ -43,7 +43,7 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface /** * @var string */ - private $string = ''; + private $pathAsString = ''; /** * @var integer @@ -59,32 +59,28 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface public function __construct($violationPath) { $path = new PropertyPath($violationPath); - $pathElements = $path->getElements(); - $pathPositions = $path->getPositions(); - $elements = array(); - $positions = array(); - $isIndex = array(); - $mapsForm = array(); + $elements = $path->getElements(); + $positions = $path->getPositions(); $data = false; - for ($i = 0, $l = count($pathElements); $i < $l; ++$i) { + for ($i = 0, $l = count($elements); $i < $l; ++$i) { if (!$data) { // The element "data" has not yet been passed - if ('children' === $pathElements[$i] && $path->isProperty($i)) { + if ('children' === $elements[$i] && $path->isProperty($i)) { // Skip element "children" ++$i; // Next element must exist and must be an index - // Otherwise not a valid path + // Otherwise consider this the end of the path if ($i >= $l || !$path->isIndex($i)) { - return; + break; } - $elements[] = $pathElements[$i]; - $positions[] = $pathPositions[$i]; - $isIndex[] = true; - $mapsForm[] = true; - } elseif ('data' === $pathElements[$i] && $path->isProperty($i)) { + $this->elements[] = $elements[$i]; + $this->positions[] = $positions[$i]; + $this->isIndex[] = true; + $this->mapsForm[] = true; + } elseif ('data' === $elements[$i] && $path->isProperty($i)) { // Skip element "data" ++$i; @@ -93,32 +89,28 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface break; } - $elements[] = $pathElements[$i]; - $positions[] = $pathPositions[$i]; - $isIndex[] = $path->isIndex($i); - $mapsForm[] = false; + $this->elements[] = $elements[$i]; + $this->positions[] = $positions[$i]; + $this->isIndex[] = $path->isIndex($i); + $this->mapsForm[] = false; $data = true; } else { // Neither "children" nor "data" property found - // Be nice and consider this the end of the path + // Consider this the end of the path break; } } else { // Already after the "data" element // Pick everything as is - $elements[] = $pathElements[$i]; - $positions[] = $pathPositions[$i]; - $isIndex[] = $path->isIndex($i); - $mapsForm[] = false; + $this->elements[] = $elements[$i]; + $this->positions[] = $positions[$i]; + $this->isIndex[] = $path->isIndex($i); + $this->mapsForm[] = false; } } - $this->elements = $elements; - $this->positions = $positions; - $this->isIndex = $isIndex; - $this->mapsForm = $mapsForm; - $this->length = count($elements); - $this->string = $violationPath; + $this->length = count($this->elements); + $this->pathAsString = $violationPath; $this->resizeString(); } @@ -128,7 +120,7 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface */ public function __toString() { - return $this->string; + return $this->pathAsString; } /** @@ -215,7 +207,7 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface * * @param integer $index The element index. * - * @return Boolean Whether the element maps to a form. + * @return Boolean Whether the element maps to a form. */ public function mapsForm($index) { @@ -241,7 +233,7 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface $lastIndex = $this->length - 1; if ($lastIndex < 0) { - $this->string = ''; + $this->pathAsString = ''; } else { // +1 for the dot/opening bracket $length = $this->positions[$lastIndex] + strlen($this->elements[$lastIndex]) + 1; @@ -251,7 +243,7 @@ class ViolationPath implements \IteratorAggregate, PropertyPathInterface ++$length; } - $this->string = substr($this->string, 0, $length); + $this->pathAsString = substr($this->pathAsString, 0, $length); } } } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 3525ecd8cc..129ba0bda4 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -127,8 +127,8 @@ class Form implements \IteratorAggregate, FormInterface */ public function __construct(FormConfigInterface $config) { - if (!$config instanceof ImmutableFormConfig) { - $config = new ImmutableFormConfig($config); + if (!$config instanceof UnmodifiableFormConfig) { + $config = new UnmodifiableFormConfig($config); } $this->config = $config; @@ -146,7 +146,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns the configuration of the form. * - * @return ImmutableFormConfig The form's immutable configuration. + * @return UnmodifiableFormConfig The form's immutable configuration. */ public function getConfig() { @@ -156,7 +156,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns the name by which the form is identified in forms. * - * @return string The name of the form. + * @return string The name of the form. */ public function getName() { @@ -265,7 +265,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns the root of the form tree. * - * @return FormInterface The root of the tree + * @return FormInterface The root of the tree */ public function getRoot() { @@ -287,7 +287,7 @@ class Form implements \IteratorAggregate, FormInterface * * @param string $name The name of the attribute. * - * @return Boolean Whether the attribute exists. + * @return Boolean Whether the attribute exists. */ public function hasAttribute($name) { @@ -299,7 +299,7 @@ class Form implements \IteratorAggregate, FormInterface * * @param string $name The name of the attribute * - * @return mixed The attribute value. + * @return mixed The attribute value. */ public function getAttribute($name) { @@ -338,20 +338,32 @@ class Form implements \IteratorAggregate, FormInterface // Validate if client data matches data class (unless empty) if (!empty($clientData)) { - // TESTME $dataClass = $this->config->getDataClass(); if (null === $dataClass && is_object($clientData)) { - // TODO clarify error message: should not be transformed to object if data class is null - // possible solutions: set data class or change client transformers - throw new UnexpectedTypeException($clientData, 'scalar or array'); + $expectedType = 'scalar'; + + if (count($this->children) > 0 && $this->config->getDataMapper()) { + $expectedType = 'array'; + } + + throw new FormException( + 'The form\'s client data is expected to of type ' . $expectedType . ', ' . + 'but is an instance of class ' . get_class($clientData) . '. You ' . + 'can avoid this error by setting the "data_class" option to ' . + '"' . get_class($clientData) . '" or by adding a client transformer ' . + 'that transforms ' . get_class($clientData) . ' to ' . $expectedType . '.' + ); } - // TESTME if (null !== $dataClass && !$clientData instanceof $dataClass) { - // TODO clarify error message: should be transformed to object if data class is set - // possible solutions: change data class or client transformers - throw new UnexpectedTypeException($clientData, $dataClass); + throw new FormException( + 'The form\'s client data is expected to be an instance of class ' . + $dataClass . ', but has the type ' . gettype($clientData) . '. You ' . + 'can avoid this error by setting the "data_class" option to ' . + 'null or by adding a client transformer that transforms ' . + gettype($clientData) . ' to ' . $dataClass . '.' + ); } } @@ -582,7 +594,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns the normalized data of the form. * - * @return mixed When the form is not bound, the default data is returned. + * @return mixed When the form is not bound, the default data is returned. * When the form is bound, the normalized bound data is * returned if the form is valid, null otherwise. */ @@ -687,7 +699,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns whether or not there are errors. * - * @return Boolean true if form is bound and not valid + * @return Boolean true if form is bound and not valid */ public function hasErrors() { @@ -700,7 +712,7 @@ class Form implements \IteratorAggregate, FormInterface /** * Returns all errors. * - * @return array An array of FormError instances that occurred during binding + * @return array An array of FormError instances that occurred during binding */ public function getErrors() { @@ -858,7 +870,7 @@ class Form implements \IteratorAggregate, FormInterface * * @param string $name The offset of the value to get * - * @return FormInterface A form instance + * @return FormInterface A form instance */ public function offsetGet($name) { diff --git a/src/Symfony/Component/Form/FormBuilder.php b/src/Symfony/Component/Form/FormBuilder.php index 6dafd341e7..560b16e884 100644 --- a/src/Symfony/Component/Form/FormBuilder.php +++ b/src/Symfony/Component/Form/FormBuilder.php @@ -176,9 +176,7 @@ class FormBuilder extends FormConfig */ public function remove($name) { - if (isset($this->unresolvedChildren[$name])) { - unset($this->unresolvedChildren[$name]); - } + unset($this->unresolvedChildren[$name]); if (isset($this->children[$name])) { if ($this->children[$name] instanceof self) { diff --git a/src/Symfony/Component/Form/FormConfig.php b/src/Symfony/Component/Form/FormConfig.php index ac50e00ebd..d979f94949 100644 --- a/src/Symfony/Component/Form/FormConfig.php +++ b/src/Symfony/Component/Form/FormConfig.php @@ -24,7 +24,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; class FormConfig implements FormConfigInterface { /** - * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + * @var EventDispatcherInterface */ private $dispatcher; @@ -64,7 +64,7 @@ class FormConfig implements FormConfigInterface private $dataMapper; /** - * @var FormValidatorInterface + * @var array */ private $validators = array(); @@ -374,7 +374,7 @@ class FormConfig implements FormConfigInterface /** * {@inheritdoc} */ - function hasAttribute($name) + public function hasAttribute($name) { return isset($this->attributes[$name]); } @@ -382,7 +382,7 @@ class FormConfig implements FormConfigInterface /** * {@inheritdoc} */ - function getAttribute($name) + public function getAttribute($name) { return isset($this->attributes[$name]) ? $this->attributes[$name] : null; } diff --git a/src/Symfony/Component/Form/FormConfigInterface.php b/src/Symfony/Component/Form/FormConfigInterface.php index 36345a2863..11c8f3f852 100644 --- a/src/Symfony/Component/Form/FormConfigInterface.php +++ b/src/Symfony/Component/Form/FormConfigInterface.php @@ -108,7 +108,7 @@ interface FormConfigInterface /** * Returns the data that should be returned when the form is empty. * - * @return mixed|\Closure The data returned if the form is empty. + * @return mixed The data returned if the form is empty. */ function getEmptyData(); @@ -124,7 +124,7 @@ interface FormConfigInterface * * @param string $name The attribute name. * - * @return Boolean Whether the attribute exists. + * @return Boolean Whether the attribute exists. */ function hasAttribute($name); @@ -133,7 +133,7 @@ interface FormConfigInterface * * @param string $name The attribute name. * - * @return mixed The attribute value. + * @return mixed The attribute value. */ function getAttribute($name); diff --git a/src/Symfony/Component/Form/FormInterface.php b/src/Symfony/Component/Form/FormInterface.php index 42e2a472a3..66f119bf62 100644 --- a/src/Symfony/Component/Form/FormInterface.php +++ b/src/Symfony/Component/Form/FormInterface.php @@ -21,7 +21,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Sets the parent form. * - * @param FormInterface $parent The parent form + * @param FormInterface $parent The parent form + * + * @return FormInterface The form instance */ function setParent(FormInterface $parent = null); @@ -42,7 +44,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Adds a child to the form. * - * @param FormInterface $child The FormInterface to add as a child + * @param FormInterface $child The FormInterface to add as a child + * + * @return FormInterface The form instance */ function add(FormInterface $child); @@ -67,7 +71,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Removes a child from the form. * - * @param string $name The name of the child to remove + * @param string $name The name of the child to remove + * + * @return FormInterface The form instance */ function remove($name); @@ -95,9 +101,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Updates the field with default data. * - * @param array $appData The data formatted as expected for the underlying object + * @param array $appData The data formatted as expected for the underlying object * - * @return Form The current form + * @return FormInterface The form instance */ function setData($appData); @@ -111,7 +117,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Returns the normalized data of the field. * - * @return mixed When the field is not bound, the default data is returned. + * @return mixed When the field is not bound, the default data is returned. * When the field is bound, the normalized bound data is * returned if the field is valid, null otherwise. */ @@ -148,7 +154,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Returns the name by which the form is identified in forms. * - * @return string The name of the form. + * @return string The name of the form. */ function getName(); @@ -162,7 +168,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Adds an error to this form. * - * @param FormError $error + * @param FormError $error + * + * @return FormInterface The form instance */ function addError(FormError $error); @@ -214,7 +222,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Writes data into the form. * - * @param mixed $data The data + * @param mixed $data The data + * + * @return FormInterface The form instance */ function bind($data); @@ -235,7 +245,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable /** * Returns the root of the form tree. * - * @return FormInterface The root of the tree + * @return FormInterface The root of the tree */ function getRoot(); diff --git a/src/Symfony/Component/Form/FormTypeGuesserChain.php b/src/Symfony/Component/Form/FormTypeGuesserChain.php index d1c27018dd..608709de87 100644 --- a/src/Symfony/Component/Form/FormTypeGuesserChain.php +++ b/src/Symfony/Component/Form/FormTypeGuesserChain.php @@ -97,7 +97,7 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface * @param \Closure $closure The closure to execute. Accepts a guesser * as argument and should return a Guess instance * - * @return Guess The guess with the highest confidence + * @return Guess The guess with the highest confidence */ private function guess(\Closure $closure) { diff --git a/src/Symfony/Component/Form/FormTypeGuesserInterface.php b/src/Symfony/Component/Form/FormTypeGuesserInterface.php index 465c96a7fc..d38d4dc5fc 100644 --- a/src/Symfony/Component/Form/FormTypeGuesserInterface.php +++ b/src/Symfony/Component/Form/FormTypeGuesserInterface.php @@ -29,7 +29,7 @@ interface FormTypeGuesserInterface * @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 required setting + * @return Guess A guess for the field's required setting */ function guessRequired($class, $property); @@ -39,7 +39,7 @@ interface FormTypeGuesserInterface * @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 maximum length + * @return Guess A guess for the field's maximum length */ function guessMaxLength($class, $property); @@ -49,7 +49,7 @@ interface FormTypeGuesserInterface * @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 minimum length * * @deprecated Deprecated since version 2.1, to be removed in 2.3. */ @@ -67,7 +67,7 @@ interface FormTypeGuesserInterface * @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 required pattern + * @return Guess A guess for the field's required pattern */ function guessPattern($class, $property); } diff --git a/src/Symfony/Component/Form/Guess/Guess.php b/src/Symfony/Component/Form/Guess/Guess.php index 8d4c278af9..77f6ebd442 100644 --- a/src/Symfony/Component/Form/Guess/Guess.php +++ b/src/Symfony/Component/Form/Guess/Guess.php @@ -75,7 +75,7 @@ abstract class Guess * * @param array $guesses A list of guesses * - * @return Guess The guess with the highest confidence + * @return Guess The guess with the highest confidence */ static public function getBestGuess(array $guesses) { @@ -103,8 +103,8 @@ abstract class Guess /** * Returns the confidence that the guessed value is correct * - * @return integer One of the constants VERY_HIGH_CONFIDENCE, - * HIGH_CONFIDENCE, MEDIUM_CONFIDENCE and LOW_CONFIDENCE + * @return integer One of the constants VERY_HIGH_CONFIDENCE, + * HIGH_CONFIDENCE, MEDIUM_CONFIDENCE and LOW_CONFIDENCE */ public function getConfidence() { diff --git a/src/Symfony/Component/Form/Tests/FormConfigTest.php b/src/Symfony/Component/Form/Tests/FormConfigTest.php index 4e6c2cf271..5896dc5509 100644 --- a/src/Symfony/Component/Form/Tests/FormConfigTest.php +++ b/src/Symfony/Component/Form/Tests/FormConfigTest.php @@ -59,7 +59,7 @@ class FormConfigTest extends \PHPUnit_Framework_TestCase /** * @dataProvider getHtml4Ids */ - public function testSetNameAcceptsOnlyNamesValidAsIdsInHtml4($name, $accepted) + public function testNameAcceptsOnlyNamesValidAsIdsInHtml4($name, $accepted) { $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); diff --git a/src/Symfony/Component/Form/Tests/FormTest.php b/src/Symfony/Component/Form/Tests/FormTest.php index f8e820d4af..a15c9d6a40 100644 --- a/src/Symfony/Component/Form/Tests/FormTest.php +++ b/src/Symfony/Component/Form/Tests/FormTest.php @@ -1234,6 +1234,36 @@ class FormTest extends \PHPUnit_Framework_TestCase $this->assertEquals(new PropertyPath('[name]'), $form->getPropertyPath()); } + /** + * @expectedException Symfony\Component\Form\Exception\FormException + */ + public function testClientDataMustNotBeObjectIfDataClassIsNull() + { + $config = new FormConfig('name', null, $this->dispatcher); + $config->appendClientTransformer(new FixedDataTransformer(array( + '' => '', + 'foo' => new \stdClass(), + ))); + $form = new Form($config); + + $form->setData('foo'); + } + + /** + * @expectedException Symfony\Component\Form\Exception\FormException + */ + public function testClientDataMustBeObjectIfDataClassIsSet() + { + $config = new FormConfig('name', 'stdClass', $this->dispatcher); + $config->appendClientTransformer(new FixedDataTransformer(array( + '' => '', + 'foo' => array('bar' => 'baz'), + ))); + $form = new Form($config); + + $form->setData('foo'); + } + protected function getBuilder($name = 'name', EventDispatcherInterface $dispatcher = null, $dataClass = null) { return new FormBuilder($name, $dataClass, $dispatcher ?: $this->dispatcher, $this->factory); diff --git a/src/Symfony/Component/Form/Tests/Util/PropertyPathBuilderTest.php b/src/Symfony/Component/Form/Tests/Util/PropertyPathBuilderTest.php index 4d50284943..dda7c7821d 100644 --- a/src/Symfony/Component/Form/Tests/Util/PropertyPathBuilderTest.php +++ b/src/Symfony/Component/Form/Tests/Util/PropertyPathBuilderTest.php @@ -93,40 +93,22 @@ class PropertyPathBuilderTest extends \PHPUnit_Framework_TestCase public function testReplaceByIndex() { - $this->builder->replaceByIndex(1, 1, 'new1'); + $this->builder->replaceByIndex(1, 'new1'); $path = new PropertyPath('old1[new1].old3[old4][old5].old6'); $this->assertEquals($path, $this->builder->getPropertyPath()); } - public function testReplaceByIndexWithLength() - { - $this->builder->replaceByIndex(0, 2, 'new1'); - - $path = new PropertyPath('[new1].old3[old4][old5].old6'); - - $this->assertEquals($path, $this->builder->getPropertyPath()); - } - public function testReplaceByProperty() { - $this->builder->replaceByProperty(1, 1, 'new1'); + $this->builder->replaceByProperty(1, 'new1'); $path = new PropertyPath('old1.new1.old3[old4][old5].old6'); $this->assertEquals($path, $this->builder->getPropertyPath()); } - public function testReplaceByPropertyWithLength() - { - $this->builder->replaceByProperty(0, 2, 'new1'); - - $path = new PropertyPath('new1.old3[old4][old5].old6'); - - $this->assertEquals($path, $this->builder->getPropertyPath()); - } - public function testReplace() { $this->builder->replace(1, 1, new PropertyPath('new1[new2].new3')); diff --git a/src/Symfony/Component/Form/Tests/Util/PropertyPathTest.php b/src/Symfony/Component/Form/Tests/Util/PropertyPathTest.php index cba5a4bd54..a9779bc429 100644 --- a/src/Symfony/Component/Form/Tests/Util/PropertyPathTest.php +++ b/src/Symfony/Component/Form/Tests/Util/PropertyPathTest.php @@ -464,6 +464,11 @@ class PropertyPathTest extends \PHPUnit_Framework_TestCase new PropertyPath(false); } + public function testValidPropertyPath_zero() + { + new PropertyPath('0'); + } + public function testGetParent_dot() { $propertyPath = new PropertyPath('grandpa.parent.child'); diff --git a/src/Symfony/Component/Form/ImmutableFormConfig.php b/src/Symfony/Component/Form/UnmodifiableFormConfig.php similarity index 89% rename from src/Symfony/Component/Form/ImmutableFormConfig.php rename to src/Symfony/Component/Form/UnmodifiableFormConfig.php index fbf739d3cb..02519fab47 100644 --- a/src/Symfony/Component/Form/ImmutableFormConfig.php +++ b/src/Symfony/Component/Form/UnmodifiableFormConfig.php @@ -13,13 +13,14 @@ namespace Symfony\Component\Form; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Util\PropertyPath; +use Symfony\Component\EventDispatcher\UnmodifiableEventDispatcher; /** - * An immutable form configuration. + * A read-only form configuration. * * @author Bernhard Schussek */ -class ImmutableFormConfig implements FormConfigInterface +class UnmodifiableFormConfig implements FormConfigInterface { /** * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface @@ -102,13 +103,18 @@ class ImmutableFormConfig implements FormConfigInterface private $dataClass; /** - * Creates an immutable copy of a given configuration. + * Creates an unmodifiable copy of a given configuration. * * @param FormConfigInterface $config The configuration to copy. */ public function __construct(FormConfigInterface $config) { - $this->dispatcher = $config->getEventDispatcher(); + $dispatcher = $config->getEventDispatcher(); + if (!$dispatcher instanceof UnmodifiableEventDispatcher) { + $dispatcher = new UnmodifiableEventDispatcher($dispatcher); + } + + $this->dispatcher = $dispatcher; $this->name = $config->getName(); $this->propertyPath = $config->getPropertyPath(); $this->mapped = $config->getMapped(); @@ -243,7 +249,7 @@ class ImmutableFormConfig implements FormConfigInterface /** * {@inheritdoc} */ - function hasAttribute($name) + public function hasAttribute($name) { return isset($this->attributes[$name]); } @@ -251,7 +257,7 @@ class ImmutableFormConfig implements FormConfigInterface /** * {@inheritdoc} */ - function getAttribute($name) + public function getAttribute($name) { return isset($this->attributes[$name]) ? $this->attributes[$name] : null; } diff --git a/src/Symfony/Component/Form/Util/PropertyPath.php b/src/Symfony/Component/Form/Util/PropertyPath.php index 47aa9093c2..3443036fe2 100644 --- a/src/Symfony/Component/Form/Util/PropertyPath.php +++ b/src/Symfony/Component/Form/Util/PropertyPath.php @@ -60,7 +60,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface * String representation of the path * @var string */ - private $string; + private $pathAsString; /** * Positions where the individual elements start in the string representation @@ -85,20 +85,20 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface $this->singulars = $propertyPath->singulars; $this->length = $propertyPath->length; $this->isIndex = $propertyPath->isIndex; - $this->string = $propertyPath->string; + $this->pathAsString = $propertyPath->pathAsString; $this->positions = $propertyPath->positions; return; } if (!is_string($propertyPath)) { - throw new UnexpectedTypeException($propertyPath, 'string'); + throw new UnexpectedTypeException($propertyPath, 'string or Symfony\Component\Form\Util\PropertyPath'); } - if (empty($propertyPath)) { + if ('' === $propertyPath) { throw new InvalidPropertyPathException('The property path should not be empty.'); } - $this->string = (string) $propertyPath; + $this->pathAsString = $propertyPath; $position = 0; $remaining = $propertyPath; @@ -149,7 +149,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface */ public function __toString() { - return $this->string; + return $this->pathAsString; } /** @@ -180,7 +180,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface $parent = clone $this; --$parent->length; - $parent->string = substr($parent->string, 0, $parent->positions[$parent->length]); + $parent->pathAsString = substr($parent->pathAsString, 0, $parent->positions[$parent->length]); array_pop($parent->elements); array_pop($parent->singulars); array_pop($parent->isIndex); @@ -253,7 +253,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface * * @param object|array $objectOrArray The object or array to traverse * - * @return mixed The value at the end of the property path + * @return mixed The value at the end of the property path * * @throws InvalidPropertyException If the property/getter does not exist * @throws PropertyAccessDeniedException If the property/getter exists but is not public @@ -345,7 +345,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface * @param string $property The property to read. * @param integer $isIndex Whether to interpret the property as index. * - * @return mixed The value of the read property + * @return mixed The value of the read property * * @throws InvalidPropertyException If the property does not exist. * @throws PropertyAccessDeniedException If the property cannot be accessed due to @@ -564,7 +564,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface * * @param string $string Some string. * - * @return string The camelized version of the string. + * @return string The camelized version of the string. */ protected function camelize($string) { @@ -578,7 +578,7 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface * @param string $methodName The method name. * @param integer $parameters The number of parameters. * - * @return Boolean Whether the method is public and has $parameters + * @return Boolean Whether the method is public and has $parameters * required parameters. */ private function isAccessible(ReflectionClass $class, $methodName, $parameters) diff --git a/src/Symfony/Component/Form/Util/PropertyPathBuilder.php b/src/Symfony/Component/Form/Util/PropertyPathBuilder.php index 7679cfb4be..d97a01126d 100644 --- a/src/Symfony/Component/Form/Util/PropertyPathBuilder.php +++ b/src/Symfony/Component/Form/Util/PropertyPathBuilder.php @@ -46,6 +46,7 @@ class PropertyPathBuilder * @param integer $offset The offset where the appended piece * starts in $path. * @param integer $length The length of the appended piece. + * If 0, the full path is appended. */ public function append(PropertyPathInterface $path, $offset = 0, $length = 0) { @@ -103,6 +104,7 @@ class PropertyPathBuilder * @param integer $pathOffset The offset where the inserted piece * starts in $path. * @param integer $pathLength The length of the inserted piece. + * If 0, the full path is inserted. */ public function replace($offset, $length, PropertyPathInterface $path, $pathOffset = 0, $pathLength = 0) { @@ -122,13 +124,10 @@ class PropertyPathBuilder * Replaces a sub-path by a single index element. * * @param integer $offset The offset at which to replace. - * @param integer $length The length of the piece to replace. * @param string $name The inserted index name. */ - public function replaceByIndex($offset, $length, $name) + public function replaceByIndex($offset, $name) { - $this->resize($offset, $length, 1); - $this->elements[$offset] = $name; $this->isIndex[$offset] = true; } @@ -137,26 +136,66 @@ class PropertyPathBuilder * Replaces a sub-path by a single property element. * * @param integer $offset The offset at which to replace. - * @param integer $length The length of the piece to replace. * @param string $name The inserted property name. */ - public function replaceByProperty($offset, $length, $name) + public function replaceByProperty($offset, $name) { - $this->resize($offset, $length, 1); - $this->elements[$offset] = $name; $this->isIndex[$offset] = false; } + /** + * Returns the length of the current path. + * + * @return integer The path length. + */ + public function getLength() + { + return count($this->elements); + } + + /** + * Returns the current property path. + * + * @return PropertyPathInterface The constructed property path. + */ + public function getPropertyPath() + { + $pathAsString = $this->__toString(); + + return '' !== $pathAsString ? new PropertyPath($pathAsString) : null; + } + + /** + * Returns the current property path as string. + * + * @return string The property path as string. + */ + public function __toString() + { + $string = ''; + + foreach ($this->elements as $offset => $element) { + if ($this->isIndex[$offset]) { + $element = '[' . $element . ']'; + } elseif ('' !== $string) { + $string .= '.'; + } + + $string .= $element; + } + + return $string; + } + /** * Resizes the path so that a chunk of length $cutLength is * removed at $offset and another chunk of length $insertionLength - * is inserted. + * can be inserted. * - * @param integer $offset The offset where a chunk should be removed. - * @param $cutLength - * @param $insertionLength - * @return mixed + * @param integer $offset The offset where the removed chunk starts. + * @param integer $cutLength The length of the removed chunk. + * @param integer $insertionLength The length of the inserted chunk. */ private function resize($offset, $cutLength, $insertionLength) { @@ -210,36 +249,4 @@ class PropertyPathBuilder } } } - - /** - * Returns the length of the current path. - * - * @return integer The path length. - */ - public function getLength() - { - return count($this->elements); - } - - /** - * Returns the current property path. - * - * @return PropertyPathInterface The constructed property path. - */ - public function getPropertyPath() - { - $string = null; - - foreach ($this->elements as $offset => $element) { - if ($this->isIndex[$offset]) { - $element = '[' . $element . ']'; - } elseif (null !== $string) { - $string .= '.'; - } - - $string .= $element; - } - - return null !== $string ? new PropertyPath($string) : null; - } } diff --git a/src/Symfony/Component/Form/Util/PropertyPathInterface.php b/src/Symfony/Component/Form/Util/PropertyPathInterface.php index 68944464c1..da803e798d 100644 --- a/src/Symfony/Component/Form/Util/PropertyPathInterface.php +++ b/src/Symfony/Component/Form/Util/PropertyPathInterface.php @@ -62,7 +62,7 @@ interface PropertyPathInterface extends \Traversable * * @param integer $index The index key * - * @return string A property or index name + * @return string A property or index name */ function getElement($index); @@ -71,7 +71,7 @@ interface PropertyPathInterface extends \Traversable * * @param integer $index The index in the property path * - * @return Boolean Whether the element at this index is a property + * @return Boolean Whether the element at this index is a property */ function isProperty($index); @@ -80,7 +80,7 @@ interface PropertyPathInterface extends \Traversable * * @param integer $index The index in the property path * - * @return Boolean Whether the element at this index is an array index + * @return Boolean Whether the element at this index is an array index */ function isIndex($index); } diff --git a/src/Symfony/Component/Form/Util/PropertyPathIteratorInterface.php b/src/Symfony/Component/Form/Util/PropertyPathIteratorInterface.php index 43bc694c90..639164a213 100644 --- a/src/Symfony/Component/Form/Util/PropertyPathIteratorInterface.php +++ b/src/Symfony/Component/Form/Util/PropertyPathIteratorInterface.php @@ -26,7 +26,7 @@ interface PropertyPathIteratorInterface extends \Iterator, \SeekableIterator /** * Returns whether the current element in the property path is a property - * names. + * name. * * @return Boolean */