Explorar el Código

clean form generate code

Thomas hace 14 años
padre
commit
74067d0d61
Se han modificado 3 ficheros con 141 adiciones y 130 borrados
  1. 26 3
      Admin/Admin.php
  2. 113 125
      Admin/EntityAdmin.php
  3. 2 2
      Admin/FieldDescription.php

+ 26 - 3
Admin/Admin.php

@@ -64,6 +64,29 @@ abstract class Admin extends ContainerAware
         'urls'        => false,
     );
 
+    /**
+     * todo: put this in the DIC
+     *
+     * @var array
+     */
+    protected $formFieldClasses = array(
+        'string'     =>  'Symfony\\Component\\Form\\TextField',
+        'text'       =>  'Symfony\\Component\\Form\\TextareaField',
+        'boolean'    =>  'Symfony\\Component\\Form\\CheckboxField',
+        'integer'    =>  'Symfony\\Component\\Form\\IntegerField',
+        'tinyint'    =>  'Symfony\\Component\\Form\\IntegerField',
+        'smallint'   =>  'Symfony\\Component\\Form\\IntegerField',
+        'mediumint'  =>  'Symfony\\Component\\Form\\IntegerField',
+        'bigint'     =>  'Symfony\\Component\\Form\\IntegerField',
+        'decimal'    =>  'Symfony\\Component\\Form\\NumberField',
+        'datetime'   =>  'Symfony\\Component\\Form\\DateTimeField',
+        'date'       =>  'Symfony\\Component\\Form\\DateField',
+        'choice'     =>  'Symfony\\Component\\Form\\ChoiceField',
+        'array'      =>  'Symfony\\Component\\Form\\FieldGroup',
+    );
+
+    protected $choicesCache = array();
+
     /**
      * return the entity manager
      *
@@ -77,16 +100,16 @@ abstract class Admin extends ContainerAware
      * @throws RuntimeException
      * @return
      */
-    abstract public function buildFormFields();
+    abstract protected function buildFormFields();
 
     /**
      * build the field to use in the list view
      *
      * @return void
      */
-    abstract public function buildListFields();
+    abstract protected function buildListFields();
 
-    abstract public function getChoices(FieldDescription $description);
+    abstract protected function getChoices(FieldDescription $description);
 
     abstract public function getForm($object, $fields);
 

+ 113 - 125
Admin/EntityAdmin.php

@@ -20,8 +20,6 @@ use Bundle\Sonata\BaseApplicationBundle\Tool\Datagrid;
 
 abstract class EntityAdmin extends Admin
 {
-
-    protected $choices_cache = array();
     
     /**
      * make sure the base fields are set in the correct format
@@ -95,7 +93,7 @@ abstract class EntityAdmin extends Admin
      * @throws RuntimeException
      * @return
      */
-    public function buildFormFields()
+    protected function buildFormFields()
     {
 
         if ($this->loaded['form_fields']) {
@@ -171,7 +169,7 @@ abstract class EntityAdmin extends Admin
      *
      * @return void
      */
-    public function buildListFields()
+    protected function buildListFields()
     {
 
         if ($this->loaded['list_fields']) {
@@ -242,10 +240,10 @@ abstract class EntityAdmin extends Admin
      * @param FieldDescription $description
      * @return array
      */
-    public function getChoices(FieldDescription $description)
+    protected function getChoices(FieldDescription $description)
     {
 
-        if (!isset($this->choices_cache[$description->getTargetEntity()])) {
+        if (!isset($this->choicesCache[$description->getTargetEntity()])) {
             $targets = $this->getEntityManager()
                 ->createQueryBuilder()
                 ->select('t')
@@ -264,10 +262,10 @@ abstract class EntityAdmin extends Admin
                 }
             }
 
-            $this->choices_cache[$description->getTargetEntity()] = $choices;
+            $this->choicesCache[$description->getTargetEntity()] = $choices;
         }
 
-        return $this->choices_cache[$description->getTargetEntity()];
+        return $this->choicesCache[$description->getTargetEntity()];
     }
 
     /**
@@ -327,34 +325,30 @@ abstract class EntityAdmin extends Admin
         return $field;
     }
 
+
     /**
-     * return an OneToOne associated field
+     * return the class associated to a FieldDescription
      *
-     * @param  $object
+     * @throws RuntimeException
      * @param FieldDescription $fieldDescription
-     * @return ChoiceField
+     * @return bool
      */
-    protected function getOneToOneField($object, FieldDescription $fieldDescription)
+    public function getFormFieldClass(FieldDescription $fieldDescription)
     {
-        
-        if ($fieldDescription->getOption('edit') == 'inline') {
-            return $this->getRelatedAssociatedField($object, $fieldDescription);
-        }
 
-        $fieldName = $fieldDescription->getFieldName();
+        $class = isset($this->formFieldClasses[$fieldDescription->getType()]) ? $this->formFieldClasses[$fieldDescription->getType()] : false;
 
-        $transformer = new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\EntityToIDTransformer(array(
-            'em'        => $this->getEntityManager(),
-            'className' => $fieldDescription->getTargetEntity()
-        ));
+        $class = $fieldDescription->getOption('form_field_widget', $class);
+
+        if(!$class) {
+            throw new \RuntimeException(sprintf('unknow type `%s`', $fieldDescription->getType()));
+        }
 
-        $field = new \Symfony\Component\Form\ChoiceField($fieldName, array_merge(array(
-            'expanded' => false,
-            'choices' => $this->getChoices($fieldDescription),
-            'value_transformer' => $transformer,
-        ), $fieldDescription->getOption('form_field_options', array())));
+        if(!class_exists($class)) {
+            throw new \RuntimeException(sprintf('The class `%s` does not exist for field `%s`', $class, $fieldDescription->getType()));
+        }
 
-        return $field;
+        return $class;
     }
 
     /**
@@ -374,6 +368,43 @@ abstract class EntityAdmin extends Admin
         $object->$method($instance);
     }
 
+    /**
+     * return an OneToOne associated field
+     *
+     * @param  $object
+     * @param FieldDescription $fieldDescription
+     * @return ChoiceField
+     */
+    protected function getOneToOneField($object, FieldDescription $fieldDescription)
+    {
+        
+        if ($fieldDescription->getOption('edit') == 'inline') {
+            return $this->getRelatedAssociatedField($object, $fieldDescription);
+        }
+
+        $options = array(
+            'value_transformer' => new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\EntityToIDTransformer(array(
+                'em'        =>  $this->getEntityManager(),
+                'className' => $fieldDescription->getTargetEntity()
+            ))
+        );
+
+        $options = array_merge($options, $fieldDescription->getOption('form_field_options', array()));
+
+        $class = $fieldDescription->getOption('form_field_widget', 'Symfony\\Component\\Form\\ChoiceField');
+
+        // set valid default value
+        if ($class == 'Symfony\\Component\\Form\\ChoiceField') {
+
+            $options = array_merge(array(
+                'expanded' => false,
+                'choices' => $this->getChoices($fieldDescription),
+             ), $options);
+        }
+
+        return new $class($fieldDescription->getFieldName(), $options);
+    }
+
     /**
      * return the OneToMany associated field
      *
@@ -383,7 +414,6 @@ abstract class EntityAdmin extends Admin
      */
     protected function getOneToManyField($object, FieldDescription $fieldDescription)
     {
-        $fieldName = $fieldDescription->getFieldName();
 
         if ($fieldDescription->getOption('edit') == 'inline') {
             $prototype = $this->getRelatedAssociatedField($object, $fieldDescription);
@@ -400,129 +430,87 @@ abstract class EntityAdmin extends Admin
             }
 
             // use custom one to expose the newfield method
-            return new  \Bundle\Sonata\BaseApplicationBundle\Form\EditableCollectionField($prototype);
+            return new \Bundle\Sonata\BaseApplicationBundle\Form\EditableCollectionField($prototype);
         }
 
-        $transformer = new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\CollectionToChoiceTransformer(array(
-            'em'        =>  $this->getEntityManager(),
-            'className' => $fieldDescription->getTargetEntity()
-        ));
-
-        $field = new \Symfony\Component\Form\ChoiceField($fieldName, array_merge(array(
-            'expanded' => true,
-            'multiple' => true,
-            'choices' => $this->getChoices($fieldDescription),
-            'value_transformer' => $transformer,
-        ), $fieldDescription->getOption('form_field_options', array())));
-
-        return $field;
+        return $this->getManyToManyField($object, $fieldDescription);
     }
 
-    /**
-     * return a form depend on the given $object and FieldDescription $fields array
-     *
-     * @throws RuntimeException
-     * @param  $object
-     * @param  $fields
-     * @return Symfony\Component\Form\Form
-     */
-    public function getForm($object, $fields)
+    protected function getManyToManyField($object, FieldDescription $fieldDescription)
     {
 
-        $this->container->get('session')->start();
+        $options = array(
+            'value_transformer' => new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\CollectionToChoiceTransformer(array(
+                'em'        =>  $this->getEntityManager(),
+                'className' => $fieldDescription->getTargetEntity()
+            ))
+        );
 
-        $form = new Form('data', $object, $this->container->get('validator'));
+        $options = array_merge($options, $fieldDescription->getOption('form_field_options', array()));
 
-        foreach ($fields as $name => $description) {
+        $class = $fieldDescription->getOption('form_field_widget', 'Symfony\\Component\\Form\\ChoiceField');
 
-            if (!$description->getType()) {
+        // set valid default value
+        if ($class == 'Symfony\\Component\\Form\\ChoiceField') {
 
-                continue;
-            }
-
-            switch($description->getType()) {
-
-                case ClassMetadataInfo::ONE_TO_MANY:
-                    
-                    $field = $this->getOneToManyField($object, $description);
-                    break;
-
-                case ClassMetadataInfo::MANY_TO_MANY:
-
-                    $transformer = new \Symfony\Bundle\DoctrineBundle\Form\ValueTransformer\CollectionToChoiceTransformer(array(
-                        'em'        =>  $this->getEntityManager(),
-                        'className' => $description->getTargetEntity()
-                    ));
-
-                    $field = new \Symfony\Component\Form\ChoiceField($name, array_merge(array(
-                        'expanded' => true,
-                        'multiple' => true,
-                        'choices' => $this->getChoices($description),
-                        'value_transformer' => $transformer,
-                    ), $description->getOption('form_field_options', array())));
-
-                    break;
-
-                case ClassMetadataInfo::MANY_TO_ONE:
-                case ClassMetadataInfo::ONE_TO_ONE:
-
-                    $field = $this->getOneToOneField($object, $description);
+            $options = array_merge(array(
+                'expanded' => true,
+                'multiple' => true,
+                'choices' => $this->getChoices($fieldDescription),
+             ), $options);
+        }
 
-                    break;
+        return new $class($fieldDescription->getFieldName(), $options);
+    }
+    
+    protected function getFormFieldInstance($object, FieldDescription $fieldDescription)
+    {
 
-                case 'string':
-                    $field = new \Symfony\Component\Form\TextField($name, $description->getOption('form_field_options', array()));
-                    break;
+        switch ($fieldDescription->getType()) {
+            case ClassMetadataInfo::ONE_TO_MANY:
 
-                case 'text':
-                    $field = new \Symfony\Component\Form\TextareaField($name, $description->getOption('form_field_options', array()));
-                    break;
+                return $this->getOneToManyField($object, $fieldDescription);
 
-                case 'boolean':
-                    $field = new \Symfony\Component\Form\CheckboxField($name, $description->getOption('form_field_options', array()));
-                    break;
+            case ClassMetadataInfo::MANY_TO_MANY:
 
-                case 'integer':
-                case 'tinyint';
-                case 'smallint':
-                case 'mediumint':
-                case 'bigint':
+                return $this->getManyToManyField($object, $fieldDescription);
 
-                    $field = new \Symfony\Component\Form\IntegerField($name, $description->getOption('form_field_options', array()));
-                    break;
+            case ClassMetadataInfo::ONE_TO_ONE:
 
-                case 'decimal':
-                    $field = new \Symfony\Component\Form\NumberField($name, $description->getOption('form_field_options', array()));
-                    break;
+                return $this->getOneToOneField($object, $fieldDescription);
 
-                case 'datetime':
-                    $field = new \Symfony\Component\Form\DateTimeField($name, $description->getOption('form_field_options', array()));
-                    break;
+            default:
+                $options = $fieldDescription->getOption('form_field_options', array());
 
-                case 'date':
-                    $field = new \Symfony\Component\Form\DateField($name, $description->getOption('form_field_options', array()));
-                    break;
+                $class = $this->getFormFieldClass($fieldDescription);
+                
+                return new $class($fieldDescription->getFieldName(), $options);
+        }
+    }
+    
+    /**
+     * return a form depend on the given $object and FieldDescription $fields array
+     *
+     * @throws RuntimeException
+     * @param  $object
+     * @param  $fields
+     * @return Symfony\Component\Form\Form
+     */
+    public function getForm($object, $fields)
+    {
 
-                case 'choice':
-                    $field = new \Symfony\Component\Form\ChoiceField($name, $description->getOption('form_field_options', array()));
-                    break;
+        $this->container->get('session')->start();
 
-                case 'array':
-                    $field = new \Symfony\Component\Form\FieldGroup($name, $description->getOption('form_field_options', array()));
+        $form = new Form('data', $object, $this->container->get('validator'));
 
-                    $values = $description->getValue($object);
+        foreach ($fields as $fieldDescription) {
 
-                    foreach ((array)$values as $k => $v) {
-                        $field->add(new \Symfony\Component\Form\TextField($k));
-                    }
-                    break;
+            if (!$fieldDescription->getType()) {
 
-                default:
-                    throw new \RuntimeException(sprintf('unknow type `%s`', $description->getType()));
+                continue;
             }
 
-            $form->add($field);
-
+            $form->add($this->getFormFieldInstance($object, $fieldDescription));
         }
 
         return $form;

+ 2 - 2
Admin/FieldDescription.php

@@ -28,8 +28,8 @@ namespace Bundle\Sonata\BaseApplicationBundle\Admin;
  *   - name (o) : the name used (label in the form, title in the list)
  *
  * Form Field options :
- *   - field_widget (o): the widget class to use to render the field
- *   - field_options (o): the options to give to the widget
+ *   - form_field_widget (o): the widget class to use to render the field
+ *   - form_field_options (o): the options to give to the widget
  *   - edit (o) : list|inline|standard (only used for associated admin)
  *      - list : open a popup where the user can search, filter and click on one field
  *               to select one item