Merge remote branch 'vicb/form-phpdoc'

* vicb/form-phpdoc:
  [Form] Fix some phpDoc
  [Form] fix and add some phpDoc
This commit is contained in:
Fabien Potencier 2011-05-10 19:08:53 +02:00
commit f9fefd306d
28 changed files with 808 additions and 257 deletions

View File

@ -34,16 +34,35 @@ abstract class AbstractType implements FormTypeInterface
return null;
}
/**
* Returns the default options for this type.
*
* @param array $options
*
* @return array The default options
*/
public function getDefaultOptions(array $options)
{
return array();
}
/**
* Returns the name of the parent type.
*
* @param array $options
*
* @return string The name of the parent type
*/
public function getParent(array $options)
{
return 'form';
}
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
public function getName()
{
preg_match('/\\\\(\w+?)(Form)?(Type)?$/i', get_class($this), $matches);
@ -51,6 +70,13 @@ abstract class AbstractType implements FormTypeInterface
return strtolower($matches[1]);
}
/**
* Adds extensions for this type.
*
* @param array $extensions An array of FormTypeExtensionInterface
*
* @throws UnexpectedTypeException if any extension does not implement FormTypeExtensionInterface
*/
public function setExtensions(array $extensions)
{
foreach ($extensions as $extension) {
@ -62,6 +88,11 @@ abstract class AbstractType implements FormTypeInterface
$this->extensions = $extensions;
}
/**
* Returns the extensions associated with this type.
*
* @return array An array of FormTypeExtensionInterface
*/
public function getExtensions()
{
return $this->extensions;

View File

@ -1,5 +1,14 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Event;
use Symfony\Component\EventDispatcher\Event;
@ -8,20 +17,35 @@ use Symfony\Component\Form\FormInterface;
class DataEvent extends Event
{
private $form;
protected $data;
/**
* Constructs an event.
*
* @param FormInterface $form The associated form
* @param mixed $data The data
*/
public function __construct(FormInterface $form, $data)
{
$this->form = $form;
$this->data = $data;
}
/**
* Returns the form at the source of the event.
*
* @return FormInterafce
*/
public function getForm()
{
return $this->form;
}
/**
* Returns the data associated with this event.
*
* @return type
*/
public function getData()
{
return $this->data;

View File

@ -1,9 +1,23 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\Event;
class FilterDataEvent extends DataEvent
{
/**
* Allows updating with some filtered data
*
* @param mixed $data
*/
public function setData($data)
{
$this->data = $data;

View File

@ -19,6 +19,13 @@ class ArrayChoiceList implements ChoiceListInterface
protected $loaded = false;
/**
* Constructor.
*
* @param array|\Closure $choices An array of choices or a function returning an array
*
* @throws UnexpectedTypeException if the type of the choices parameter is not supported
*/
public function __construct($choices)
{
if (!is_array($choices) && !$choices instanceof \Closure) {
@ -28,6 +35,11 @@ class ArrayChoiceList implements ChoiceListInterface
$this->choices = $choices;
}
/**
* Returns a list of choices
*
* @return array
*/
public function getChoices()
{
if (!$this->loaded) {
@ -38,7 +50,9 @@ class ArrayChoiceList implements ChoiceListInterface
}
/**
* @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface::getChoices
* Initializes the list of choices.
*
* @throws UnexpectedTypeException if the function does not return an array
*/
protected function load()
{

View File

@ -13,5 +13,10 @@ namespace Symfony\Component\Form\Extension\Core\ChoiceList;
interface ChoiceListInterface
{
/**
* Returns a list of choices
*
* @return array
*/
function getChoices();
}

View File

@ -16,7 +16,7 @@ class MonthChoiceList extends PaddedChoiceList
private $formatter;
/**
* Generates an array of localized month choices
* Generates an array of localized month choices.
*
* @param IntlDateFormatter $formatter An IntlDateFormatter instance
* @param array $months The month numbers to generate
@ -28,6 +28,11 @@ class MonthChoiceList extends PaddedChoiceList
$this->formatter = $formatter;
}
/**
* Initializes the list of months.
*
* @throws UnexpectedTypeException if the function does not return an array
*/
protected function load()
{
parent::load();

View File

@ -25,10 +25,12 @@ class PaddedChoiceList extends ArrayChoiceList
* If the values are shorter than $padLength characters, they are padded with
* zeros on the left side.
*
* @param array $values The available choices
* @param array|\Closure $values The available choices
* @param integer $padLength The length to pad the choices
* @param string $padString The padding character
* @param integer $padType The direction of padding
*
* @throws UnexpectedTypeException if the type of the values parameter is not supported
*/
public function __construct($values, $padLength, $padString, $padType = STR_PAD_LEFT)
{
@ -39,6 +41,13 @@ class PaddedChoiceList extends ArrayChoiceList
$this->padType = $padType;
}
/**
* Initializes the list of choices.
*
* Each choices is padded according to the format given in the constructor
*
* @throws UnexpectedTypeException if the function does not return an array
*/
protected function load()
{
parent::load();

View File

@ -17,6 +17,13 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
class ArrayToChoicesTransformer implements DataTransformerInterface
{
/**
* @param array $array
*
* @return array
*
* @throws UnexpectedTypeException if the given value is not an array
*/
public function transform($array)
{
if (null === $array) {
@ -30,6 +37,13 @@ class ArrayToChoicesTransformer implements DataTransformerInterface
return FormUtil::toArrayKeys($array);
}
/**
* @param array $array
*
* @return array
*
* @throws UnexpectedTypeException if the given value is not an array
*/
public function reverseTransform($array)
{
if (null === $array) {

View File

@ -77,8 +77,9 @@ class ArrayToPartsTransformer implements DataTransformerInterface
return null;
}
throw new TransformationFailedException(sprintf(
'The keys "%s" should not be empty', implode('", "', $emptyKeys)));
throw new TransformationFailedException(
sprintf('The keys "%s" should not be empty', implode('", "', $emptyKeys)
));
}
return $result;

View File

@ -27,6 +27,12 @@ abstract class BaseDateTimeTransformer implements DataTransformerInterface
protected $outputTimezone;
/**
* Constructor.
*
* @param string $inputTimezone The name of the input timezone
* @param string $outputTimezone The name of the output timezone
*/
public function __construct($inputTimezone = null, $outputTimezone = null)
{
$this->inputTimezone = $inputTimezone ?: date_default_timezone_get();

View File

@ -26,7 +26,10 @@ class BooleanToStringTransformer implements DataTransformerInterface
* Transforms a Boolean into a string.
*
* @param Boolean $value Boolean value.
*
* @return string String value.
*
* @throws UnexpectedTypeException if the given value is not a Boolean
*/
public function transform($value)
{
@ -45,7 +48,10 @@ class BooleanToStringTransformer implements DataTransformerInterface
* Transforms a string into a Boolean.
*
* @param string $value String value.
*
* @return Boolean Boolean value.
*
* @throws UnexpectedTypeException if the given value is not a string
*/
public function reverseTransform($value)
{

View File

@ -17,12 +17,6 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
/**
* Transforms between a normalized time and a localized time string/array.
*
* Options:
*
* * "input": The type of the normalized format ("time" or "timestamp"). Default: "datetime"
* * "output": The type of the transformed format ("string" or "array"). Default: "string"
* * "format": The format of the time string ("short", "medium", "long" or "full"). Default: "short"
*
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
* @author Florian Eckerstorfer <florian@eckerstorfer.org>
*/
@ -32,7 +26,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
private $fields;
public function __construct($inputTimezone = null, $outputTimezone = null, $fields = null, $pad = false)
/**
* Constructor.
*
* @param string $inputTimezone The input timezone
* @param string $outputTimezone The output timezone
* @param array $fields The date fields
* @param Boolean $pad Wether to use padding
*
* @throws UnexpectedTypeException if a timezone is not a string
*/
public function __construct($inputTimezone = null, $outputTimezone = null, array $fields = null, $pad = false)
{
parent::__construct($inputTimezone, $outputTimezone);
@ -41,14 +45,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
}
$this->fields = $fields;
$this->pad =$pad;
$this->pad = (Boolean) $pad;
}
/**
* Transforms a normalized date into a localized date string/array.
* Transforms a normalized date into a localized date.
*
* @param DateTime $dateTime Normalized date.
* @return string|array Localized date array.
*
* @return array Localized date.
*
* @throws UnexpectedTypeException if the given value is not an instance of \DateTime
*/
public function transform($dateTime)
{
@ -67,11 +74,8 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($dateTime, '\DateTime');
}
$inputTimezone = $this->inputTimezone;
$outputTimezone = $this->outputTimezone;
if ($inputTimezone != $outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($outputTimezone));
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
}
$result = array_intersect_key(array(
@ -86,7 +90,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
if (!$this->pad) {
foreach ($result as &$entry) {
// remove leading zeros
$entry = (string)(int)$entry;
$entry = (string) (int) $entry;
}
}
@ -94,10 +98,14 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
}
/**
* Transforms a localized date string/array into a normalized date.
* Transforms a localized date into a normalized date.
*
* @param array $value Localized date
*
* @param array $value Localized date string/array
* @return DateTime Normalized date
*
* @throws UnexpectedTypeException if the given value is not an array
* @throws TransformationFailedException if the value could not bet transformed
*/
public function reverseTransform($value)
{
@ -105,9 +113,6 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
return null;
}
$inputTimezone = $this->inputTimezone;
$outputTimezone = $this->outputTimezone;
if (!is_array($value)) {
throw new UnexpectedTypeException($value, 'array');
}
@ -125,8 +130,9 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
}
if (count($emptyFields) > 0) {
throw new TransformationFailedException(sprintf(
'The fields "%s" should not be empty', implode('", "', $emptyFields)));
throw new TransformationFailedException(
sprintf('The fields "%s" should not be empty', implode('", "', $emptyFields)
));
}
try {
@ -138,14 +144,14 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
empty($value['hour']) ? '0' : $value['hour'],
empty($value['minute']) ? '0' : $value['minute'],
empty($value['second']) ? '0' : $value['second'],
$outputTimezone
$this->outputTimezone
));
} catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), null, $e);
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
}
if ($inputTimezone != $outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone));
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
}
return $dateTime;

View File

@ -17,12 +17,6 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
/**
* Transforms between a normalized time and a localized time string
*
* Options:
*
* * "input": The type of the normalized format ("time" or "timestamp"). Default: "datetime"
* * "output": The type of the transformed format ("string" or "array"). Default: "string"
* * "format": The format of the time string ("short", "medium", "long" or "full"). Default: "short"
*
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
* @author Florian Eckerstorfer <florian@eckerstorfer.org>
*/
@ -32,6 +26,19 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
private $timeFormat;
/**
* Constructor.
*
* @see BaseDateTimeTransformer::formats for available format options
*
* @param string $inputTimezone The name of the input timezone
* @param string $outputTimezone The name of the output timezone
* @param integer $dateFormat The date format
* @param integer $timeFormat The time format
*
* @throws UnexpectedTypeException If a format is not supported
* @throws UnexpectedTypeException if a timezone is not a string
*/
public function __construct($inputTimezone = null, $outputTimezone = null, $dateFormat = null, $timeFormat = null)
{
parent::__construct($inputTimezone, $outputTimezone);
@ -60,7 +67,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
* Transforms a normalized date into a localized date string/array.
*
* @param DateTime $dateTime Normalized date.
*
* @return string|array Localized date string/array.
*
* @throws UnexpectedTypeException if the given value is not an instance of \DateTime
* @throws TransformationFailedException if the date could not be transformed
*/
public function transform($dateTime)
{
@ -72,14 +83,12 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($dateTime, '\DateTime');
}
$inputTimezone = $this->inputTimezone;
// convert time to UTC before passing it to the formatter
if ('UTC' != $inputTimezone) {
if ('UTC' !== $this->inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone('UTC'));
}
$value = $this->getIntlDateFormatter()->format((int)$dateTime->format('U'));
$value = $this->getIntlDateFormatter()->format((int) $dateTime->format('U'));
if (intl_get_error_code() != 0) {
throw new TransformationFailedException(intl_get_error_message());
@ -92,12 +101,14 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
* Transforms a localized date string/array into a normalized date.
*
* @param string|array $value Localized date string/array
*
* @return DateTime Normalized date
*
* @throws UnexpectedTypeException if the given value is not a string
* @throws TransformationFailedException if the date could not be parsed
*/
public function reverseTransform($value)
{
$inputTimezone = $this->inputTimezone;
if (!is_string($value)) {
throw new UnexpectedTypeException($value, 'string');
}
@ -115,8 +126,8 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
// read timestamp into DateTime object - the formatter delivers in UTC
$dateTime = new \DateTime(sprintf('@%s UTC', $timestamp));
if ('UTC' != $inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone));
if ('UTC' !== $this->inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
}
return $dateTime;
@ -129,10 +140,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
*/
protected function getIntlDateFormatter()
{
$dateFormat = $this->dateFormat;
$timeFormat = $this->timeFormat;
$timezone = $this->outputTimezone;
return new \IntlDateFormatter(\Locale::getDefault(), $dateFormat, $timeFormat, $timezone);
return new \IntlDateFormatter(
\Locale::getDefault(),
$this->dateFormat,
$this->timeFormat,
$this->outputTimezone
);
}
}

View File

@ -24,6 +24,17 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
{
private $format;
/**
* Transforms a \DateTime instance to a string
*
* @see \DateTime::format() for supported formats
*
* @param string $inputTimezone The name of the input timezone
* @param string $outputTimezone The name of the output timezone
* @param string $format The date format
*
* @throws UnexpectedTypeException if a timezone is not a string
*/
public function __construct($inputTimezone = null, $outputTimezone = null, $format = 'Y-m-d H:i:s')
{
parent::__construct($inputTimezone, $outputTimezone);
@ -36,7 +47,10 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
* and timezone
*
* @param DateTime $value A DateTime object
*
* @return string A value as produced by PHP's date() function
*
* @throws UnexpectedTypeException if the given value is not a \DateTime instance
*/
public function transform($value)
{
@ -54,10 +68,14 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
}
/**
* Transforms a date string in the configured timezone into a DateTime object
* Transforms a date string in the configured timezone into a DateTime object.
*
* @param string $value A value as produced by PHP's date() function
* @return DateTime A DateTime object
*
* @return \DateTime An instance of \DateTime
*
* @throws UnexpectedTypeException if the given value is not a string
* @throws TransformationFailedException if the date could not be parsed
*/
public function reverseTransform($value)
{
@ -69,19 +87,16 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($value, 'string');
}
$outputTimezone = $this->outputTimezone;
$inputTimezone = $this->inputTimezone;
try {
$dateTime = new \DateTime("$value $outputTimezone");
$dateTime = new \DateTime(sprintf("%s %s", $value, $this->outputTimezone));
if ($inputTimezone != $outputTimezone) {
$dateTime->setTimeZone(new \DateTimeZone($inputTimezone));
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimeZone(new \DateTimeZone($this->inputTimezone));
}
return $dateTime;
} catch (\Exception $e) {
throw new TransformationFailedException('Expected a valid date string. ' . $e->getMessage(), 0, $e);
throw new TransformationFailedException('Invalid date format.', $e->getCode(), $e);
}
}
}

View File

@ -23,10 +23,13 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
{
/**
* Transforms a DateTime object into a timestamp in the configured timezone
* Transforms a DateTime object into a timestamp in the configured timezone.
*
* @param DateTime $value A DateTime object
*
* @return integer A timestamp
*
* @throws UnexpectedTypeException if the given value is not an instance of \DateTime
*/
public function transform($value)
{
@ -40,14 +43,18 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
$value->setTimezone(new \DateTimeZone($this->outputTimezone));
return (int)$value->format('U');
return (int) $value->format('U');
}
/**
* Transforms a timestamp in the configured timezone into a DateTime object
*
* @param string $value A value as produced by PHP's date() function
* @return DateTime A DateTime object
* @param string $value A timestamp
*
* @return \DateTime An instance of \DateTime
*
* @throws UnexpectedTypeException if the given value is not a timestamp
* @throws TransformationFailedException if the given timestamp is invalid
*/
public function reverseTransform($value)
{
@ -59,19 +66,16 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($value, 'numeric');
}
$outputTimezone = $this->outputTimezone;
$inputTimezone = $this->inputTimezone;
try {
$dateTime = new \DateTime("@$value $outputTimezone");
$dateTime = new \DateTime(sprintf("@%s %s", $value, $this->outputTimezone));
if ($inputTimezone != $outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone));
if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
}
return $dateTime;
} catch (\Exception $e) {
throw new TransformationFailedException('Expected a valid timestamp. ' . $e->getMessage(), 0, $e);
throw new TransformationFailedException('Invalid timestamp format.', $e->getCode(), $e);
}
}
}

View File

@ -21,23 +21,38 @@ use Symfony\Component\HttpFoundation\File\File;
*/
class FileToArrayTransformer implements DataTransformerInterface
{
/**
* Convert a File instance to a file representation
*
* @param File $file The file
*
* @return array The file representation
*
* @throws UnexpectedTypeException if the file is not an instance of File
*/
public function transform($file)
{
if (null === $file || '' === $file) {
return array(
'file' => '',
);
return array('file' => '');
}
if (!$file instanceof File) {
throw new UnexpectedTypeException($file, 'Symfony\Component\HttpFoundation\File\File');
}
return array(
'file' => $file,
);
return array('file' => $file);
}
/**
* Transfom a file internal representation to a File instance
*
* @param File $array the file representation
*
* @return File The file
*
* @throws UnexpectedTypeException if the file representation is not an array
* @throws TransformationFailedException if the file representation is invalid
*/
public function reverseTransform($array)
{
if (null === $array || '' === $array || array() === $array) {

View File

@ -24,6 +24,6 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo
*/
public function reverseTransform($value)
{
return (int)parent::reverseTransform($value);
return (int) parent::reverseTransform($value);
}
}

View File

@ -47,7 +47,11 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransform
* Transforms a normalized format into a localized money string.
*
* @param number $value Normalized number
*
* @return string Localized money string.
*
* @throws UnexpectedTypeException if the given value is not numeric
* @throws TransformationFailedException if the value can not be transformed
*/
public function transform($value)
{
@ -66,7 +70,11 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransform
* Transforms a localized money string into a normalized format.
*
* @param string $value Localized money string
*
* @return number Normalized number
*
* @throws UnexpectedTypeException if the given value is not a string
* @throws TransformationFailedException if the value can not be transformed
*/
public function reverseTransform($value)
{

View File

@ -56,8 +56,12 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
/**
* Transforms a number type into localized number.
*
* @param number $value Number value.
* @param integer|float $value Number value.
*
* @return string Localized value.
*
* @throws UnexpectedTypeException if the given value is not numeric
* @throws TransformationFailedException if the value can not be transformed
*/
public function transform($value)
{
@ -82,7 +86,12 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
/**
* Transforms a localized number into an integer or float
*
* @param string $value
* @param string $value The localized value
*
* @return integer|float The numeric value
*
* @throws UnexpectedTypeException if the given value is not a string
* @throws TransformationFailedException if the value can not be transformed
*/
public function reverseTransform($value)
{

View File

@ -35,6 +35,14 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
private $precision;
/**
* Constructor.
*
* @see self::$types for a list of supported types
*
* @param integer $precision The precision
* @param string $type One of the supported types
*/
public function __construct($precision = null, $type = null)
{
if (is_null($precision)) {
@ -46,7 +54,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
}
if (!in_array($type, self::$types, true)) {
throw new \InvalidArgumentException(sprintf('The option "type" is expected to be one of "%s"', implode('", "', self::$types)));
throw new UnexpectedTypeException($type, implode('", "', self::$types));
}
$this->type = $type;
@ -56,8 +64,12 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
/**
* Transforms between a normalized format (integer or float) into a percentage value.
*
* @param number $value Normalized value.
* @return number Percentage value.
* @param number $value Normalized value
*
* @return number Percentage value
*
* @throws UnexpectedTypeException if the given value is not numeric
* @throws TransformationFailedException if the value could not be transformed
*/
public function transform($value)
{
@ -88,7 +100,11 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
* Transforms between a percentage value into a normalized format (integer or float).
*
* @param number $value Percentage value.
*
* @return number Normalized value.
*
* @throws UnexpectedTypeException if the given value is not a string
* @throws TransformationFailedException if the value could not be transformed
*/
public function reverseTransform($value)
{

View File

@ -27,6 +27,13 @@ class ValueToDuplicatesTransformer implements DataTransformerInterface
$this->keys = $keys;
}
/**
* Duplicates the given value through the array.
*
* @param mixed $value The value
*
* @return array The array
*/
public function transform($value)
{
$result = array();
@ -38,9 +45,19 @@ class ValueToDuplicatesTransformer implements DataTransformerInterface
return $result;
}
/**
* Extracts the duplicated value from an array.
*
* @param array $array
*
* @return mixed The value
*
* @throws UnexpectedTypeException if the given value is not an array
* @throws TransformationFailedException if the given array can not be transformed
*/
public function reverseTransform($array)
{
if (!is_array($array) ) {
if (!is_array($array)) {
throw new UnexpectedTypeException($array, 'array');
}
@ -51,7 +68,8 @@ class ValueToDuplicatesTransformer implements DataTransformerInterface
if (!empty($array[$key])) {
if ($array[$key] !== $result) {
throw new TransformationFailedException(
'All values in the array should be the same');
'All values in the array should be the same'
);
}
} else {
$emptyKeys[] = $key;
@ -59,13 +77,14 @@ class ValueToDuplicatesTransformer implements DataTransformerInterface
}
if (count($emptyKeys) > 0) {
if (count($emptyKeys) === count($this->keys)) {
if (count($emptyKeys) == count($this->keys)) {
// All keys empty
return null;
}
throw new TransformationFailedException(sprintf(
'The keys "%s" should not be empty', implode('", "', $emptyKeys)));
throw new TransformationFailedException(
sprintf('The keys "%s" should not be empty', implode('", "', $emptyKeys)
));
}
return $result;

View File

@ -70,7 +70,7 @@ class Form implements \IteratorAggregate, FormInterface
private $name;
/**
* The parent fo this form
* The parent of this form
* @var FormInterface
*/
private $parent;
@ -115,7 +115,7 @@ class Form implements \IteratorAggregate, FormInterface
* The form data in application format
* @var mixed
*/
private $data;
private $appData;
/**
* The form data in normalized format
@ -136,22 +136,22 @@ class Form implements \IteratorAggregate, FormInterface
private $emptyData = '';
/**
* The names of bound values that don't belong to any children
* The bound values that don't belong to any children
* @var array
*/
private $extraData = array();
/**
* The transformer for transforming from application to normalized format
* The transformers for transforming from application to normalized format
* and back
* @var DataTransformer\DataTransformerInterface
* @var array An array of DataTransformerInterface
*/
private $normTransformers;
/**
* The transformer for transforming from normalized to client format and
* The transformers for transforming from normalized to client format and
* back
* @var DataTransformer\DataTransformerInterface
* @var array An array of DataTransformerInterface
*/
private $clientTransformers;
@ -189,7 +189,7 @@ class Form implements \IteratorAggregate, FormInterface
/**
* The FormTypeInterface instances used to create this form
* @var array
* @var array An array of FormTypeInterface
*/
private $types;
@ -218,18 +218,18 @@ class Form implements \IteratorAggregate, FormInterface
}
}
$this->name = (string)$name;
$this->types = $types;
$this->name = (string) $name;
$this->dispatcher = $dispatcher;
$this->types = $types;
$this->clientTransformers = $clientTransformers;
$this->normTransformers = $normTransformers;
$this->validators = $validators;
$this->dataMapper = $dataMapper;
$this->required = $required;
$this->readOnly = $readOnly;
$this->attributes = $attributes;
$this->errorBubbling = $errorBubbling;
$this->validators = $validators;
$this->required = (Boolean) $required;
$this->readOnly = (Boolean) $readOnly;
$this->errorBubbling = (Boolean) $errorBubbling;
$this->emptyData = $emptyData;
$this->attributes = $attributes;
$this->setData(null);
}
@ -242,24 +242,38 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* {@inheritDoc}
* Returns the name by which the form is identified in forms.
*
* @return string The name of the form.
*/
public function getName()
{
return $this->name;
}
/**
* Returns the supported types.
*
* @return array An array of FormTypeInterface
*/
public function getTypes()
{
return $this->types;
}
/**
* {@inheritDoc}
* Returns whether the form is required to be filled out.
*
* If the form has a parent and the parent is not required, this method
* will always return false. Otherwise the value set with setRequired()
* is returned.
*
* @return Boolean
*/
public function isRequired()
{
if (null === $this->parent || $this->parent->isRequired()) {
return $this->required;
}
@ -267,11 +281,20 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* {@inheritDoc}
* Returns whether this form is read only.
*
* The content of a read-only form is displayed, but not allowed to be
* modified. The validation of modified read-only forms should fail.
*
* Fields whose parents are read-only are considered read-only regardless of
* their own state.
*
* @return Boolean
*/
public function isReadOnly()
{
if (null === $this->parent || !$this->parent->isReadOnly()) {
return $this->readOnly;
}
@ -279,7 +302,11 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* {@inheritDoc}
* Sets the parent form.
*
* @param FormInterface $parent The parent form
*
* @return Form The current form
*/
public function setParent(FormInterface $parent = null)
{
@ -299,7 +326,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns whether the field has a parent.
* Returns whether the form has a parent.
*
* @return Boolean
*/
@ -309,7 +336,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns the root of the form tree
* Returns the root of the form tree.
*
* @return FormInterface The root of the tree
*/
@ -319,7 +346,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns whether the field is the root of the form tree
* Returns whether the field is the root of the form tree.
*
* @return Boolean
*/
@ -328,20 +355,32 @@ class Form implements \IteratorAggregate, FormInterface
return !$this->hasParent();
}
/**
* Returns whether the form has an attribute with the given name.
*
* @param string $name The name of the attribute
*/
public function hasAttribute($name)
{
return isset($this->attributes[$name]);
}
/**
* Returns the value of the attributes with the given name.
*
* @param string $name The name of the attribute
*/
public function getAttribute($name)
{
return $this->attributes[$name];
}
/**
* Updates the field with default data
* Updates the field with default data.
*
* @see FormInterface
* @param array $appData The data formatted as expected for the underlying object
*
* @return Form The current form
*/
public function setData($appData)
{
@ -355,14 +394,14 @@ class Form implements \IteratorAggregate, FormInterface
// Treat data as strings unless a value transformer exists
if (!$this->clientTransformers && !$this->normTransformers && is_scalar($appData)) {
$appData = (string)$appData;
$appData = (string) $appData;
}
// Synchronize representations - must not change the content!
$normData = $this->appToNorm($appData);
$clientData = $this->normToClient($normData);
$this->data = $appData;
$this->appData = $appData;
$this->normData = $normData;
$this->clientData = $clientData;
$this->synchronized = true;
@ -379,9 +418,43 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Binds POST data to the field, transforms and validates it.
* Returns the data in the format needed for the underlying object.
*
* @param string|array $clientData The POST data
* @return mixed
*/
public function getData()
{
return $this->appData;
}
/**
* Returns the data transformed by the value transformer.
*
* @return string
*/
public function getClientData()
{
return $this->clientData;
}
/**
* Returns the extra data.
*
* @return array The bound data which do not belong to a child
*/
public function getExtraData()
{
return $this->extraData;
}
/**
* Binds data to the field, transforms and validates it.
*
* @param string|array $clientData The data
*
* @return Form The current form
*
* @throws UnexpectedTypeException
*/
public function bind($clientData)
{
@ -390,7 +463,7 @@ class Form implements \IteratorAggregate, FormInterface
}
if (is_scalar($clientData) || null === $clientData) {
$clientData = (string)$clientData;
$clientData = (string) $clientData;
}
// Initialize errors in the very beginning so that we don't lose any
@ -444,7 +517,7 @@ class Form implements \IteratorAggregate, FormInterface
$clientData = $this->emptyData;
if ($clientData instanceof \Closure) {
$clientData = $clientData->__invoke($this);
$clientData = $clientData($this);
}
}
@ -473,7 +546,7 @@ class Form implements \IteratorAggregate, FormInterface
}
$this->bound = true;
$this->data = $appData;
$this->appData = $appData;
$this->normData = $normData;
$this->clientData = $clientData;
$this->extraData = $extraData;
@ -488,15 +561,14 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Binds a request to the form
* Binds a request to the form.
*
* If the request was a POST request, the data is bound to the form,
* If the request method is POST, PUT or GET, the data is bound to the form,
* transformed and written into the form data (an object or an array).
* You can set the form data by passing it in the second parameter
* of this method or by passing it in the "data" option of the form's
* constructor.
*
* @param Request $request The request to bind to the form
*
* @throws FormException if the method of the request is not one of GET, POST or PUT
*/
public function bindRequest(Request $request)
{
@ -519,16 +591,6 @@ class Form implements \IteratorAggregate, FormInterface
$this->bind($data);
}
/**
* Returns the data in the format needed for the underlying object.
*
* @return mixed
*/
public function getData()
{
return $this->data;
}
/**
* Returns the normalized data of the field.
*
@ -541,21 +603,6 @@ class Form implements \IteratorAggregate, FormInterface
return $this->normData;
}
/**
* Returns the data transformed by the value transformer
*
* @return string
*/
public function getClientData()
{
return $this->clientData;
}
public function getExtraData()
{
return $this->extraData;
}
/**
* Adds an error to the field.
*
@ -571,7 +618,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns whether errors bubble up to the parent
* Returns whether errors bubble up to the parent.
*
* @return Boolean
*/
@ -591,7 +638,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns whether the data in the different formats is synchronized
* Returns whether the data in the different formats is synchronized.
*
* @return Boolean
*/
@ -601,17 +648,20 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* {@inheritDoc}
* Returns whether the form is empty.
*
* @return Boolean
*/
public function isEmpty()
{
foreach ($this->children as $child) {
if (!$child->isEmpty()) {
return false;
}
}
return array() === $this->data || null === $this->data || '' === $this->data;
return array() === $this->appData || null === $this->appData || '' === $this->appData;
}
/**
@ -622,11 +672,13 @@ class Form implements \IteratorAggregate, FormInterface
public function isValid()
{
if (!$this->isBound() || $this->hasErrors()) {
return false;
}
foreach ($this->children as $child) {
if (!$child->isValid()) {
return false;
}
}
@ -649,7 +701,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns all errors
* Returns all errors.
*
* @return array An array of FormError instances that occurred during binding
*/
@ -659,9 +711,9 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns the DataTransformer.
* Returns the DataTransformers.
*
* @return array
* @return array An array of DataTransformerInterface
*/
public function getNormTransformers()
{
@ -669,9 +721,9 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns the DataTransformer.
* Returns the DataTransformers.
*
* @return array
* @return array An array of DataTransformerInterface
*/
public function getClientTransformers()
{
@ -679,7 +731,7 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Returns all children in this group
* Returns all children in this group.
*
* @return array
*/
@ -688,11 +740,21 @@ class Form implements \IteratorAggregate, FormInterface
return $this->children;
}
/**
* Return whether the form has children.
*
* @return Boolean
*/
public function hasChildren()
{
return count($this->children) > 0;
}
/**
* Adds a child to the form.
*
* @param FormInterface $child The FormInterface to add as a child
*/
public function add(FormInterface $child)
{
$this->children[$child->getName()] = $child;
@ -704,6 +766,11 @@ class Form implements \IteratorAggregate, FormInterface
}
}
/**
* Removes a child from the form.
*
* @param string $name The name of the child to remove
*/
public function remove($name)
{
if (isset($this->children[$name])) {
@ -717,6 +784,7 @@ class Form implements \IteratorAggregate, FormInterface
* Returns whether a child with the given name exists.
*
* @param string $name
*
* @return Boolean
*/
public function has($name)
@ -728,11 +796,15 @@ class Form implements \IteratorAggregate, FormInterface
* Returns the child with the given name.
*
* @param string $name
*
* @return FormInterface
*
* @throws \InvalidArgumentException if the child does not exist
*/
public function get($name)
{
if (isset($this->children[$name])) {
return $this->children[$name];
}
@ -805,9 +877,10 @@ class Form implements \IteratorAggregate, FormInterface
}
/**
* Normalizes the value if a normalization transformer is set
* Normalizes the value if a normalization transformer is set.
*
* @param mixed $value The value to transform
*
* @return string
*/
private function appToNorm($value)
@ -819,6 +892,71 @@ class Form implements \IteratorAggregate, FormInterface
return $value;
}
/**
* Reverse transforms a value if a normalization transformer is set.
*
* @param string $value The value to reverse transform
*
* @return mixed
*/
private function normToApp($value)
{
for ($i = count($this->normTransformers) - 1; $i >= 0; --$i) {
$value = $this->normTransformers[$i]->reverseTransform($value);
}
return $value;
}
/**
* Transforms the value if a value transformer is set.
*
* @param mixed $value The value to transform
*
* @return string
*/
private function normToClient($value)
{
if (!$this->clientTransformers) {
// Scalar values should always be converted to strings to
// facilitate differentiation between empty ("") and zero (0).
return null === $value || is_scalar($value) ? (string) $value : $value;
}
foreach ($this->clientTransformers as $transformer) {
$value = $transformer->transform($value);
}
return $value;
}
/**
* Reverse transforms a value if a value transformer is set.
*
* @param string $value The value to reverse transform
*
* @return mixed
*/
private function clientToNorm($value)
{
if (!$this->clientTransformers) {
return '' === $value ? null : $value;
}
for ($i = count($this->clientTransformers) - 1; $i >= 0; --$i) {
$value = $this->clientTransformers[$i]->reverseTransform($value);
}
return $value;
}
/**
* Creates a view.
*
* @param FormView $parent The parent view
*
* @return FormView The view
*/
public function createView(FormView $parent = null)
{
if (null === $parent && $this->parent) {
@ -827,9 +965,7 @@ class Form implements \IteratorAggregate, FormInterface
$view = new FormView();
if (null !== $parent) {
$view->setParent($parent);
}
$types = (array) $this->types;
$childViews = array();
@ -858,59 +994,4 @@ class Form implements \IteratorAggregate, FormInterface
return $view;
}
/**
* Reverse transforms a value if a normalization transformer is set.
*
* @param string $value The value to reverse transform
* @return mixed
*/
private function normToApp($value)
{
for ($i = count($this->normTransformers) - 1; $i >= 0; --$i) {
$value = $this->normTransformers[$i]->reverseTransform($value);
}
return $value;
}
/**
* Transforms the value if a value transformer is set.
*
* @param mixed $value The value to transform
* @return string
*/
private function normToClient($value)
{
if (!$this->clientTransformers) {
// Scalar values should always be converted to strings to
// facilitate differentiation between empty ("") and zero (0).
return null === $value || is_scalar($value) ? (string)$value : $value;
}
foreach ($this->clientTransformers as $transformer) {
$value = $transformer->transform($value);
}
return $value;
}
/**
* Reverse transforms a value if a value transformer is set.
*
* @param string $value The value to reverse transform
* @return mixed
*/
private function clientToNorm($value)
{
if (!$this->clientTransformers) {
return '' === $value ? null : $value;
}
for ($i = count($this->clientTransformers) - 1; $i >= 0; --$i) {
$value = $this->clientTransformers[$i]->reverseTransform($value);
}
return $value;
}
}

View File

@ -22,6 +22,13 @@ class FormFactory implements FormFactoryInterface
private $guesser;
/**
* Constructor.
*
* @param array $extensions An array of FormExtensionInterface
*
* @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
*/
public function __construct(array $extensions)
{
foreach ($extensions as $extension) {

View File

@ -32,30 +32,108 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
*/
function getParent();
function add(FormInterface $child);
function has($name);
function remove($name);
function getChildren();
function hasChildren();
/**
* Returns whether the form has a parent.
*
* @return Boolean
*/
function hasParent();
/**
* Adds a child to the form.
*
* @param FormInterface $child The FormInterface to add as a child
*/
function add(FormInterface $child);
/**
* Returns whether a child with the given name exists.
*
* @param string $name
*
* @return Boolean
*/
function has($name);
/**
* Removes a child from the form.
*
* @param string $name The name of the child to remove
*/
function remove($name);
/**
* Returns all children in this group.
*
* @return array
*/
function getChildren();
/**
* Return whether the form has children.
*
* @return Boolean
*/
function hasChildren();
/**
* Returns all errors.
*
* @return array An array of FormError instances that occurred during binding
*/
function getErrors();
function setData($data);
/**
* Updates the field with default data.
*
* @param array $appData The data formatted as expected for the underlying object
*
* @return Form The current form
*/
function setData($appData);
/**
* Returns the data in the format needed for the underlying object.
*
* @return mixed
*/
function getData();
/**
* Returns the normalized data of the field.
*
* @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.
*/
function getNormData();
/**
* Returns the data transformed by the value transformer.
*
* @return string
*/
function getClientData();
/**
* Returns the extra data.
*
* @return array The bound data which do not belong to a child
*/
function getExtraData();
/**
* Returns whether the field is bound.
*
* @return Boolean true if the form is bound to input values, false otherwise
*/
function isBound();
/**
* Returns the supported types.
*
* @return array An array of FormTypeInterface
*/
function getTypes();
/**
@ -66,7 +144,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function getName();
/**
* Adds an error to this form
* Adds an error to this form.
*
* @param FormError $error
*/
@ -91,7 +169,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function isRequired();
/**
* Returns whether this form can be read only
* Returns whether this form can be read only.
*
* The content of a read-only form is displayed, but not allowed to be
* modified. The validation of modified read-only forms should fail.
@ -104,28 +182,60 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function isReadOnly();
/**
* Returns whether the form is empty
* Returns whether the form is empty.
*
* @return Boolean
*/
function isEmpty();
/**
* Returns whether the data in the different formats is synchronized.
*
* @return Boolean
*/
function isSynchronized();
/**
* Writes posted data into the form
* Writes data into the form.
*
* @param mixed $data The data from the POST request
* @param mixed $data The data
*/
function bind($data);
/**
* Returns whether the form has an attribute with the given name.
*
* @param string $name The name of the attribute
*/
function hasAttribute($name);
/**
* Returns the value of the attributes with the given name.
*
* @param string $name The name of the attribute
*/
function getAttribute($name);
/**
* Returns the root of the form tree.
*
* @return FormInterface The root of the tree
*/
function getRoot();
/**
* Returns whether the field is the root of the form tree.
*
* @return Boolean
*/
function isRoot();
/**
* Creates a view.
*
* @param FormView $parent The parent view
*
* @return FormView The view
*/
function createView(FormView $parent = null);
}

View File

@ -21,13 +21,44 @@ interface FormTypeInterface
function createBuilder($name, FormFactoryInterface $factory, array $options);
/**
* Returns the default options for this type.
*
* @param array $options
*
* @return array The default options
*/
function getDefaultOptions(array $options);
/**
* Returns the name of the parent type.
*
* @param array $options
*
* @return string The name of the parent type
*/
function getParent(array $options);
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
function getName();
/**
* Adds extensions for this type.
*
* @param array $extensions An array of FormTypeExtensionInterface
*
* @throws UnexpectedTypeException if any extension does not implement FormTypeExtensionInterface
*/
function setExtensions(array $extensions);
/**
* Returns the extensions associated with this type.
*
* @return array An array of FormTypeExtensionInterface
*/
function getExtensions();
}

View File

@ -56,6 +56,7 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
/**
* @param $name
* @param $default
*
* @return mixed
*/
public function get($name, $default = null)
@ -85,71 +86,144 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
return $this->all();
}
/**
* Sets the value for an attribute.
*
* @param string $name The name of the attribute
* @param string $value The value
*/
public function setAttribute($name, $value)
{
$this->vars['attr'][$name] = $value;
}
/**
* Returns whether the attached form is rendered.
*
* @return Boolean Whether the form is rendered
*/
public function isRendered()
{
return $this->rendered;
}
/**
* Marks the attached form as rendered
*/
public function setRendered()
{
$this->rendered = true;
}
public function setParent(self $parent)
/**
* Sets the parent view.
*
* @param FormView $parent The parent view
*/
public function setParent(self $parent = null)
{
$this->parent = $parent;
}
/**
* Returns the parent view.
*
* @return FormView The parent view
*/
public function getParent()
{
return $this->parent;
}
/**
* Retuns whether this view has a parent.
*
* @return Boolean Whether this view has a parent
*/
public function hasParent()
{
return null !== $this->parent;
}
/**
* Sets the children view.
*
* @param array $children The children as instances of FormView
*/
public function setChildren(array $children)
{
$this->children = $children;
}
/**
* Returns the children.
*
* @return array The children as instances of FormView
*/
public function getChildren()
{
return $this->children;
}
/**
* Returns wether this view has children.
*
* @return Boolean Whether this view has children
*/
public function hasChildren()
{
return count($this->children) > 0;
}
/**
* Returns a child by name (implements \ArrayAccess).
*
* @param string $name The child name
*
* @return FormView The child view
*/
public function offsetGet($name)
{
return $this->children[$name];
}
/**
* Returns whether the given child exists (implements \ArrayAccess).
*
* @param string $name The child name
*
* @return Boolean Whether the child view exists
*/
public function offsetExists($name)
{
return isset($this->children[$name]);
}
/**
* Implements \ArrayAccess.
*
* @throws \BadMethodCallException always as setting a child by name is not allowed
*/
public function offsetSet($name, $value)
{
throw new \BadMethodCallException('Not supported');
}
/**
* Removes a child (implements \ArrayAccess).
*
* @param string $name The child name
*/
public function offsetUnset($name)
{
unset($this->children[$name]);
}
/**
* Returns an iterator to iterate over children (implements \IteratorAggregate)
*
* @return \ArrayIterator The iterator
*/
public function getIterator()
{
if (count($this->children)) {
@ -159,11 +233,25 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
return new \ArrayIterator($this->children);
}
/**
* Returns whether the given choice is a group.
*
* @param mixed $choice A choice
*
* @return Boolean Whether the choice is a group
*/
public function isChoiceGroup($choice)
{
return is_array($choice) || $choice instanceof \Traversable;
}
/**
* Returns whether the given choice is selected.
*
* @param mixed $choice The choice
*
* @return Boolean Whether the choice is selected
*/
public function isChoiceSelected($choice)
{
$choice = FormUtil::toArrayKey($choice);
@ -178,8 +266,9 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable
}
/**
* @see Countable
* @return integer
* Implements \Countable.
*
* @return integer The number of children views
*/
public function count()
{

View File

@ -15,15 +15,15 @@ abstract class FormUtil
{
public static function toArrayKey($value)
{
if ((string)(int)$value === (string)$value) {
return (int)$value;
if ((string) (int) $value === (string) $value) {
return (int) $value;
}
if (is_bool($value)) {
return (int)$value;
return (int) $value;
}
return (string)$value;
return (string) $value;
}
public static function toArrayKeys(array $array)