Author: francois
Date: 2010-04-23 11:30:46 +0200 (Fri, 23 Apr 2010)
New Revision: 29246

Modified:
   plugins/sfPropel15Plugin/trunk/README
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/createAction.php
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/editAction.php
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/filterAction.php
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/newAction.php
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/paginationAction.php
   
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/updateAction.php
   plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt
   plugins/sfPropel15Plugin/trunk/lib/form/sfFormFilterPropel.class.php
   plugins/sfPropel15Plugin/trunk/lib/generator/sfPropelGenerator.class.php
Log:
[sfPropel15Plugin] Allowing advanced form customization from generator.yml

Modified: plugins/sfPropel15Plugin/trunk/README
===================================================================
--- plugins/sfPropel15Plugin/trunk/README       2010-04-22 21:17:02 UTC (rev 
29245)
+++ plugins/sfPropel15Plugin/trunk/README       2010-04-23 09:30:46 UTC (rev 
29246)
@@ -104,7 +104,7 @@
 
 ### Filter and Edit forms enhancement
 
-- **YAML widget customization**: The `generator.yml` format was extended to 
allow basic widget customization directly in YAML, without the need to edit a 
form object.
+- **YAML widget customization**: The `generator.yml` format was extended to 
allow widget and validator customization directly in YAML, without the need to 
edit a form object. You can also safely omit a field from a `display` list in a 
form definition, without any risk to loose data.
 
 The new options for the `admin15` generator theme are fully documented, and 
illustrated by real life examples, in the 
[`doc/admin_generator.txt`](http://trac.symfony-project.org/browser/plugins/sfPropel15Plugin/doc/admin_generator.txt)
 file in this plugin source code.
 

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/createAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/createAction.php
 2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/createAction.php
 2010-04-23 09:30:46 UTC (rev 29246)
@@ -1,6 +1,7 @@
   public function executeCreate(sfWebRequest $request)
   {
     $this->form = $this->configuration->getForm();
+<?php echo $this->getFormCustomization('new') ?>
     $this-><?php echo $this->getSingularName() ?> = $this->form->getObject();
 
     $this->processForm($request, $this->form);

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/editAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/editAction.php
   2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/editAction.php
   2010-04-23 09:30:46 UTC (rev 29246)
@@ -2,4 +2,5 @@
   {
     $this-><?php echo $this->getSingularName() ?> = 
$this->getRoute()->getObject();
     $this->form = $this->configuration->getForm($this-><?php echo 
$this->getSingularName() ?>);
+<?php echo $this->getFormCustomization('edit') ?>
   }

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/filterAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/filterAction.php
 2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/filterAction.php
 2010-04-23 09:30:46 UTC (rev 29246)
@@ -10,6 +10,7 @@
     }
 
     $this->filters = $this->configuration->getFilterForm($this->getFilters());
+<?php echo $this->getFormCustomization('filter', 'filters') ?>
 
     $this->filters->bind($request->getParameter($this->filters->getName()));
     if ($this->filters->isValid())

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/newAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/newAction.php
    2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/newAction.php
    2010-04-23 09:30:46 UTC (rev 29246)
@@ -2,4 +2,5 @@
   {
     $this->form = $this->configuration->getForm();
     $this-><?php echo $this->getSingularName() ?> = $this->form->getObject();
+<?php echo $this->getFormCustomization('new') ?>
   }

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/paginationAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/paginationAction.php
     2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/paginationAction.php
     2010-04-23 09:30:46 UTC (rev 29246)
@@ -23,31 +23,7 @@
     if (null === $this->filters)
     {
       $this->filters = 
$this->configuration->getFilterForm($this->getFilters());
-      foreach ($this->configuration->getFieldsFilter() as $key => $field)
-      {
-       if (isset($field['widget']))
-       {
-         $widget = $field['widget'];
-         $options = (isset($widget['options'])) ? $widget['options'] : array();
-         $attributes = (isset($widget['attributes'])) ? $widget['attributes'] 
: array();
-         if (isset($widget['class']))
-         {
-           $class = $widget['class'];
-           $this->filters->setWidget($key, new $class($options, $attributes));
-         }
-         else
-         {
-           foreach ($options as $name => $value)
-           {
-             $this->filters->getWidget($key)->setOption($name, $value);
-           }
-           foreach ($attributes as $name => $value)
-           {
-             $this->filters->getWidget($key)->setAttribute($name, $value);
-           }
-         }
-       }
-      }
+<?php echo $this->getFormCustomization('filter', 'filters') ?>
     }
 
     $query = $this->filters->buildCriteria($this->getFilters());

Modified: 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/updateAction.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/updateAction.php
 2010-04-22 21:17:02 UTC (rev 29245)
+++ 
plugins/sfPropel15Plugin/trunk/data/generator/sfPropelModule/admin15/parts/updateAction.php
 2010-04-23 09:30:46 UTC (rev 29246)
@@ -2,6 +2,7 @@
   {
     $this-><?php echo $this->getSingularName() ?> = 
$this->getRoute()->getObject();
     $this->form = $this->configuration->getForm($this-><?php echo 
$this->getSingularName() ?>);
+<?php echo $this->getFormCustomization('edit') ?>
 
     $this->processForm($request, $this->form);
 

Modified: plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt
===================================================================
--- plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt      2010-04-22 
21:17:02 UTC (rev 29245)
+++ plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt      2010-04-23 
09:30:46 UTC (rev 29246)
@@ -45,7 +45,7 @@
       display: [title, Author, Publisher]
       with:    [Author, Publisher]
 
-*Tip*: Before adding relations to the `with` setting, check that you don't 
already have a filter on the foreign key column that already makes the query to 
list all the related objects. If it's the case, then Propel's Instance Pooling 
will make the `with` superfluous, as each call to a related object will not 
trigger an additional query anyway.
+**Tip**: Before adding relations to the `with` setting, check that you don't 
already have a filter on the foreign key column that already makes the query to 
list all the related objects. If it's the case, then Propel's Instance Pooling 
will make the `with` superfluous, as each call to a related object will not 
trigger an additional query anyway.
 
 Additional Query Methods
 ------------------------
@@ -220,20 +220,38 @@
 
 The amdin generator looks for a `filterByXXX()` method in the query class, 
where `XXX` is the CamelCase version of the custom filter you add.
 
-YAML Widget Customization
--------------------------
+YAML Form Customization
+-----------------------
 
-You can now change widget options directly from within the `generator.yml`. 
That means you no longer need to edit a form object for basic widget 
customization.
+You can now modify, add or remove widgets and validators directly from within 
the `generator.yml`, for all generator forms. That means you no longer need to 
edit a form object for basic widget customization.
 
-Just add your custom widget `class`, `options`, or `attributes` under the 
`widget` key of your field description. For instance, to add a custom order and 
CSS class to a choice widget in the edit form, the following YAML code is 
enough:
+This is made possible by five new field attributes that you can customize: 
`widgetClass`, `widgetOptions`, `validatorClass`, `validatorOptions`, and 
`validatorMessages`. Of course, you can still modify the HTML attributes of a 
widget by setting the `attributes` attribute.
 
-    [yaml]
-    # in modules/book/config/generator.yml
-    config:
-      edit:
-        display: [id, title, author_id]
-        fields:
-          author_id:
-            widget:
-              options:    { order_by: [LastName, asc] }
-              attributes: { class: authorList }
\ No newline at end of file
+**Tip**: You can also safely omit one of the form fields in the `display` 
list. The `admin15` generator theme takes care of unsetting the field in the 
form for you.
+
+For instance, to replace an input filter on a text column by a choice list, 
try the following:
+
+    [php]
+    filter:
+      fields:
+        sex: 
+          widgetClass:   sfWidgetFormChoice
+          widgetOptions: { choices: { '': '' , male: Male, female: Female } }
+
+To remove the "is empty" checkbox for a given filter, just set the relevant 
option in YAML:
+
+    [php]
+    filter:
+      fields:
+        title: 
+          widgetOptions: { with_empty: false }
+
+To replace a text input by a textarea in the edit form, change the input type:
+
+    [php]
+    form:
+      fields:
+        body:
+          widgetClass:   sfWidgetFormTextarea
+
+The configuration cascade works as usual for these attributes, so a field 
customization defined under the `form` key affects both the `new` and `edit` 
forms, and a field customization defined under the main `field` key affects all 
forms, including the filter form.
\ No newline at end of file

Modified: plugins/sfPropel15Plugin/trunk/lib/form/sfFormFilterPropel.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/form/sfFormFilterPropel.class.php        
2010-04-22 21:17:02 UTC (rev 29245)
+++ plugins/sfPropel15Plugin/trunk/lib/form/sfFormFilterPropel.class.php        
2010-04-23 09:30:46 UTC (rev 29246)
@@ -205,6 +205,10 @@
     {
       $criteria->add($colname, '%'.$values['text'].'%', Criteria::LIKE);
     }
+    else if (is_scalar($values) && '' != $values)
+    {
+      $criteria->add($colname, '%'.$values.'%', Criteria::LIKE);
+    }
   }
 
   protected function addNumberCriteria(Criteria $criteria, $field, $values)
@@ -221,6 +225,10 @@
     {
       $criteria->add($colname, $values['text']);
     }
+    else if (is_scalar($values) && '' != $values)
+    {
+      $criteria->add($colname, $values);
+    }
   }
 
   protected function addBooleanCriteria(Criteria $criteria, $field, $value)

Modified: 
plugins/sfPropel15Plugin/trunk/lib/generator/sfPropelGenerator.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/generator/sfPropelGenerator.class.php    
2010-04-22 21:17:02 UTC (rev 29245)
+++ plugins/sfPropel15Plugin/trunk/lib/generator/sfPropelGenerator.class.php    
2010-04-23 09:30:46 UTC (rev 29246)
@@ -354,4 +354,157 @@
 
     return call_user_func(array($peer, 'translateFieldName'), $field, 
BasePeer::TYPE_COLNAME, $to);
   }
+  
+  /**
+   * Get the code to modify a form object based on fields configuration.
+   *
+   * Configuration attributes considered for customization:
+   *  * widgetClass
+   *  * widgetOptions
+   *  * widgetAttributes (same effect as the 'attributes' attribute)
+   *  * validatorClass
+   *  * validatorOptions
+   *  * validatorMessages
+   *
+   * This also removes unused fields from the display list.
+   *
+   * <code>
+   * form:
+   *   display: [foo1, foo2]
+   *   fields:
+   *     foo1: { widgetOptions: { bar: baz } }
+   *     foo2: { widgetClass: sfWidgetFormInputText, validatorClass: 
sfValidatorPass }   
+   * $form->getWidget('foo1')->setOption('bar', 'baz');
+   * $form->setWidget('foo2', new sfWidgetFormInputText());
+   * $form->setValidator('foo2', new sfValidatorPass());
+   * unset($form['foo']);
+   * </code>
+   *
+   * @param string $view Choices are 'edit', 'new', or 'filter'
+   * @param string $formVariableName The name of the variable referencing the 
form.
+   *                                 Choices are 'form', or 'filters'
+   *
+   * @return string the form customization code
+   */
+  public function getFormCustomization($view, $formVariableName = 'form')
+  {
+    $customization = '';
+    $class = $this->getSingularName();
+    $form = $this->configuration->getForm(new $class()); // fallback field 
definition
+    $defaultFieldNames = array_keys($form->getWidgetSchema()->getFields());
+    $unusedFields = array_combine($defaultFieldNames, $defaultFieldNames);
+    $fieldsets = ($view == 'filter') ? array('NONE' => 
$this->configuration->getFormFilterFields($form)) : 
$this->configuration->getFormFields($form, $view);
+    
+    foreach ($fieldsets as $fieldset => $fields)
+    {
+      foreach ($fields as $fieldName => $field) 
+      {
+        // widget customization
+        if (!$widgetConfig = $field->getConfig('widget', array()))
+        {
+          if ($widgetClass = $field->getConfig('widgetClass', false))
+          {
+            $widgetConfig['class'] = $widgetClass;
+          }
+          if ($widgetOptions = $field->getConfig('widgetOptions', false))
+          {
+            $widgetConfig['options'] = $widgetOptions;
+          }
+          if ($widgetAttributes = $field->getConfig('widgetAttributes', false))
+          {
+            $widgetConfig['attributes'] = $widgetAttributes;
+          }
+        }
+        if ($widgetConfig) 
+        {
+          $options = (isset($widgetConfig['options'])) ? 
$widgetConfig['options'] : array();
+          $attributes = (isset($widgetConfig['attributes'])) ? 
$widgetConfig['attributes'] : array();
+          if (isset($widgetConfig['class']))
+          {
+            $class = $widgetConfig['class'];
+            $customization .= "    \$this->" . $formVariableName . 
"->setWidget('$fieldName', new $class(" . $this->asPhp($options) . ", " . 
$this->asPhp($attributes) . "));
+";
+          }
+          else
+          {
+            foreach ($options as $name => $value)
+            {
+              $customization .= "    \$this->" . $formVariableName . 
"->getWidget('$fieldName')->setOption('$name', " . $this->asPhp($value) . ");
+";
+            }
+            foreach ($attributes as $name => $value)
+            {
+              $customization .= "    \$this->" . $formVariableName . 
"->getWidget('$fieldName')->setAttribute('$name', " . $this->asPhp($value) . ");
+";
+            }
+          }
+        }
+        
+        // validator configuration
+        if (!$validatorConfig = $field->getConfig('validator', array()))
+        {
+          if ($validatorClass = $field->getConfig('validatorClass', false))
+          {
+            $validatorConfig['class'] = $validatorClass;
+          }
+          if ($validatorOptions = $field->getConfig('validatorOptions', false))
+          {
+            $validatorConfig['options'] = $validatorOptions;
+          }
+          if ($validatorMessages = $field->getConfig('validatorMessages', 
false))
+          {
+            $validatorConfig['messages'] = $validatorMessages;
+          }
+        }
+        if ($validatorConfig) 
+        {
+          $options = (isset($validatorConfig['options'])) ? 
$validatorConfig['options'] : array();
+          $messages = (isset($validatorConfig['messages'])) ? 
$validatorConfig['messages'] : array();
+          if (isset($validatorConfig['class']))
+          {
+            $class = $validatorConfig['class'];
+            $customization .= "    \$this->" . $formVariableName . 
"->setValidator('$fieldName', new $class(" . $this->asPhp($options) . ", " . 
$this->asPhp($messages) . "));
+";
+          }
+          else
+          {
+            foreach ($options as $name => $value)
+            {
+              $customization .= "    \$this->" . $formVariableName . 
"->getValidator('$fieldName')->setOption('$name', " . $this->asPhp($value) . ");
+";
+            }
+            foreach ($messages as $name => $value)
+            {
+              $customization .= "    \$this->" . $formVariableName . 
"->getValidator('$fieldName')->setMessage('$name', " . $this->asPhp($value) . 
");
+";
+            }
+          }
+        }
+
+        // this field is used
+        if (isset($unusedFields[$fieldName]))
+        {
+          unset($unusedFields[$fieldName]);
+        }
+      }
+    }
+    
+    // remove unused fields
+    if (!empty($unusedFields))
+    {
+      foreach ($unusedFields as $field)
+      {
+        // ignore primary keys and CSRF
+        if ($form->getWidget($field) instanceof sfWidgetFormInputHidden 
+         || $form->getCSRFFieldName() == $field)
+        {
+          continue;
+        }
+        $customization .= "    unset(\$this->" . $formVariableName . 
"['$field']);
+";
+      }
+    }
+    
+    return $customization;
+  }
 }

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/symfony-svn?hl=en.

Reply via email to