[Form] Catch exceptions in DataTransformers
This commit is contained in:
parent
9cc7aacf76
commit
dac798c791
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* 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');
|
||||
}
|
||||
}
|
0
tests/Symfony/Tests/Component/Form/Fixtures/foo
Normal file
0
tests/Symfony/Tests/Component/Form/Fixtures/foo
Normal file
Reference in New Issue
Block a user