diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml index ae0be68d1e439..f9655322287af 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml @@ -38,7 +38,6 @@ - null diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_debug.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_debug.xml index d7e4803f5cf5d..8990f7c6cddc7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_debug.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form_debug.xml @@ -26,7 +26,6 @@ - false diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 9f5e6e23e7eba..8b3156de2dba1 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -13,6 +13,11 @@ CHANGELOG * removed the support for caching loaded choice lists in `LazyChoiceList`, cache the choice list in the used `ChoiceLoaderInterface` implementation instead + * removed the support for objects implementing both `\Traversable` and `\ArrayAccess` in `ResizeFormListener::preSubmit()` + * removed the ability to use `FormDataCollector` without the `symfony/var-dumper` component + * removed passing a `ValueExporter` instance to the `FormDataExtractor::__construct()` method + * removed passing guesser services ids as the fourth argument of `DependencyInjectionExtension::__construct()` + * removed the ability to validate an unsubmitted form. 3.3.0 ----- diff --git a/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php b/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php index c3218ae4ec1cf..3cab8ba0bd96f 100644 --- a/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php +++ b/src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php @@ -102,11 +102,7 @@ public function preSubmit(FormEvent $event) $form = $event->getForm(); $data = $event->getData(); - if ($data instanceof \Traversable && $data instanceof \ArrayAccess) { - @trigger_error('Support for objects implementing both \Traversable and \ArrayAccess is deprecated since version 3.1 and will be removed in 4.0. Use an array instead.', E_USER_DEPRECATED); - } - - if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) { + if (!is_array($data)) { $data = array(); } diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index b088abc7962f6..0362c856cb7e6 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -16,7 +16,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; -use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\VarDumper\Caster\Caster; use Symfony\Component\VarDumper\Caster\ClassStub; @@ -72,27 +71,23 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf */ private $formsByView; - /** - * @var ValueExporter - */ - private $valueExporter; - /** * @var ClonerInterface */ private $cloner; - private $hasVarDumper; - public function __construct(FormDataExtractorInterface $dataExtractor) { + if (!class_exists(ClassStub::class)) { + throw new \LogicException(sprintf('The VarDumper component is needed for using the %s class. Install symfony/var-dumper version 3.4 or above.', __CLASS__)); + } + $this->dataExtractor = $dataExtractor; $this->data = array( 'forms' => array(), 'forms_by_hash' => array(), 'nb_errors' => 0, ); - $this->hasVarDumper = class_exists(ClassStub::class); } /** @@ -241,11 +236,9 @@ public function getData() public function serialize() { - if ($this->hasVarDumper) { - foreach ($this->data['forms_by_hash'] as &$form) { - if (isset($form['type_class']) && !$form['type_class'] instanceof ClassStub) { - $form['type_class'] = new ClassStub($form['type_class']); - } + foreach ($this->data['forms_by_hash'] as &$form) { + if (isset($form['type_class']) && !$form['type_class'] instanceof ClassStub) { + $form['type_class'] = new ClassStub($form['type_class']); } } @@ -261,55 +254,43 @@ protected function cloneVar($var, $isClass = false) return $var; } if (null === $this->cloner) { - if ($this->hasVarDumper) { - $this->cloner = new VarCloner(); - $this->cloner->setMaxItems(-1); - $this->cloner->addCasters(array( - '*' => function ($v, array $a, Stub $s, $isNested) { - foreach ($a as &$v) { - if (is_object($v) && !$v instanceof \DateTimeInterface) { - $v = new CutStub($v); - } + $this->cloner = new VarCloner(); + $this->cloner->setMaxItems(-1); + $this->cloner->addCasters(array( + '*' => function ($v, array $a, Stub $s, $isNested) { + foreach ($a as &$v) { + if (is_object($v) && !$v instanceof \DateTimeInterface) { + $v = new CutStub($v); } - - return $a; - }, - \Exception::class => function (\Exception $e, array $a, Stub $s) { - if (isset($a[$k = "\0Exception\0previous"])) { - unset($a[$k]); - ++$s->cut; - } - - return $a; - }, - FormInterface::class => function (FormInterface $f, array $a) { - return array( - Caster::PREFIX_VIRTUAL.'name' => $f->getName(), - Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())), - ); - }, - ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) { - return array( - Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(), - Caster::PREFIX_VIRTUAL.'path' => $v->getPropertyPath(), - Caster::PREFIX_VIRTUAL.'value' => $v->getInvalidValue(), - ); - }, - )); - } else { - @trigger_error(sprintf('Using the %s() method without the VarDumper component is deprecated since version 3.2 and won\'t be supported in 4.0. Install symfony/var-dumper version 3.2 or above.', __METHOD__), E_USER_DEPRECATED); - $this->cloner = false; - } - } - if (false !== $this->cloner) { - return $this->cloner->cloneVar($var, Caster::EXCLUDE_VERBOSE); - } - - if (null === $this->valueExporter) { - $this->valueExporter = new ValueExporter(); + } + + return $a; + }, + \Exception::class => function (\Exception $e, array $a, Stub $s) { + if (isset($a[$k = "\0Exception\0previous"])) { + unset($a[$k]); + ++$s->cut; + } + + return $a; + }, + FormInterface::class => function (FormInterface $f, array $a) { + return array( + Caster::PREFIX_VIRTUAL.'name' => $f->getName(), + Caster::PREFIX_VIRTUAL.'type_class' => new ClassStub(get_class($f->getConfig()->getType()->getInnerType())), + ); + }, + ConstraintViolationInterface::class => function (ConstraintViolationInterface $v, array $a) { + return array( + Caster::PREFIX_VIRTUAL.'root' => $v->getRoot(), + Caster::PREFIX_VIRTUAL.'path' => $v->getPropertyPath(), + Caster::PREFIX_VIRTUAL.'value' => $v->getInvalidValue(), + ); + }, + )); } - return $this->valueExporter->exportValue($var); + return $this->cloner->cloneVar($var, Caster::EXCLUDE_VERBOSE); } private function &recursiveBuildPreliminaryFormTree(FormInterface $form, array &$outputByHash) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php index de6fac41231de..355f4d13577c7 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php @@ -13,7 +13,6 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; -use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; use Symfony\Component\Validator\ConstraintViolationInterface; /** @@ -23,16 +22,6 @@ */ class FormDataExtractor implements FormDataExtractorInterface { - /** - * Constructs a new data extractor. - */ - public function __construct(ValueExporter $valueExporter = null, $triggerDeprecationNotice = true) - { - if (null !== $valueExporter && $triggerDeprecationNotice) { - @trigger_error('Passing a ValueExporter instance to '.__METHOD__.'() is deprecated in version 3.2 and will be removed in 4.0.', E_USER_DEPRECATED); - } - } - /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Form/Extension/DependencyInjection/DependencyInjectionExtension.php b/src/Symfony/Component/Form/Extension/DependencyInjection/DependencyInjectionExtension.php index 59e7eb766e4b4..3315be895c1d4 100644 --- a/src/Symfony/Component/Form/Extension/DependencyInjection/DependencyInjectionExtension.php +++ b/src/Symfony/Component/Form/Extension/DependencyInjection/DependencyInjectionExtension.php @@ -24,10 +24,6 @@ class DependencyInjectionExtension implements FormExtensionInterface private $typeExtensionServices; private $guesserServices; - // @deprecated to be removed in Symfony 4.0 - private $typeServiceIds; - private $guesserServiceIds; - /** * Constructor. * @@ -35,16 +31,8 @@ class DependencyInjectionExtension implements FormExtensionInterface * @param iterable[] $typeExtensionServices * @param iterable $guesserServices */ - public function __construct(ContainerInterface $typeContainer, array $typeExtensionServices, $guesserServices, array $guesserServiceIds = null) + public function __construct(ContainerInterface $typeContainer, array $typeExtensionServices, $guesserServices) { - if (null !== $guesserServiceIds) { - @trigger_error(sprintf('Passing four arguments to the %s::__construct() method is deprecated since Symfony 3.3 and will be disallowed in Symfony 4.0. The new constructor only accepts three arguments.', __CLASS__), E_USER_DEPRECATED); - $this->guesserServiceIds = $guesserServiceIds; - $this->typeServiceIds = $typeExtensionServices; - $typeExtensionServices = $guesserServices; - $guesserServices = $guesserServiceIds; - } - $this->typeContainer = $typeContainer; $this->typeExtensionServices = $typeExtensionServices; $this->guesserServices = $guesserServices; @@ -52,14 +40,6 @@ public function __construct(ContainerInterface $typeContainer, array $typeExtens public function getType($name) { - if (null !== $this->guesserServiceIds) { - if (!isset($this->typeServiceIds[$name])) { - throw new InvalidArgumentException(sprintf('The field type "%s" is not registered in the service container.', $name)); - } - - return $this->typeContainer->get($this->typeServiceIds[$name]); - } - if (!$this->typeContainer->has($name)) { throw new InvalidArgumentException(sprintf('The field type "%s" is not registered in the service container.', $name)); } @@ -69,10 +49,6 @@ public function getType($name) public function hasType($name) { - if (null !== $this->guesserServiceIds) { - return isset($this->typeServiceIds[$name]); - } - return $this->typeContainer->has($name); } @@ -82,10 +58,6 @@ public function getTypeExtensions($name) if (isset($this->typeExtensionServices[$name])) { foreach ($this->typeExtensionServices[$name] as $serviceId => $extension) { - if (null !== $this->guesserServiceIds) { - $extension = $this->typeContainer->get($serviceId = $extension); - } - $extensions[] = $extension; // validate result of getExtendedType() to ensure it is consistent with the service definition @@ -116,10 +88,6 @@ public function getTypeGuesser() $guessers = array(); foreach ($this->guesserServices as $serviceId => $service) { - if (null !== $this->guesserServiceIds) { - $service = $this->typeContainer->get($serviceId = $service); - } - $guessers[] = $service; } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index cdbb0fe171824..57b0c5d20e63d 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -736,9 +736,7 @@ public function isEmpty() public function isValid() { if (!$this->submitted) { - @trigger_error('Call Form::isValid() with an unsubmitted form is deprecated since version 3.2 and will throw an exception in 4.0. Use Form::isSubmitted() before Form::isValid() instead.', E_USER_DEPRECATED); - - return false; + throw new LogicException('Cannot check if an unsubmitted form is valid. Call Form::isSubmitted() before Form::isValid().'); } if ($this->isDisabled()) { diff --git a/src/Symfony/Component/Form/Tests/Extension/DependencyInjection/DependencyInjectionExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/DependencyInjection/DependencyInjectionExtensionTest.php index 66a7bf07191d2..a94d57ec475a4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DependencyInjection/DependencyInjectionExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DependencyInjection/DependencyInjectionExtensionTest.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Form\Tests\Extension\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension; use Symfony\Component\Form\FormTypeGuesserChain; use Symfony\Component\Form\FormTypeGuesserInterface; @@ -59,61 +58,6 @@ public function testThrowExceptionForInvalidExtendedType() $extension->getTypeExtensions('test'); } - /** - * @group legacy - * @expectedDeprecation Passing four arguments to the Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension::__construct() method is deprecated since Symfony 3.3 and will be disallowed in Symfony 4.0. The new constructor only accepts three arguments. - */ - public function testLegacyGetTypeExtensions() - { - $container = $this->createContainerMock(); - - $services = array( - 'extension1' => $typeExtension1 = $this->createFormTypeExtensionMock('test'), - 'extension2' => $typeExtension2 = $this->createFormTypeExtensionMock('test'), - 'extension3' => $typeExtension3 = $this->createFormTypeExtensionMock('other'), - ); - - $container->expects($this->any()) - ->method('get') - ->willReturnCallback(function ($id) use ($services) { - if (isset($services[$id])) { - return $services[$id]; - } - - throw new ServiceNotFoundException($id); - }); - - $extension = new DependencyInjectionExtension($container, array(), array('test' => array('extension1', 'extension2'), 'other' => array('extension3')), array()); - - $this->assertTrue($extension->hasTypeExtensions('test')); - $this->assertFalse($extension->hasTypeExtensions('unknown')); - $this->assertSame(array($typeExtension1, $typeExtension2), $extension->getTypeExtensions('test')); - } - - /** - * @group legacy - * @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException - * @expectedDeprecation Passing four arguments to the Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension::__construct() method is deprecated since Symfony 3.3 and will be disallowed in Symfony 4.0. The new constructor only accepts three arguments. - */ - public function testLegacyThrowExceptionForInvalidExtendedType() - { - $formTypeExtension = $this->createFormTypeExtensionMock('unmatched'); - - $container = $this->createContainerMock(); - - $container->expects($this->any()) - ->method('get') - ->with('extension') - ->willReturn($formTypeExtension); - - $extension = new DependencyInjectionExtension($container, array(), array('test' => array('extension')), array()); - - $extensions = $extension->getTypeExtensions('test'); - - $this->assertCount(1, $extensions); - $this->assertSame($formTypeExtension, $extensions[0]); - } - public function testGetTypeGuesser() { $container = $this->createContainerMock(); @@ -130,33 +74,6 @@ public function testGetTypeGuesserReturnsNullWhenNoTypeGuessersHaveBeenConfigure $this->assertNull($extension->getTypeGuesser()); } - /** - * @group legacy - */ - public function testLegacyGetTypeGuesser() - { - $container = $this->createContainerMock(); - $container - ->expects($this->once()) - ->method('get') - ->with('foo') - ->willReturn($this->getMockBuilder(FormTypeGuesserInterface::class)->getMock()); - $extension = new DependencyInjectionExtension($container, array(), array(), array('foo')); - - $this->assertInstanceOf(FormTypeGuesserChain::class, $extension->getTypeGuesser()); - } - - /** - * @group legacy - */ - public function testLegacyGetTypeGuesserReturnsNullWhenNoTypeGuessersHaveBeenConfigured() - { - $container = $this->createContainerMock(); - $extension = new DependencyInjectionExtension($container, array(), array(), array()); - - $this->assertNull($extension->getTypeGuesser()); - } - private function createContainerMock() { return $this->getMockBuilder('Psr\Container\ContainerInterface') diff --git a/src/Symfony/Component/Form/Tests/SimpleFormTest.php b/src/Symfony/Component/Form/Tests/SimpleFormTest.php index a938a176ccd92..36caf2d15b9f8 100644 --- a/src/Symfony/Component/Form/Tests/SimpleFormTest.php +++ b/src/Symfony/Component/Form/Tests/SimpleFormTest.php @@ -313,15 +313,6 @@ public function testValidIfSubmittedAndDisabled() $this->assertTrue($form->isValid()); } - /** - * @group legacy - * @expectedDeprecation Call Form::isValid() with an unsubmitted form %s. - */ - public function testNotValidIfNotSubmitted() - { - $this->assertFalse($this->form->isValid()); - } - public function testNotValidIfErrors() { $form = $this->getBuilder()->getForm(); diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php index 77c72f9562e75..a49686694daa8 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php @@ -57,7 +57,7 @@ protected function cloneVar($var) { if (null === self::$cloner) { if (!class_exists(ClassStub::class)) { - throw new \LogicException(sprintf('The VarDumper component is needed for the %s() method. Install symfony/var-dumper version 3.2 or above.', __METHOD__)); + throw new \LogicException(sprintf('The VarDumper component is needed for the %s() method. Install symfony/var-dumper version 3.4 or above.', __METHOD__)); } self::$cloner = new VarCloner();