Browse Source

Fix "many" parent append

Emmanuel Vella 11 years ago
parent
commit
de6f89eda9

+ 8 - 1
Admin/Admin.php

@@ -844,7 +844,14 @@ abstract class Admin implements AdminInterface, DomainObjectInterface
 
             $object = $this->getSubject();
 
-            $propertyAccessor->setValue($object, $propertyPath, $parent);
+            $value = $propertyAccessor->getValue($object, $propertyPath);
+
+            if (is_array($value) || ($value instanceof \Traversable && $value instanceof \ArrayAccess)) {
+                $value[] = $parent;
+                $propertyAccessor->setValue($object, $propertyPath, $value);
+            } else {
+                $propertyAccessor->setValue($object, $propertyPath, $parent);
+            }
         }
 
         $this->form = $this->getFormBuilder()->getForm();

+ 76 - 0
Tests/Admin/AdminTest.php

@@ -12,6 +12,8 @@
 namespace Sonata\AdminBundle\Tests\Admin;
 
 use Sonata\AdminBundle\Admin\Admin;
+use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Post;
+use Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Tag;
 use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
 use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToStringNull;
 use Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin;
@@ -1063,4 +1065,78 @@ class AdminTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($expected, $admin->getPersistentParameters());
     }
+
+    public function testGetFormWithNonCollectionParentValue()
+    {
+        $post = new Post();
+        $tagAdmin = $this->createTagAdmin($post);
+        $tag = $tagAdmin->getSubject();
+
+        $tag->setPosts(null);
+        $tagAdmin->getForm();
+        $this->assertSame($post, $tag->getPosts());
+    }
+
+    public function testGetFormWithCollectionParentValue()
+    {
+        $post = new Post();
+        $tagAdmin = $this->createTagAdmin($post);
+        $tag = $tagAdmin->getSubject();
+
+        // Case of a doctrine collection
+        $this->assertInstanceOf('Doctrine\Common\Collections\Collection', $tag->getPosts());
+        $this->assertCount(0, $tag->getPosts());
+
+        $tag->addPost(new Post());
+
+        $this->assertCount(1, $tag->getPosts());
+
+        $tagAdmin->getForm();
+
+        $this->assertInstanceOf('Doctrine\Common\Collections\Collection', $tag->getPosts());
+        $this->assertCount(2, $tag->getPosts());
+        $this->assertContains($post, $tag->getPosts());
+
+        // Case of an array
+        $tag->setPosts(array());
+        $this->assertCount(0, $tag->getPosts());
+
+        $tag->addPost(new Post());
+
+        $this->assertCount(1, $tag->getPosts());
+
+        $tagAdmin->getForm();
+
+        $this->assertInternalType('array', $tag->getPosts());
+        $this->assertCount(2, $tag->getPosts());
+        $this->assertContains($post, $tag->getPosts());
+    }
+
+    private function createTagAdmin(Post $post)
+    {
+        $postAdmin = $this->getMockBuilder('Sonata\AdminBundle\Tests\Fixtures\Admin\PostAdmin')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $postAdmin->expects($this->any())->method('getObject')->will($this->returnValue($post));
+
+        $formBuilder = $this->getMockForAbstractClass('Sonata\AdminBundle\Tests\Form\Builder\FormBuilder');
+        $formBuilder->expects($this->any())->method('getForm')->will($this->returnValue(null));
+
+        $tagAdmin = $this->getMockBuilder('Sonata\AdminBundle\Tests\Fixtures\Admin\TagAdmin')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getFormBuilder'))
+            ->getMock();
+
+        $tagAdmin->expects($this->any())->method('getFormBuilder')->will($this->returnValue($formBuilder));
+        $tagAdmin->setParent($postAdmin);
+
+        $tag = new Tag();
+        $tagAdmin->setSubject($tag);
+
+        $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+        $tagAdmin->setRequest($request);
+
+        return $tagAdmin;
+    }
 }

+ 16 - 0
Tests/Fixtures/Admin/TagAdmin.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace Sonata\AdminBundle\Tests\Fixtures\Admin;
+
+use Sonata\AdminBundle\Admin\Admin;
+
+class TagAdmin extends Admin
+{
+    public function getParentAssociationMapping()
+    {
+        if ($this->getParent() instanceof PostAdmin) {
+            return 'posts';
+        }
+    }
+}
+

+ 37 - 0
Tests/Fixtures/Bundle/Entity/Post.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity;
+
+use Doctrine\Common\Collections\ArrayCollection;
+
+class Post
+{
+    private $tags;
+
+    public function __construct()
+    {
+        $this->tags = new ArrayCollection();
+    }
+
+    public function setTags($tags)
+    {
+        $this->tags = $tags;
+    }
+
+    public function getTags()
+    {
+        return $this->tags;
+    }
+
+    public  function addTag(Tag $tag)
+    {
+        $tag->addPost($this);
+        $this->tags[] = ($tag);
+    }
+
+    public function removePost(Tag $tag)
+    {
+        $tag->removePost($this);
+        $this->tags->removeElement($tag);
+    }
+}

+ 35 - 0
Tests/Fixtures/Bundle/Entity/Tag.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity;
+
+use Doctrine\Common\Collections\ArrayCollection;
+
+class Tag
+{
+    private $posts;
+
+    public function __construct()
+    {
+        $this->posts = new ArrayCollection();
+    }
+
+    public function setPosts($posts)
+    {
+        $this->posts = $posts;
+    }
+
+    public function getPosts()
+    {
+        return $this->posts;
+    }
+
+    public  function addPost(Post $post)
+    {
+        $this->posts[] = $post;
+    }
+
+    public function removePost(Post $post)
+    {
+        $this->posts->removeElement($post);
+    }
+}

+ 25 - 0
Tests/Form/Builder/FormBuilder.php

@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Sonata 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\Builder;
+
+use Symfony\Component\Form\Test\FormBuilderInterface;
+
+/**
+ * Class FormBuilder
+ *
+ * Used to avoid an issue when to mocking FormBuilderInterface directly
+ *
+ * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
+ */
+abstract class FormBuilder implements FormBuilderInterface
+{
+}