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

View File

@ -39,9 +39,9 @@ interface DataTransformerInterface
* By convention, transform() should return an empty string if NULL is * By convention, transform() should return an empty string if NULL is
* passed. * passed.
* *
* @param mixed $value The value in the original representation * @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 no string * @throws UnexpectedTypeException when the argument is no string
* @throws DataTransformerException when the transformation fails * @throws DataTransformerException when the transformation fails
*/ */
function transform($value); function transform($value);
@ -64,9 +64,9 @@ interface DataTransformerInterface
* By convention, reverseTransform() should return NULL if an empty string * By convention, reverseTransform() should return NULL if an empty string
* is passed. * is passed.
* *
* @param mixed $value The value in the transformed representation * @param mixed $value The value in the transformed representation
* @throws UnexpectedTypeException when the argument is not of the * @throws UnexpectedTypeException when the argument is not of the
* expected type * expected type
* @throws DataTransformerException when the transformation fails * @throws DataTransformerException when the transformation fails
*/ */
function reverseTransform($value); function reverseTransform($value);

View File

@ -1,5 +1,14 @@
<?php <?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; namespace Symfony\Component\Form\Event;
use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\Event;
@ -8,20 +17,35 @@ use Symfony\Component\Form\FormInterface;
class DataEvent extends Event class DataEvent extends Event
{ {
private $form; private $form;
protected $data; protected $data;
/**
* Constructs an event.
*
* @param FormInterface $form The associated form
* @param mixed $data The data
*/
public function __construct(FormInterface $form, $data) public function __construct(FormInterface $form, $data)
{ {
$this->form = $form; $this->form = $form;
$this->data = $data; $this->data = $data;
} }
/**
* Returns the form at the source of the event.
*
* @return FormInterafce
*/
public function getForm() public function getForm()
{ {
return $this->form; return $this->form;
} }
/**
* Returns the data associated with this event.
*
* @return type
*/
public function getData() public function getData()
{ {
return $this->data; return $this->data;

View File

@ -1,9 +1,23 @@
<?php <?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; namespace Symfony\Component\Form\Event;
class FilterDataEvent extends DataEvent class FilterDataEvent extends DataEvent
{ {
/**
* Allows updating with some filtered data
*
* @param mixed $data
*/
public function setData($data) public function setData($data)
{ {
$this->data = $data; $this->data = $data;

View File

@ -19,6 +19,13 @@ class ArrayChoiceList implements ChoiceListInterface
protected $loaded = false; 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) public function __construct($choices)
{ {
if (!is_array($choices) && !$choices instanceof \Closure) { if (!is_array($choices) && !$choices instanceof \Closure) {
@ -28,6 +35,11 @@ class ArrayChoiceList implements ChoiceListInterface
$this->choices = $choices; $this->choices = $choices;
} }
/**
* Returns a list of choices
*
* @return array
*/
public function getChoices() public function getChoices()
{ {
if (!$this->loaded) { 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() protected function load()
{ {

View File

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

View File

@ -16,7 +16,7 @@ class MonthChoiceList extends PaddedChoiceList
private $formatter; private $formatter;
/** /**
* Generates an array of localized month choices * Generates an array of localized month choices.
* *
* @param IntlDateFormatter $formatter An IntlDateFormatter instance * @param IntlDateFormatter $formatter An IntlDateFormatter instance
* @param array $months The month numbers to generate * @param array $months The month numbers to generate
@ -28,6 +28,11 @@ class MonthChoiceList extends PaddedChoiceList
$this->formatter = $formatter; $this->formatter = $formatter;
} }
/**
* Initializes the list of months.
*
* @throws UnexpectedTypeException if the function does not return an array
*/
protected function load() protected function load()
{ {
parent::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 * If the values are shorter than $padLength characters, they are padded with
* zeros on the left side. * 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 integer $padLength The length to pad the choices
* @param string $padString The padding character * @param string $padString The padding character
* @param integer $padType The direction of padding * @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) public function __construct($values, $padLength, $padString, $padType = STR_PAD_LEFT)
{ {
@ -39,6 +41,13 @@ class PaddedChoiceList extends ArrayChoiceList
$this->padType = $padType; $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() protected function load()
{ {
parent::load(); parent::load();

View File

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

View File

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

View File

@ -27,6 +27,12 @@ abstract class BaseDateTimeTransformer implements DataTransformerInterface
protected $outputTimezone; 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) public function __construct($inputTimezone = null, $outputTimezone = null)
{ {
$this->inputTimezone = $inputTimezone ?: date_default_timezone_get(); $this->inputTimezone = $inputTimezone ?: date_default_timezone_get();

View File

@ -26,7 +26,10 @@ class BooleanToStringTransformer implements DataTransformerInterface
* Transforms a Boolean into a string. * Transforms a Boolean into a string.
* *
* @param Boolean $value Boolean value. * @param Boolean $value Boolean value.
*
* @return string String value. * @return string String value.
*
* @throws UnexpectedTypeException if the given value is not a Boolean
*/ */
public function transform($value) public function transform($value)
{ {
@ -45,7 +48,10 @@ class BooleanToStringTransformer implements DataTransformerInterface
* Transforms a string into a Boolean. * Transforms a string into a Boolean.
* *
* @param string $value String value. * @param string $value String value.
*
* @return Boolean Boolean value. * @return Boolean Boolean value.
*
* @throws UnexpectedTypeException if the given value is not a string
*/ */
public function reverseTransform($value) 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. * 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 Bernhard Schussek <bernhard.schussek@symfony.com>
* @author Florian Eckerstorfer <florian@eckerstorfer.org> * @author Florian Eckerstorfer <florian@eckerstorfer.org>
*/ */
@ -32,7 +26,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
private $fields; 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); parent::__construct($inputTimezone, $outputTimezone);
@ -41,14 +45,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
} }
$this->fields = $fields; $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. * @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) public function transform($dateTime)
{ {
@ -67,11 +74,8 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($dateTime, '\DateTime'); throw new UnexpectedTypeException($dateTime, '\DateTime');
} }
$inputTimezone = $this->inputTimezone; if ($this->inputTimezone !== $this->outputTimezone) {
$outputTimezone = $this->outputTimezone; $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
if ($inputTimezone != $outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($outputTimezone));
} }
$result = array_intersect_key(array( $result = array_intersect_key(array(
@ -86,7 +90,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
if (!$this->pad) { if (!$this->pad) {
foreach ($result as &$entry) { foreach ($result as &$entry) {
// remove leading zeros // 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 * @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) public function reverseTransform($value)
{ {
@ -105,9 +113,6 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
return null; return null;
} }
$inputTimezone = $this->inputTimezone;
$outputTimezone = $this->outputTimezone;
if (!is_array($value)) { if (!is_array($value)) {
throw new UnexpectedTypeException($value, 'array'); throw new UnexpectedTypeException($value, 'array');
} }
@ -125,8 +130,9 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
} }
if (count($emptyFields) > 0) { if (count($emptyFields) > 0) {
throw new TransformationFailedException(sprintf( throw new TransformationFailedException(
'The fields "%s" should not be empty', implode('", "', $emptyFields))); sprintf('The fields "%s" should not be empty', implode('", "', $emptyFields)
));
} }
try { try {
@ -138,14 +144,14 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer
empty($value['hour']) ? '0' : $value['hour'], empty($value['hour']) ? '0' : $value['hour'],
empty($value['minute']) ? '0' : $value['minute'], empty($value['minute']) ? '0' : $value['minute'],
empty($value['second']) ? '0' : $value['second'], empty($value['second']) ? '0' : $value['second'],
$outputTimezone $this->outputTimezone
)); ));
} catch (\Exception $e) { } catch (\Exception $e) {
throw new TransformationFailedException($e->getMessage(), null, $e); throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
} }
if ($inputTimezone != $outputTimezone) { if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone)); $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
} }
return $dateTime; return $dateTime;

View File

@ -17,12 +17,6 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
/** /**
* Transforms between a normalized time and a localized time string * 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 Bernhard Schussek <bernhard.schussek@symfony.com>
* @author Florian Eckerstorfer <florian@eckerstorfer.org> * @author Florian Eckerstorfer <florian@eckerstorfer.org>
*/ */
@ -32,6 +26,19 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
private $timeFormat; 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) public function __construct($inputTimezone = null, $outputTimezone = null, $dateFormat = null, $timeFormat = null)
{ {
parent::__construct($inputTimezone, $outputTimezone); parent::__construct($inputTimezone, $outputTimezone);
@ -60,7 +67,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
* Transforms a normalized date into a localized date string/array. * Transforms a normalized date into a localized date string/array.
* *
* @param DateTime $dateTime Normalized date. * @param DateTime $dateTime Normalized date.
*
* @return string|array Localized date string/array. * @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) public function transform($dateTime)
{ {
@ -72,14 +83,12 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($dateTime, '\DateTime'); throw new UnexpectedTypeException($dateTime, '\DateTime');
} }
$inputTimezone = $this->inputTimezone;
// convert time to UTC before passing it to the formatter // convert time to UTC before passing it to the formatter
if ('UTC' != $inputTimezone) { if ('UTC' !== $this->inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone('UTC')); $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) { if (intl_get_error_code() != 0) {
throw new TransformationFailedException(intl_get_error_message()); 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. * Transforms a localized date string/array into a normalized date.
* *
* @param string|array $value Localized date string/array * @param string|array $value Localized date string/array
*
* @return DateTime Normalized date * @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) public function reverseTransform($value)
{ {
$inputTimezone = $this->inputTimezone;
if (!is_string($value)) { if (!is_string($value)) {
throw new UnexpectedTypeException($value, 'string'); throw new UnexpectedTypeException($value, 'string');
} }
@ -115,8 +126,8 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
// read timestamp into DateTime object - the formatter delivers in UTC // read timestamp into DateTime object - the formatter delivers in UTC
$dateTime = new \DateTime(sprintf('@%s UTC', $timestamp)); $dateTime = new \DateTime(sprintf('@%s UTC', $timestamp));
if ('UTC' != $inputTimezone) { if ('UTC' !== $this->inputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone)); $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
} }
return $dateTime; return $dateTime;
@ -129,10 +140,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer
*/ */
protected function getIntlDateFormatter() protected function getIntlDateFormatter()
{ {
$dateFormat = $this->dateFormat; return new \IntlDateFormatter(
$timeFormat = $this->timeFormat; \Locale::getDefault(),
$timezone = $this->outputTimezone; $this->dateFormat,
$this->timeFormat,
return new \IntlDateFormatter(\Locale::getDefault(), $dateFormat, $timeFormat, $timezone); $this->outputTimezone
);
} }
} }

View File

@ -24,6 +24,17 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
{ {
private $format; 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') public function __construct($inputTimezone = null, $outputTimezone = null, $format = 'Y-m-d H:i:s')
{ {
parent::__construct($inputTimezone, $outputTimezone); parent::__construct($inputTimezone, $outputTimezone);
@ -36,7 +47,10 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
* and timezone * and timezone
* *
* @param DateTime $value A DateTime object * @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
*/ */
public function transform($value) 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 * @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) public function reverseTransform($value)
{ {
@ -69,19 +87,16 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($value, 'string'); throw new UnexpectedTypeException($value, 'string');
} }
$outputTimezone = $this->outputTimezone;
$inputTimezone = $this->inputTimezone;
try { try {
$dateTime = new \DateTime("$value $outputTimezone"); $dateTime = new \DateTime(sprintf("%s %s", $value, $this->outputTimezone));
if ($inputTimezone != $outputTimezone) { if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimeZone(new \DateTimeZone($inputTimezone)); $dateTime->setTimeZone(new \DateTimeZone($this->inputTimezone));
} }
return $dateTime; return $dateTime;
} catch (\Exception $e) { } 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 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 * @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
*/ */
public function transform($value) public function transform($value)
{ {
@ -40,14 +43,18 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
$value->setTimezone(new \DateTimeZone($this->outputTimezone)); $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 * Transforms a timestamp in the configured timezone into a DateTime object
* *
* @param string $value A value as produced by PHP's date() function * @param string $value A timestamp
* @return DateTime A DateTime object *
* @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) public function reverseTransform($value)
{ {
@ -59,19 +66,16 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
throw new UnexpectedTypeException($value, 'numeric'); throw new UnexpectedTypeException($value, 'numeric');
} }
$outputTimezone = $this->outputTimezone;
$inputTimezone = $this->inputTimezone;
try { try {
$dateTime = new \DateTime("@$value $outputTimezone"); $dateTime = new \DateTime(sprintf("@%s %s", $value, $this->outputTimezone));
if ($inputTimezone != $outputTimezone) { if ($this->inputTimezone !== $this->outputTimezone) {
$dateTime->setTimezone(new \DateTimeZone($inputTimezone)); $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone));
} }
return $dateTime; return $dateTime;
} catch (\Exception $e) { } 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 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) public function transform($file)
{ {
if (null === $file || '' === $file) { if (null === $file || '' === $file) {
return array( return array('file' => '');
'file' => '',
);
} }
if (!$file instanceof File) { if (!$file instanceof File) {
throw new UnexpectedTypeException($file, 'Symfony\Component\HttpFoundation\File\File'); throw new UnexpectedTypeException($file, 'Symfony\Component\HttpFoundation\File\File');
} }
return array( return array('file' => $file);
'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) public function reverseTransform($array)
{ {
if (null === $array || '' === $array || array() === $array) { if (null === $array || '' === $array || array() === $array) {

View File

@ -24,6 +24,6 @@ class IntegerToLocalizedStringTransformer extends NumberToLocalizedStringTransfo
*/ */
public function reverseTransform($value) 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. * Transforms a normalized format into a localized money string.
* *
* @param number $value Normalized number * @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
*/ */
public function transform($value) public function transform($value)
{ {
@ -66,7 +70,11 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransform
* Transforms a localized money string into a normalized format. * Transforms a localized money string into a normalized format.
* *
* @param string $value Localized money string * @param string $value Localized money string
*
* @return number Normalized number * @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) public function reverseTransform($value)
{ {

View File

@ -56,8 +56,12 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
/** /**
* Transforms a number type into localized number. * Transforms a number type into localized number.
* *
* @param number $value Number value. * @param integer|float $value Number value.
* @return string Localized 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) public function transform($value)
{ {
@ -82,7 +86,12 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
/** /**
* Transforms a localized number into an integer or float * 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) public function reverseTransform($value)
{ {

View File

@ -35,6 +35,14 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
private $precision; 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) public function __construct($precision = null, $type = null)
{ {
if (is_null($precision)) { if (is_null($precision)) {
@ -46,7 +54,7 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
} }
if (!in_array($type, self::$types, true)) { 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; $this->type = $type;
@ -56,8 +64,12 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
/** /**
* Transforms between a normalized format (integer or float) into a percentage value. * Transforms between a normalized format (integer or float) into a percentage value.
* *
* @param number $value Normalized value. * @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
*/ */
public function transform($value) public function transform($value)
{ {
@ -88,7 +100,11 @@ class PercentToLocalizedStringTransformer implements DataTransformerInterface
* Transforms between a percentage value into a normalized format (integer or float). * Transforms between a percentage value into a normalized format (integer or float).
* *
* @param number $value Percentage value. * @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
*/ */
public function reverseTransform($value) public function reverseTransform($value)
{ {

View File

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

View File

@ -70,7 +70,7 @@ class Form implements \IteratorAggregate, FormInterface
private $name; private $name;
/** /**
* The parent fo this form * The parent of this form
* @var FormInterface * @var FormInterface
*/ */
private $parent; private $parent;
@ -115,7 +115,7 @@ class Form implements \IteratorAggregate, FormInterface
* The form data in application format * The form data in application format
* @var mixed * @var mixed
*/ */
private $data; private $appData;
/** /**
* The form data in normalized format * The form data in normalized format
@ -136,22 +136,22 @@ class Form implements \IteratorAggregate, FormInterface
private $emptyData = ''; 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 * @var array
*/ */
private $extraData = array(); private $extraData = array();
/** /**
* The transformer for transforming from application to normalized format * The transformers for transforming from application to normalized format
* and back * and back
* @var DataTransformer\DataTransformerInterface * @var array An array of DataTransformerInterface
*/ */
private $normTransformers; private $normTransformers;
/** /**
* The transformer for transforming from normalized to client format and * The transformers for transforming from normalized to client format and
* back * back
* @var DataTransformer\DataTransformerInterface * @var array An array of DataTransformerInterface
*/ */
private $clientTransformers; private $clientTransformers;
@ -189,7 +189,7 @@ class Form implements \IteratorAggregate, FormInterface
/** /**
* The FormTypeInterface instances used to create this form * The FormTypeInterface instances used to create this form
* @var array * @var array An array of FormTypeInterface
*/ */
private $types; private $types;
@ -218,18 +218,18 @@ class Form implements \IteratorAggregate, FormInterface
} }
} }
$this->name = (string)$name; $this->name = (string) $name;
$this->types = $types;
$this->dispatcher = $dispatcher; $this->dispatcher = $dispatcher;
$this->types = $types;
$this->clientTransformers = $clientTransformers; $this->clientTransformers = $clientTransformers;
$this->normTransformers = $normTransformers; $this->normTransformers = $normTransformers;
$this->validators = $validators;
$this->dataMapper = $dataMapper; $this->dataMapper = $dataMapper;
$this->required = $required; $this->validators = $validators;
$this->readOnly = $readOnly; $this->required = (Boolean) $required;
$this->attributes = $attributes; $this->readOnly = (Boolean) $readOnly;
$this->errorBubbling = $errorBubbling; $this->errorBubbling = (Boolean) $errorBubbling;
$this->emptyData = $emptyData; $this->emptyData = $emptyData;
$this->attributes = $attributes;
$this->setData(null); $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() public function getName()
{ {
return $this->name; return $this->name;
} }
/**
* Returns the supported types.
*
* @return array An array of FormTypeInterface
*/
public function getTypes() public function getTypes()
{ {
return $this->types; 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() public function isRequired()
{ {
if (null === $this->parent || $this->parent->isRequired()) { if (null === $this->parent || $this->parent->isRequired()) {
return $this->required; 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() public function isReadOnly()
{ {
if (null === $this->parent || !$this->parent->isReadOnly()) { if (null === $this->parent || !$this->parent->isReadOnly()) {
return $this->readOnly; 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) public function setParent(FormInterface $parent = null)
{ {
@ -291,7 +318,7 @@ class Form implements \IteratorAggregate, FormInterface
/** /**
* Returns the parent field. * Returns the parent field.
* *
* @return FormInterface The parent field * @return FormInterface The parent field
*/ */
public function getParent() public function getParent()
{ {
@ -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 * @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 * @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 * @return Boolean
*/ */
@ -328,20 +355,32 @@ class Form implements \IteratorAggregate, FormInterface
return !$this->hasParent(); 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) public function hasAttribute($name)
{ {
return isset($this->attributes[$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) public function getAttribute($name)
{ {
return $this->attributes[$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) public function setData($appData)
{ {
@ -355,14 +394,14 @@ class Form implements \IteratorAggregate, FormInterface
// Treat data as strings unless a value transformer exists // Treat data as strings unless a value transformer exists
if (!$this->clientTransformers && !$this->normTransformers && is_scalar($appData)) { if (!$this->clientTransformers && !$this->normTransformers && is_scalar($appData)) {
$appData = (string)$appData; $appData = (string) $appData;
} }
// Synchronize representations - must not change the content! // Synchronize representations - must not change the content!
$normData = $this->appToNorm($appData); $normData = $this->appToNorm($appData);
$clientData = $this->normToClient($normData); $clientData = $this->normToClient($normData);
$this->data = $appData; $this->appData = $appData;
$this->normData = $normData; $this->normData = $normData;
$this->clientData = $clientData; $this->clientData = $clientData;
$this->synchronized = true; $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) public function bind($clientData)
{ {
@ -390,7 +463,7 @@ class Form implements \IteratorAggregate, FormInterface
} }
if (is_scalar($clientData) || null === $clientData) { 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 // 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; $clientData = $this->emptyData;
if ($clientData instanceof \Closure) { if ($clientData instanceof \Closure) {
$clientData = $clientData->__invoke($this); $clientData = $clientData($this);
} }
} }
@ -473,7 +546,7 @@ class Form implements \IteratorAggregate, FormInterface
} }
$this->bound = true; $this->bound = true;
$this->data = $appData; $this->appData = $appData;
$this->normData = $normData; $this->normData = $normData;
$this->clientData = $clientData; $this->clientData = $clientData;
$this->extraData = $extraData; $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). * 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 * @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) public function bindRequest(Request $request)
{ {
@ -519,16 +591,6 @@ class Form implements \IteratorAggregate, FormInterface
$this->bind($data); $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. * Returns the normalized data of the field.
* *
@ -541,21 +603,6 @@ class Form implements \IteratorAggregate, FormInterface
return $this->normData; 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. * 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 * @return Boolean
*/ */
@ -583,7 +630,7 @@ class Form implements \IteratorAggregate, FormInterface
/** /**
* Returns whether the field is bound. * Returns whether the field is bound.
* *
* @return Boolean true if the form is bound to input values, false otherwise * @return Boolean true if the form is bound to input values, false otherwise
*/ */
public function isBound() public function isBound()
{ {
@ -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 * @return Boolean
*/ */
@ -601,17 +648,20 @@ class Form implements \IteratorAggregate, FormInterface
} }
/** /**
* {@inheritDoc} * Returns whether the form is empty.
*
* @return Boolean
*/ */
public function isEmpty() public function isEmpty()
{ {
foreach ($this->children as $child) { foreach ($this->children as $child) {
if (!$child->isEmpty()) { if (!$child->isEmpty()) {
return false; 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() public function isValid()
{ {
if (!$this->isBound() || $this->hasErrors()) { if (!$this->isBound() || $this->hasErrors()) {
return false; return false;
} }
foreach ($this->children as $child) { foreach ($this->children as $child) {
if (!$child->isValid()) { if (!$child->isValid()) {
return false; 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 * @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() 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() 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 * @return array
*/ */
@ -688,11 +740,21 @@ class Form implements \IteratorAggregate, FormInterface
return $this->children; return $this->children;
} }
/**
* Return whether the form has children.
*
* @return Boolean
*/
public function hasChildren() public function hasChildren()
{ {
return count($this->children) > 0; 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) public function add(FormInterface $child)
{ {
$this->children[$child->getName()] = $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) public function remove($name)
{ {
if (isset($this->children[$name])) { if (isset($this->children[$name])) {
@ -717,6 +784,7 @@ class Form implements \IteratorAggregate, FormInterface
* Returns whether a child with the given name exists. * Returns whether a child with the given name exists.
* *
* @param string $name * @param string $name
*
* @return Boolean * @return Boolean
*/ */
public function has($name) public function has($name)
@ -728,11 +796,15 @@ class Form implements \IteratorAggregate, FormInterface
* Returns the child with the given name. * Returns the child with the given name.
* *
* @param string $name * @param string $name
*
* @return FormInterface * @return FormInterface
*
* @throws \InvalidArgumentException if the child does not exist
*/ */
public function get($name) public function get($name)
{ {
if (isset($this->children[$name])) { if (isset($this->children[$name])) {
return $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 * @param mixed $value The value to transform
*
* @return string * @return string
*/ */
private function appToNorm($value) private function appToNorm($value)
@ -819,6 +892,71 @@ class Form implements \IteratorAggregate, FormInterface
return $value; 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) public function createView(FormView $parent = null)
{ {
if (null === $parent && $this->parent) { if (null === $parent && $this->parent) {
@ -827,9 +965,7 @@ class Form implements \IteratorAggregate, FormInterface
$view = new FormView(); $view = new FormView();
if (null !== $parent) { $view->setParent($parent);
$view->setParent($parent);
}
$types = (array) $this->types; $types = (array) $this->types;
$childViews = array(); $childViews = array();
@ -858,59 +994,4 @@ class Form implements \IteratorAggregate, FormInterface
return $view; 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; private $guesser;
/**
* Constructor.
*
* @param array $extensions An array of FormExtensionInterface
*
* @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
*/
public function __construct(array $extensions) public function __construct(array $extensions)
{ {
foreach ($extensions as $extension) { foreach ($extensions as $extension) {

View File

@ -32,30 +32,108 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
*/ */
function getParent(); function getParent();
function add(FormInterface $child); /**
* Returns whether the form has a parent.
function has($name); *
* @return Boolean
function remove($name); */
function getChildren();
function hasChildren();
function hasParent(); 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 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(); 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(); function getNormData();
/**
* Returns the data transformed by the value transformer.
*
* @return string
*/
function getClientData(); 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(); function isBound();
/**
* Returns the supported types.
*
* @return array An array of FormTypeInterface
*/
function getTypes(); function getTypes();
/** /**
@ -66,7 +144,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function getName(); function getName();
/** /**
* Adds an error to this form * Adds an error to this form.
* *
* @param FormError $error * @param FormError $error
*/ */
@ -91,7 +169,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function isRequired(); 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 * The content of a read-only form is displayed, but not allowed to be
* modified. The validation of modified read-only forms should fail. * modified. The validation of modified read-only forms should fail.
@ -104,28 +182,60 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
function isReadOnly(); function isReadOnly();
/** /**
* Returns whether the form is empty * Returns whether the form is empty.
* *
* @return Boolean * @return Boolean
*/ */
function isEmpty(); function isEmpty();
/**
* Returns whether the data in the different formats is synchronized.
*
* @return Boolean
*/
function isSynchronized(); 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); 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); function hasAttribute($name);
/**
* Returns the value of the attributes with the given name.
*
* @param string $name The name of the attribute
*/
function getAttribute($name); function getAttribute($name);
/**
* Returns the root of the form tree.
*
* @return FormInterface The root of the tree
*/
function getRoot(); function getRoot();
/**
* Returns whether the field is the root of the form tree.
*
* @return Boolean
*/
function isRoot(); function isRoot();
/**
* Creates a view.
*
* @param FormView $parent The parent view
*
* @return FormView The view
*/
function createView(FormView $parent = null); function createView(FormView $parent = null);
} }

View File

@ -21,13 +21,44 @@ interface FormTypeInterface
function createBuilder($name, FormFactoryInterface $factory, array $options); 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); 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); function getParent(array $options);
/**
* Returns the name of this type.
*
* @return string The name of this type
*/
function getName(); 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); function setExtensions(array $extensions);
/**
* Returns the extensions associated with this type.
*
* @return array An array of FormTypeExtensionInterface
*/
function getExtensions(); function getExtensions();
} }

View File

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

View File

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