Browse Source

Deprecate ModelsToArrayTransformer::$choiceList (#4284)

The constructor was modified to simulate a new signature with 2 arguments,
and keep the old 3 arguments signature
Updated call to `ModelsToArrayTransformer::__construct()` in `ModelType`
to use new signature.
Romain Sanchez 8 years ago
parent
commit
a7e8d10cd8

+ 98 - 9
Form/DataTransformer/ModelsToArrayTransformer.php

@@ -39,6 +39,9 @@ class ModelsToArrayTransformer implements DataTransformerInterface
 
     /**
      * @var ModelChoiceList
+     *
+     * @deprecated since 3.x, to be removed in 4.0
+     * NEXT_MAJOR: remove this property
      */
     protected $choiceList;
 
@@ -51,18 +54,69 @@ class ModelsToArrayTransformer implements DataTransformerInterface
      *
      * @throws RuntimeException
      */
-    public function __construct($choiceList, ModelManagerInterface $modelManager, $class)
+    public function __construct($choiceList, $modelManager, $class = null)
     {
-        if (!$choiceList instanceof ModelChoiceList
-            && !$choiceList instanceof ModelChoiceLoader
-            && !$choiceList instanceof LazyChoiceList) {
-            throw new RuntimeException('First param passed to ModelsToArrayTransformer should be instance of
-                ModelChoiceLoader or ModelChoiceList or LazyChoiceList');
+        /*
+        NEXT_MAJOR: Remove condition , magic methods, legacyConstructor() method, $choiceList property and argument
+        __construct() signature should be : public function __construct(ModelManager $modelManager, $class)
+         */
+
+        $args = func_get_args();
+
+        if (func_num_args() == 3) {
+            $this->legacyConstructor($args);
+        } else {
+            $this->modelManager = $args[0];
+            $this->class = $args[1];
+        }
+    }
+
+    /**
+     * @internal
+     */
+    public function __get($name)
+    {
+        if ('choiceList' === $name) {
+            $this->triggerDeprecation();
         }
 
-        $this->choiceList = $choiceList;
-        $this->modelManager = $modelManager;
-        $this->class = $class;
+        return $this->$name;
+    }
+
+    /**
+     * @internal
+     */
+    public function __set($name, $value)
+    {
+        if ('choiceList' === $name) {
+            $this->triggerDeprecation();
+        }
+
+        $this->$name = $value;
+    }
+
+    /**
+     * @internal
+     */
+    public function __isset($name)
+    {
+        if ('choiceList' === $name) {
+            $this->triggerDeprecation();
+        }
+
+        return isset($this->$name);
+    }
+
+    /**
+     * @internal
+     */
+    public function __unset($name)
+    {
+        if ('choiceList' === $name) {
+            $this->triggerDeprecation();
+        }
+
+        unset($this->$name);
     }
 
     /**
@@ -112,6 +166,29 @@ class ModelsToArrayTransformer implements DataTransformerInterface
         return $collection;
     }
 
+    /**
+     * Simulates the old constructor for BC.
+     *
+     * @param array $args
+     *
+     * @throws RuntimeException
+     */
+    private function legacyConstructor($args)
+    {
+        $choiceList = $args[0];
+
+        if (!$choiceList instanceof ModelChoiceList
+            && !$choiceList instanceof ModelChoiceLoader
+            && !$choiceList instanceof LazyChoiceList) {
+            throw new RuntimeException('First param passed to ModelsToArrayTransformer should be instance of
+                ModelChoiceLoader or ModelChoiceList or LazyChoiceList');
+        }
+
+        $this->choiceList = $choiceList;
+        $this->modelManager = $args[1];
+        $this->class = $args[2];
+    }
+
     /**
      * @param object $entity
      *
@@ -125,4 +202,16 @@ class ModelsToArrayTransformer implements DataTransformerInterface
             throw new \InvalidArgumentException(sprintf('Unable to retrieve the identifier values for entity %s', ClassUtils::getClass($entity)), 0, $e);
         }
     }
+
+    /**
+     * @internal
+     */
+    private function triggerDeprecation()
+    {
+        @trigger_error(sprintf(
+                'Using the "%s::$choiceList" property is deprecated since version 3.x and will be removed in 4.0.',
+                __CLASS__),
+            E_USER_DEPRECATED)
+        ;
+    }
 }

+ 0 - 1
Form/Type/ModelType.php

@@ -51,7 +51,6 @@ class ModelType extends AbstractType
         if ($options['multiple']) {
             if (array_key_exists('choice_loader', $options) && $options['choice_loader'] !== null) { // SF2.7+
                 $builder->addViewTransformer(new ModelsToArrayTransformer(
-                    $options['choice_loader'],
                     $options['model_manager'],
                     $options['class']), true);
             } else {

+ 55 - 0
Tests/Form/DataTransformer/ModelsToArrayTransformerTest.php

@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Sonata Project package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Tests\Form\DataTransformer;
+
+use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
+
+class ModelsToArrayTransformerTest extends \PHPUnit_Framework_TestCase
+{
+    private $modelManager;
+
+    protected function setUp()
+    {
+        $this->modelManager = $this->prophesize('Sonata\AdminBundle\Model\ModelManagerInterface')->reveal();
+    }
+
+    public function testConstructor()
+    {
+        $transformer = new ModelsToArrayTransformer(
+            $this->modelManager,
+            'Sonata\AdminBundle\Tests\Fixtures\Entity\Foo'
+        );
+
+        $this->assertInstanceOf('Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer', $transformer);
+    }
+
+    /**
+     * @group legacy
+     */
+    public function testLegacyConstructor()
+    {
+        $choiceListClass = interface_exists('Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface')
+            ? 'Sonata\AdminBundle\Form\ChoiceList\ModelChoiceLoader'
+            : 'Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList'
+        ;
+
+        $choiceList = $this->prophesize($choiceListClass)->reveal();
+
+        $transformer = new ModelsToArrayTransformer(
+            $choiceList,
+            $this->modelManager,
+            'Sonata\AdminBundle\Tests\Fixtures\Entity\Foo'
+        );
+
+        $this->assertInstanceOf('Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer', $transformer);
+    }
+}

+ 4 - 0
UPGRADE-3.x.md

@@ -1,6 +1,10 @@
 UPGRADE 3.x
 ===========
 
+## Deprecated ModelsToArrayTransformer::$choiceList property
+
+When instantiating a ModelsToArrayTransformer object, please use the 2 parameter signature ($modelManager, $class).
+
 ## Deprecated Sonata\AdminBundle\Controller\CoreController::getRequest()
 
 Inject `Symfony\Component\HttpFoundation\Request` in your actions directly as an argument.