diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php index 9bbeee1b19..64960ec372 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ArrayToBooleanChoicesTransformer.php @@ -25,17 +25,19 @@ class ArrayToBooleanChoicesTransformer implements DataTransformerInterface } /** - * Transforms a single choice or an array of choices to a format appropriate - * for the nested checkboxes/radio buttons. + * Transforms an array of choices to a format appropriate for the nested + * checkboxes/radio buttons. * * The result is an array with the options as keys and true/false as values, * depending on whether a given option is selected. If this field is rendered * as select tag, the value is not modified. * - * @param mixed $array An array if "multiple" is set to true, a scalar - * value otherwise. - * @return mixed An array if "expanded" or "multiple" is set to true, - * a scalar value otherwise. + * @param mixed $array An array + * + * @return mixed An array + * + * @throws UnexpectedTypeException if the given value is not an array + * @throws TransformationFailedException if the choices can not be retrieved */ public function transform($array) { @@ -47,27 +49,31 @@ class ArrayToBooleanChoicesTransformer implements DataTransformerInterface throw new UnexpectedTypeException($array, 'array'); } - $choices = $this->choiceList->getChoices(); + try { + $choices = $this->choiceList->getChoices(); + } catch (\Exception $e) { + throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); + } - foreach ($choices as $choice => $_) { - $choices[$choice] = in_array($choice, $array, true); + foreach (array_keys($choices) as $key) { + $choices[$key] = in_array($key, $array, true); } return $choices; } /** - * Transforms a checkbox/radio button array to a single choice or an array - * of choices. + * Transforms a checkbox/radio button array to an array of choices. * * The input value is an array with the choices as keys and true/false as * values, depending on whether a given choice is selected. The output - * is an array with the selected choices or a single selected choice. + * is an array with the selected choices. * - * @param mixed $value An array if "expanded" or "multiple" is set to true, - * a scalar value otherwise. - * @return mixed $value An array if "multiple" is set to true, a scalar - * value otherwise. + * @param mixed $value An array + * + * @return mixed $value An array + * + * @throws UnexpectedTypeException if the given value is not an array */ public function reverseTransform($value) { diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php index c4a9c776b8..85f5aa995d 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DataTransformerChain.php @@ -45,7 +45,11 @@ class DataTransformerChain implements DataTransformerInterface * by this method. * * @param mixed $value The original value + * * @return mixed The transformed value + * + * @throws Symfony\Component\Form\Exception\TransformationFailedException + * @throws Symfony\Component\Form\Exception\UnexpectedTypeException */ public function transform($value) { @@ -66,7 +70,11 @@ class DataTransformerChain implements DataTransformerInterface * by this method. * * @param mixed $value The transformed value + * * @return mixed The reverse-transformed value + * + * @throws Symfony\Component\Form\Exception\TransformationFailedException + * @throws Symfony\Component\Form\Exception\UnexpectedTypeException */ public function reverseTransform($value) { diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php index e77d2bb074..5971753cee 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php @@ -56,6 +56,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer * @return array Localized date. * * @throws UnexpectedTypeException if the given value is not an instance of \DateTime + * @throws TransformationFailedException if the output timezone is not supported */ public function transform($dateTime) { @@ -74,8 +75,13 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer throw new UnexpectedTypeException($dateTime, '\DateTime'); } + if ($this->inputTimezone !== $this->outputTimezone) { - $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); + try { + $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); + } catch (\Exception $e) { + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); + } } $result = array_intersect_key(array( @@ -106,6 +112,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer * * @throws UnexpectedTypeException if the given value is not an array * @throws TransformationFailedException if the value could not bet transformed + * @throws TransformationFailedException if the input timezone is not supported */ public function reverseTransform($value) { @@ -146,14 +153,14 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer empty($value['second']) ? '0' : $value['second'], $this->outputTimezone )); + + if ($this->inputTimezone !== $this->outputTimezone) { + $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); + } } catch (\Exception $e) { throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } - if ($this->inputTimezone !== $this->outputTimezone) { - $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); - } - return $dateTime; } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php index 8c746c3fee..783b50f841 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php @@ -52,11 +52,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer } if (!in_array($dateFormat, self::$formats, true)) { - throw new \InvalidArgumentException(sprintf('The value $dateFormat is expected to be one of "%s". Is "%s"', implode('", "', self::$formats), $dateFormat)); + throw new UnexpectedTypeException($dateFormat, implode('", "', self::$formats)); } if (!in_array($timeFormat, self::$formats, true)) { - throw new \InvalidArgumentException(sprintf('The value $timeFormat is expected to be one of "%s". Is "%s"', implode('", "', self::$formats), $timeFormat)); + throw new UnexpectedTypeException($timeFormat, implode('", "', self::$formats)); } $this->dateFormat = $dateFormat; @@ -106,6 +106,7 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer * * @throws UnexpectedTypeException if the given value is not a string * @throws TransformationFailedException if the date could not be parsed + * @throws TransformationFailedException if the input timezone is not supported */ public function reverseTransform($value) { @@ -127,7 +128,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer $dateTime = new \DateTime(sprintf('@%s UTC', $timestamp)); if ('UTC' !== $this->inputTimezone) { - $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); + try { + $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); + } catch (\Exception $e) { + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); + } } return $dateTime; diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php index 5f556b74ae..938433dd0b 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php @@ -51,6 +51,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer * @return string A value as produced by PHP's date() function * * @throws UnexpectedTypeException if the given value is not a \DateTime instance + * @throws TransformationFailedException if the output timezone is not supported */ public function transform($value) { @@ -62,7 +63,11 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer throw new UnexpectedTypeException($value, '\DateTime'); } - $value->setTimezone(new \DateTimeZone($this->outputTimezone)); + try { + $value->setTimezone(new \DateTimeZone($this->outputTimezone)); + } catch (\Exception $e) { + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); + } return $value->format($this->format); } @@ -76,6 +81,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer * * @throws UnexpectedTypeException if the given value is not a string * @throws TransformationFailedException if the date could not be parsed + * @throws TransformationFailedException if the input timezone is not supported */ public function reverseTransform($value) { @@ -93,10 +99,10 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer if ($this->inputTimezone !== $this->outputTimezone) { $dateTime->setTimeZone(new \DateTimeZone($this->inputTimezone)); } - - return $dateTime; } catch (\Exception $e) { - throw new TransformationFailedException('Invalid date format.', $e->getCode(), $e); + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } + + return $dateTime; } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php index 76229e8570..36fefdd05f 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php @@ -30,6 +30,7 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer * @return integer A timestamp * * @throws UnexpectedTypeException if the given value is not an instance of \DateTime + * @throws TransformationFailedException if the output timezone is not supported */ public function transform($value) { @@ -41,7 +42,11 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer throw new UnexpectedTypeException($value, '\DateTime'); } - $value->setTimezone(new \DateTimeZone($this->outputTimezone)); + try { + $value->setTimezone(new \DateTimeZone($this->outputTimezone)); + } catch (\Exception $e) { + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); + } return (int) $value->format('U'); } @@ -72,10 +77,10 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer if ($this->inputTimezone !== $this->outputTimezone) { $dateTime->setTimezone(new \DateTimeZone($this->inputTimezone)); } - - return $dateTime; } catch (\Exception $e) { - throw new TransformationFailedException('Invalid timestamp format.', $e->getCode(), $e); + throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } + + return $dateTime; } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php index e84f684b35..edc7ef1578 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/FileToStringTransformer.php @@ -13,6 +13,8 @@ namespace Symfony\Component\Form\Extension\Core\DataTransformer; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Exception\UnexpectedTypeException; +use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; +use Symfony\Component\Form\Exception\TransformationFailedException; use Symfony\Component\HttpFoundation\File\File; /** @@ -20,6 +22,15 @@ use Symfony\Component\HttpFoundation\File\File; */ class FileToStringTransformer implements DataTransformerInterface { + /** + * Transforms a File instance to a path + * + * @param File $file The file + * + * @return string The path to the file + * + * @throws UnexpectedTypeException if the given file is not an instance of File + */ public function transform($file) { if (null === $file || '' === $file) { @@ -33,6 +44,17 @@ class FileToStringTransformer implements DataTransformerInterface return $file->getPath(); } + + /** + * Transforms a path to a File instance + * + * @param string $path The path to the file + * + * @return File The File + * + * @throws UnexpectedTypeException if the given path is not a string + * @throws TransformationFailedException if the File instance could not be created + */ public function reverseTransform($path) { if (null === $path || '' === $path) { @@ -43,6 +65,16 @@ class FileToStringTransformer implements DataTransformerInterface throw new UnexpectedTypeException($path, 'string'); } - return new File($path); + try { + $file = new File($path); + } catch (FileNotFoundException $e) { + throw new TransformationFailedException( + sprintf('The file "%s" does not exist', $path), + $e->getCode(), + $e + ); + } + + return $file; } } \ No newline at end of file diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php index 3faa151f7d..fd26908da1 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/ScalarToBooleanChoicesTransformer.php @@ -19,14 +19,19 @@ class ScalarToBooleanChoicesTransformer implements DataTransformerInterface { private $choiceList; + /** + * Constructor. + * + * @param ChoiceListInterface $choiceList + */ public function __construct(ChoiceListInterface $choiceList) { $this->choiceList = $choiceList; } /** - * Transforms a single choice or an array of choices to a format appropriate - * for the nested checkboxes/radio buttons. + * Transforms a single choice to a format appropriate for the nested + * checkboxes/radio buttons. * * The result is an array with the options as keys and true/false as values, * depending on whether a given option is selected. If this field is rendered @@ -34,32 +39,43 @@ class ScalarToBooleanChoicesTransformer implements DataTransformerInterface * * @param mixed $value An array if "multiple" is set to true, a scalar * value otherwise. - * @return mixed An array if "expanded" or "multiple" is set to true, - * a scalar value otherwise. + * + * @return mixed An array + * + * @throws UnexpectedTypeException if the given value is not scalar + * @throws TransformationFailedException if the choices can not be retrieved */ public function transform($value) { - $choices = $this->choiceList->getChoices(); + if (!is_scalar($value) && !is_null($value)) { + throw new UnexpectedTypeException($value, 'scalar'); + } - foreach ($choices as $choice => $_) { - $choices[$choice] = $choice === $value; + try { + $choices = $this->choiceList->getChoices(); + } catch (\Exception $e) { + throw new TransformationFailedException('Can not get the choice list', $e->getCode(), $e); + } + + foreach (array_keys($choices) as $key) { + $choices[$key] = $key === $value; } return $choices; } /** - * Transforms a checkbox/radio button array to a single choice or an array - * of choices. + * Transforms a checkbox/radio button array to a single choice. * * The input value is an array with the choices as keys and true/false as * values, depending on whether a given choice is selected. The output - * is an array with the selected choices or a single selected choice. + * is the selected choice. * - * @param mixed $value An array if "expanded" or "multiple" is set to true, - * a scalar value otherwise. - * @return mixed $value An array if "multiple" is set to true, a scalar - * value otherwise. + * @param array $value An array of values + * + * @return mixed $value A scalar value + * + * @throws new UnexpectedTypeException if the given value is not an array */ public function reverseTransform($value) { diff --git a/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php index dea995a7a5..50dd12c2cb 100644 --- a/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php +++ b/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -123,12 +123,12 @@ class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase $this->assertEquals($dateTime->format('d.m.Y H:i'), $transformer->transform($input)); } + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ public function testTransformRequiresValidDateTime() { $transformer = new DateTimeToLocalizedStringTransformer(); - - $this->setExpectedException('Symfony\Component\Form\Exception\UnexpectedTypeException'); - $transformer->transform('2010-01-01'); } @@ -225,35 +225,37 @@ class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase $this->assertSame(null, $transformer->reverseTransform('', null)); } + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ public function testReverseTransformRequiresString() { $transformer = new DateTimeToLocalizedStringTransformer(); - - $this->setExpectedException('Symfony\Component\Form\Exception\UnexpectedTypeException'); - $transformer->reverseTransform(12345, null); } + /** + * @expectedException Symfony\Component\Form\Exception\TransformationFailedException + */ public function testReverseTransformWrapsIntlErrors() { $transformer = new DateTimeToLocalizedStringTransformer(); - - $this->setExpectedException('Symfony\Component\Form\Exception\TransformationFailedException'); - $transformer->reverseTransform('12345', null); } + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ public function testValidateDateFormatOption() { - $this->setExpectedException('\InvalidArgumentException'); - new DateTimeToLocalizedStringTransformer(null, null, 'foobar'); } + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ public function testValidateTimeFormatOption() { - $this->setExpectedException('\InvalidArgumentException'); - new DateTimeToLocalizedStringTransformer(null, null, null, 'foobar'); } } diff --git a/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/FileToStringTransformerTest.php b/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/FileToStringTransformerTest.php new file mode 100644 index 0000000000..1a400c643c --- /dev/null +++ b/tests/Symfony/Tests/Component/Form/Extension/Core/DataTransformer/FileToStringTransformerTest.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Form\Extension\Core\DataTransformer; + +use Symfony\Component\Form\Extension\Core\DataTransformer\FileToStringTransformer; +use Symfony\Component\HttpFoundation\File\File; + +class FileToStringTransformerTest extends \PHPUnit_Framework_TestCase +{ + private $transformer; + + protected function setUp() + { + $this->transformer = new FileToStringTransformer(); + } + + public function testTransform() + { + $path = realpath(__DIR__.'/../../../Fixtures/foo'); + + $file = new File($path); + $t = $this->transformer->transform($file); + + $this->assertTrue(file_exists($path)); + $this->assertInternalType('string', $t); + $this->assertEquals($path, realpath($t)); + } + + /** + * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException + */ + public function testTransformRequiresAFile() + { + $this->transformer->transform(array()); + } + + public function testReverseTransform() + { + $path = realpath(__DIR__.'/../../../Fixtures/foo'); + + $file = new File($path); + $r = $this->transformer->reverseTransform($path); + + $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $file); + $this->assertEquals($path, realpath($r->getPath())); + + } + + /** + * @expectedException Symfony\Component\Form\Exception\TransformationFailedException + */ + public function testReverseTransformRequiresArray() + { + $t = $this->transformer->reverseTransform(__DIR__.'/../../../Fixtures/no-foo'); + } +} diff --git a/tests/Symfony/Tests/Component/Form/Fixtures/foo b/tests/Symfony/Tests/Component/Form/Fixtures/foo new file mode 100644 index 0000000000..e69de29bb2