浏览代码

[DoctrineBundle][Form] Implemented EntityFieldFactoryGuesser

Bernhard Schussek 14 年之前
父节点
当前提交
3bf9f7782d

+ 8 - 0
src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml

@@ -45,6 +45,9 @@
 
         <!-- cache warmer -->
         <parameter key="doctrine.orm.proxy_cache_warmer.class">Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer</parameter>
+        
+        <!-- form field factory guesser -->
+        <parameter key="form.field_factory.doctrine_guesser.class">Symfony\Component\Form\Extension\Doctrine\EntityFieldFactoryGuesser</parameter>
     </parameters>
 
     <services>
@@ -62,5 +65,10 @@
             <tag name="kernel.cache_warmer" />
             <argument type="service" id="service_container" />
         </service>
+        
+        <service id="form.field_factory.doctrine_guesser" class="%form.field_factory.doctrine_guesser.class%" public="false">
+        	<tag name="form.field_factory.guesser" />
+            <argument type="service" id="doctrine.orm.default_entity_manager" />
+        </service>
     </services>
 </container>

+ 194 - 0
src/Symfony/Component/Form/Extension/Doctrine/EntityFieldFactoryGuesser.php

@@ -0,0 +1,194 @@
+<?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\Component\Form\Extension\Doctrine;
+
+use Symfony\Component\Form\FieldFactory\FieldFactoryGuesserInterface;
+use Symfony\Component\Form\FieldFactory\FieldFactoryGuess;
+use Symfony\Component\Form\FieldFactory\FieldFactoryClassGuess;
+use Doctrine\ORM\EntityManager;
+
+/**
+ * Guesses form fields from the metadata of Doctrine 2
+ *
+ * @author Bernhard Schussek <bernhard.schussek@symfony-project.com>
+ */
+class EntityFieldFactoryGuesser implements FieldFactoryGuesserInterface
+{
+    /**
+     * The Doctrine 2 entity manager
+     * @var Doctrine\ORM\EntityManager
+     */
+    protected $em = null;
+
+    /**
+     * Constructor
+     *
+     * @param ClassMetadataFactoryInterface $metadataFactory
+     */
+    public function __construct(EntityManager $em)
+    {
+        $this->em = $em;
+    }
+
+    /**
+	 * Returns whether Doctrine 2 metadata exists for that class
+	 *
+	 * @return boolean
+     */
+    protected function isMappedClass($class)
+    {
+        return !$this->em->getConfiguration()->getMetadataDriverImpl()->isTransient($class);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function guessClass($object, $property)
+    {
+        $className = get_class($object);
+
+        if ($this->isMappedClass($className)) {
+            $metadata = $this->em->getClassMetadata($className);
+
+            if ($metadata->hasAssociation($property)) {
+                $multiple = $metadata->isCollectionValuedAssociation($property);
+                $mapping = $metadata->getAssociationMapping($property);
+
+                return new FieldFactoryClassGuess(
+                	'Symfony\Component\Form\Extension\Doctrine\EntityChoiceField',
+                    array(
+                        'em' => $this->em,
+                        'class' => $mapping['targetEntity'],
+                        'multiple' => $multiple,
+                    ),
+                    FieldFactoryGuess::HIGH_CONFIDENCE
+                );
+            } else {
+                switch ($metadata->getTypeOfField($property))
+                {
+        //            case 'array':
+        //                return new FieldFactoryClassGuess(
+        //                	'Symfony\Component\Form\CollectionField',
+        //                    array(),
+        //                    FieldFactoryGuess::HIGH_CONFIDENCE
+        //                );
+                    case 'boolean':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\CheckboxField',
+                            array(),
+                            FieldFactoryGuess::HIGH_CONFIDENCE
+                        );
+                    case 'datetime':
+                    case 'vardatetime':
+                    case 'datetimetz':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\DateTimeField',
+                            array(),
+                            FieldFactoryGuess::HIGH_CONFIDENCE
+                        );
+                    case 'date':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\DateField',
+                            array(),
+                            FieldFactoryGuess::HIGH_CONFIDENCE
+                        );
+                    case 'decimal':
+                    case 'float':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\NumberField',
+                            array(),
+                            FieldFactoryGuess::MEDIUM_CONFIDENCE
+                        );
+                    case 'integer':
+                    case 'bigint':
+                    case 'smallint':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\IntegerField',
+                            array(),
+                            FieldFactoryGuess::MEDIUM_CONFIDENCE
+                        );
+                    case 'string':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\TextField',
+                            array(),
+                            FieldFactoryGuess::MEDIUM_CONFIDENCE
+                        );
+                    case 'text':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\TextareaField',
+                            array(),
+                            FieldFactoryGuess::MEDIUM_CONFIDENCE
+                        );
+                    case 'time':
+                        return new FieldFactoryClassGuess(
+                        	'Symfony\Component\Form\TimeField',
+                            array(),
+                            FieldFactoryGuess::HIGH_CONFIDENCE
+                        );
+    //                case 'object': ???
+                }
+            }
+        }
+
+        return new FieldFactoryClassGuess(
+        	'Symfony\Component\Form\TextField',
+            array(),
+            FieldFactoryGuess::LOW_CONFIDENCE
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function guessRequired($object, $property)
+    {
+        if ($this->isMappedClass(get_class($object))) {
+            $metadata = $this->em->getClassMetadata(get_class($object));
+
+            if ($metadata->hasField($property)) {
+                if (!$metadata->isNullable($property)) {
+                    return new FieldFactoryGuess(
+                        true,
+                        FieldFactoryGuess::HIGH_CONFIDENCE
+                    );
+                }
+
+                return new FieldFactoryGuess(
+                    false,
+                    FieldFactoryGuess::MEDIUM_CONFIDENCE
+                );
+            }
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function guessMaxLength($object, $property)
+    {
+        if ($this->isMappedClass(get_class($object))) {
+            $metadata = $this->em->getClassMetadata(get_class($object));
+
+            if (!$metadata->hasAssociation($property)) {
+                $mapping = $metadata->getFieldMapping($property);
+
+
+                if (isset($mapping['length'])) {
+                    return new FieldFactoryGuess(
+                        $mapping['length'],
+                        FieldFactoryGuess::HIGH_CONFIDENCE
+                    );
+                }
+            }
+        }
+    }
+}