Ver código fonte

Add an orm independant MergeCollectionListener

Thomas Rabaix 14 anos atrás
pai
commit
b8a7ae58ce

+ 0 - 1
Datagrid/Datagrid.php

@@ -54,7 +54,6 @@ class Datagrid implements DatagridInterface
         return $this->pager;
         return $this->pager;
     }
     }
 
 
-
     public function getResults()
     public function getResults()
     {
     {
         $this->buildPager();
         $this->buildPager();

+ 61 - 0
Form/EventListener/MergeCollectionListener.php

@@ -0,0 +1,61 @@
+<?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\Form\EventListener;
+
+use Symfony\Component\Form\Events;
+use Symfony\Component\Form\Event\FilterDataEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+use Sonata\AdminBundle\Model\ModelManagerInterface;
+
+class MergeCollectionListener implements EventSubscriberInterface
+{
+    protected $modelManager;
+
+    public function __construct(ModelManagerInterface $modelManager)
+    {
+        $this->modelManager = $modelManager;
+    }
+
+    public static function getSubscribedEvents()
+    {
+        return Events::onBindNormData;
+    }
+
+    public function onBindNormData(FilterDataEvent $event)
+    {
+        $collection = $event->getForm()->getData();
+        $data = $event->getData();
+
+        if (!$collection) {
+            $collection = $data;
+        } else if (count($data) === 0) {
+            $this->modelManager->collectionClear($collection);
+        } else {
+            // merge $data into $collection
+            foreach ($collection as $entity) {
+                if (!$this->modelManager->collectionHasElement($data, $entity)) {
+                    $this->modelManager->collectionRemoveElement($collection, $entity);
+                } else {
+                    $this->modelManager->collectionRemoveElement($data, $entity);
+                }
+            }
+
+            foreach ($data as $entity) {
+                $this->modelManager->collectionAddElement($collection, $entity);
+            }
+        }
+
+        $event->setData($collection);
+    }
+}

+ 2 - 3
Form/Type/ModelType.php

@@ -14,9 +14,9 @@ namespace Sonata\AdminBundle\Form\Type;
 
 
 use Symfony\Component\Form\FormBuilder;
 use Symfony\Component\Form\FormBuilder;
 use Symfony\Component\Form\FormFactoryInterface;
 use Symfony\Component\Form\FormFactoryInterface;
-use Symfony\Bridge\Doctrine\Form\EventListener\MergeCollectionListener;
 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\AbstractType;
 
 
+use Sonata\AdminBundle\Form\EventListener\MergeCollectionListener;
 use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList;
 use Sonata\AdminBundle\Form\ChoiceList\ModelChoiceList;
 use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
 use Sonata\AdminBundle\Form\DataTransformer\ModelsToArrayTransformer;
 use Sonata\AdminBundle\Form\DataTransformer\ModelToIdTransformer;
 use Sonata\AdminBundle\Form\DataTransformer\ModelToIdTransformer;
@@ -35,9 +35,8 @@ class ModelType extends AbstractType
     {
     {
         if ($options['multiple']) {
         if ($options['multiple']) {
             $builder
             $builder
-                ->addEventSubscriber(new MergeCollectionListener())
+                ->addEventSubscriber(new MergeCollectionListener($this->modelManager))
                 ->prependClientTransformer(new ModelsToArrayTransformer($options['choice_list']));
                 ->prependClientTransformer(new ModelsToArrayTransformer($options['choice_list']));
-
         } else {
         } else {
             $builder->prependClientTransformer(new ModelToIdTransformer($this->modelManager, $options['class']));
             $builder->prependClientTransformer(new ModelToIdTransformer($this->modelManager, $options['class']));
         }
         }

+ 36 - 0
Model/ModelManagerInterface.php

@@ -133,6 +133,42 @@ interface ModelManagerInterface
      */
      */
     function getModelCollectionInstance($class);
     function getModelCollectionInstance($class);
 
 
+    /**
+     * Removes an element from the collection
+     *
+     * @param mixed $collection
+     * @param mixed $element
+     * @return void
+     */
+    function collectionRemoveElement(&$collection, &$element);
+
+    /**
+     * Add an element from the collection
+     *
+     * @param mixed $collection
+     * @param mixed $element
+     * @return mixed
+     */
+    function collectionAddElement(&$collection, &$element);
+
+    /**
+     * Check if the element exists in the collection
+     *
+     * @param mixed $collection
+     * @param mixed $element
+     * @return boolean
+     */
+    function collectionHasElement(&$collection, &$element);
+
+    /**
+     * Clear the collection
+     *
+     * @param mixed $collection
+     * @param mixed $element
+     * @return mixed
+     */
+    function collectionClear(&$collection);
+
     /**
     /**
      * Returns the parameters used in the columns header
      * Returns the parameters used in the columns header
      *
      *

+ 20 - 0
Model/ORM/ModelManager.php

@@ -328,4 +328,24 @@ class ModelManager implements ModelManagerInterface
     {
     {
         return new \Doctrine\Common\Collections\ArrayCollection();
         return new \Doctrine\Common\Collections\ArrayCollection();
     }
     }
+
+    function collectionClear(&$collection)
+    {
+        return $collection->clear();
+    }
+
+    function collectionHasElement(&$collection, &$element)
+    {
+        return $collection->contains($element);
+    }
+
+    function collectionAddElement(&$collection, &$element)
+    {
+        return $collection->add($element);
+    }
+
+    function collectionRemoveElement(&$collection, &$element)
+    {
+        return $collection->removeElement($element);
+    }
 }
 }