Author: francois
Date: 2010-05-12 00:16:05 +0200 (Wed, 12 May 2010)
New Revision: 29413

Added:
   plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php
Modified:
   plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php
Log:
[sfPropel15Plugin] Added sfFormPropel::embedRelation() (WIP)

Modified: plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php      
2010-05-11 16:50:01 UTC (rev 29412)
+++ plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php      
2010-05-11 22:16:05 UTC (rev 29413)
@@ -20,6 +20,9 @@
  */
 abstract class sfFormPropel extends sfFormObject
 {
+  protected $ignoreIfEmpty = false;
+  protected $fixedValues = array();
+  
   /**
    * Constructor.
    *
@@ -58,7 +61,7 @@
    */
   public function getConnection()
   {
-    return 
Propel::getConnection(constant(constant(get_class($this->getObject()).'::PEER').'::DATABASE_NAME'));
+    return Propel::getConnection(constant($this->getPeer().'::DATABASE_NAME'));
   }
 
   /**
@@ -95,6 +98,8 @@
    */
   protected function doUpdateObject($values)
   {
+    print_r($values);
+    $values = array_merge($values, $this->getFixedValues());
     $this->getObject()->fromArray($values, BasePeer::TYPE_FIELDNAME);
   }
 
@@ -118,7 +123,7 @@
     {
       try
       {
-        $method = sprintf('update%sColumn', 
call_user_func(array(constant(get_class($this->getObject()).'::PEER'), 
'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, 
BasePeer::TYPE_PHPNAME));
+        $method = sprintf('update%sColumn', 
call_user_func(array($this->getPeer(), 'translateFieldName'), $field, 
BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
       }
       catch (Exception $e)
       {
@@ -229,7 +234,7 @@
 
     if (!$values[$field])
     {
-      $column = 
call_user_func(array(constant(get_class($this->getObject()).'::PEER'), 
'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, 
BasePeer::TYPE_PHPNAME);
+      $column = call_user_func(array($this->getPeer(), 'translateFieldName'), 
$field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
       $getter = 'get'.$column;
 
       return $this->getObject()->$getter();
@@ -258,7 +263,7 @@
       throw new LogicException(sprintf('You cannot remove the current file for 
field "%s" as the field is not a file.', $field));
     }
 
-    $column = 
call_user_func(array(constant(get_class($this->getObject()).'::PEER'), 
'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, 
BasePeer::TYPE_PHPNAME);
+    $column = call_user_func(array($this->getPeer(), 'translateFieldName'), 
$field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
     $getter = 'get'.$column;
 
     if (($directory = $this->validatorSchema[$field]->getOption('path')) && 
is_file($directory.DIRECTORY_SEPARATOR.$this->getObject()->$getter()))
@@ -266,7 +271,12 @@
       unlink($directory.DIRECTORY_SEPARATOR.$this->getObject()->$getter());
     }
   }
-
+  
+  public function getPeer()
+  {
+    return constant(get_class($this->getObject()).'::PEER');
+  }
+  
   /**
    * Saves the current file for the field.
    *
@@ -288,7 +298,7 @@
       $file = $this->getValue($field);
     }
 
-    $column = 
call_user_func(array(constant(get_class($this->getObject()).'::PEER'), 
'translateFieldName'), $field, BasePeer::TYPE_FIELDNAME, 
BasePeer::TYPE_PHPNAME);
+    $column = call_user_func(array($this->getPeer(), 'translateFieldName'), 
$field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
     $method = sprintf('generate%sFilename', $column);
 
     if (null !== $filename)
@@ -308,4 +318,121 @@
       return $file->save();
     }
   }
+  
+  /**
+   * Overrides sfForm::mergeForm() to also merge embedded forms
+   * Allows autosave of marged collections
+   *
+   * @param  sfForm   $form      The sfForm instance to merge with current form
+   *
+   * @throws LogicException      If one of the form has already been bound
+   */
+  public function mergeForm(sfForm $form)
+  {
+    foreach ($form->getEmbeddedForms() as $name => $embeddedForm)
+    {
+      $this->embedForm($name, clone $embeddedForm);
+    }
+    parent::mergeForm($form);
+  }
+  
+  /**
+   * Merge Relation form into this form
+   */
+  public function mergeRelation($relationName, $options = array())
+  {
+    $relationForm = $this->getRelationForm($relationName, $options);
+    
+    $this->mergeForm($relationForm);
+  }
+  
+  public function embedRelation($relationName, $options = array())
+  {
+    $options = array_merge(array(
+      'title'               => $relationName,
+      'decorator'           => null
+    ), $options);
+    
+    $relationForm = $this->getRelationForm($relationName, $options);
+    
+    $this->embedForm($options['title'], $relationForm, $options['decorator']);
+  }
+  
+  public function getRelationForm($relationName, $options = array())
+  {
+    $options = array_merge(array(
+      'embedded_form_class' => null,
+      'item_pattern'        => '%index%',
+      'add_empty'           => false,
+      'empty_name'          => null,
+      'hide_on_new'         => false,
+    ), $options);
+    
+    if ($this->getObject()->isNew() && $options['hide_on_new'])
+    {
+      return;
+    }
+    
+    // compute relation elements
+    $tableMap = call_user_func(array($this->getPeer(), 'getTableMap'));
+    $relationMap = $tableMap->getRelation($relationName);
+    if ($relationMap->getType() != RelationMap::ONE_TO_MANY)
+    {
+      throw new sfException('embedRelation() only works for one-to-many 
relationships');
+    }
+    $collection = call_user_func(array($this->getObject(), sprintf('get%ss', 
$relationName)));
+    $relatedPeer = $relationMap->getRightTable()->getPeerClassname();
+    
+    // compute relation fields, to be removed from embedded forms
+    // because this data is not editable
+    $relationFields = array();
+    foreach ($relationMap->getColumnMappings(RelationMap::LEFT_TO_RIGHT) as 
$leftCol => $rightCol)
+    {
+      $relationFields[$leftCol]= call_user_func(array($relatedPeer, 
'translateFieldName'), $rightCol, BasePeer::TYPE_COLNAME, 
BasePeer::TYPE_FIELDNAME);
+    }
+    
+    // create the relation form
+    $collectionForm = new sfFormPropelCollection($collection, array(
+      'embedded_form_class' => $options['embedded_form_class'],
+      'item_pattern'        => $options['item_pattern'],
+      'remove_fields'       => $relationFields,
+    ));
+    
+    // add empty form for addition
+    // FIXME new relations saved at each edit
+    if ($options['add_empty'])
+    {
+      if (null === $options['empty_name']) {
+        $options['empty_name'] = 'new' . $relationMap->getName();
+      }
+      $relatedClass = $relationMap->getRightTable()->getClassname();
+      $formClass = $collectionForm->getFormClass();
+      $emptyForm = new $formClass(new $relatedClass());
+      $relationValues = array();
+      foreach ($relationFields as $leftCol => $field)
+      {
+        unset($emptyForm[$field]);
+        $emptyForm->setFixedValue($field, 
$this->getObject()->getByName($leftCol, BasePeer::TYPE_COLNAME));
+      }
+      $collectionForm->embedForm($options['empty_name'], $emptyForm);
+    }
+    
+    return $collectionForm;
+  }
+  
+  public function setFixedValues($values)
+  {
+    $this->fixedValues = $values;
+  }
+
+  public function setFixedValue($name, $value)
+  {
+    $this->fixedValues[$name] = $value;
+  }
+
+  public function getFixedValues()
+  {
+    return $this->fixedValues;
+  }
+
 }

Added: plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php    
                        (rev 0)
+++ plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php    
2010-05-11 22:16:05 UTC (rev 29413)
@@ -0,0 +1,79 @@
+<?php
+
+
+class sfFormPropelCollection extends sfForm
+{
+  protected $model;
+  protected $collection;
+  protected $isEmpty = false;
+  
+  public function __construct($collection = null, $options = array(), 
$CSRFSecret = null)
+  {
+    $options = array_merge(array(
+      'item_pattern' => '%index%',
+      'remove_fields' => array(),
+    ), $options);
+    if (!$collection)
+    {
+      $this->model = $options['model'];
+      $collection = new PropelObjectcollection();
+      $collection->setModel($this->model);
+      $this->collection = $collection;
+    }
+    else
+    {
+      if (!$collection instanceof PropelObjectCollection)
+      {
+        throw new sfException(sprintf('The "%s" form only accepts a 
PropelObjectCollection object.', get_class($this)));
+      }
+      $this->collection = $collection;
+      $this->model = $collection->getModel();
+    }
+    
+    $this->isEmpty = $this->getCollection()->isEmpty();
+
+    parent::__construct(array(), $options, $CSRFSecret);
+  }
+  
+  public function configure()
+  {
+    $formClass = $this->getFormClass();
+    $i = 1;
+    foreach ($this->getCollection() as $relatedObject)
+    {
+      $form = new $formClass($relatedObject);
+      foreach ($this->getOption('remove_fields') as $field)
+      {
+        unset($form[$field]);
+      }
+      $name = strtr($this->getOption('item_pattern'), array('%index%' => $i, 
'%model%' => $this->getModel()));
+      $this->embedForm($name, $form);
+      $i++;
+    }
+  }
+  
+  public function getCollection()
+  {
+    return $this->collection;
+  }
+  
+  public function getModel()
+  {
+    return $this->model;
+  }
+  
+  public function isEmpty()
+  {
+    return $this->isEmpty;
+  }
+  
+  public function getFormClass()
+  {
+    if (!$class = $this->getOption('embedded_form_class', false))
+    {
+      $class = $this->getCollection()->getModel() . 'Form';
+    }
+    
+    return $class;
+  }
+}
\ No newline at end of file


Property changes on: 
plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php
___________________________________________________________________
Added: svn:keywords
   + "Id Revision Author Date Rev"
Added: svn:eol-style
   + native

-- 
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