]> git.andy128k.dev Git - ipf.git/commitdiff
Support ManyToMany relations in forms
authoravl <alex.litovchenko@gmail.com>
Sun, 5 Oct 2008 17:48:23 +0000 (20:48 +0300)
committeravl <alex.litovchenko@gmail.com>
Sun, 5 Oct 2008 17:48:23 +0000 (20:48 +0300)
ipf/admin/model.php
ipf/admin/templates/admin/base.html
ipf/form/db/manytomany.php [new file with mode: 0644]
ipf/form/field/modelchoice.php
ipf/form/field/modelmultiplechoice.php [new file with mode: 0644]
ipf/form/field/multiplechoice.php [new file with mode: 0644]
ipf/form/model.php
ipf/form/widget/selectmultipleinput.php
ipf/orm/connection/unitofwork.php
ipf/orm/exception/orm.php
ipf/orm/record.php

index 673299f3804f0c3b7dd3c22052ca1cc8f537ed17..73db6b468c50f4c7ab5aa37dbbd24815e58c11b6 100644 (file)
@@ -216,6 +216,15 @@ class IPF_Admin_Model{
         }
         else{
             $data = $o->getData();
+            foreach($o->getTable()->getRelations() as $rname=>$rel){
+                if (array_search($rname,$this->fields())){
+                    if ($rel->getType()==IPF_ORM_Relation::MANY_AGGREGATE){
+                        $data[$rname] = array();
+                        foreach($rel->fetchRelatedFor($o) as $ri)
+                            $data[$rname][] = $ri->id;
+                    }
+                }
+            }
             $form = $this->_getEditForm($o,&$data,array('user_fields'=>$this->fields()));
             $this->_setupEditForm($form);
             $this->setInlines($o, &$data);
index 476d8ecede80f0416c0dd1ed1535f2c3633f4d2e..047adf5cbc71825fb41f16b04206331c79b19d37 100644 (file)
@@ -32,5 +32,6 @@
 </div>
 <!-- END Container -->
 {block scripts}{/block}
+
 </body>
 </html>
diff --git a/ipf/form/db/manytomany.php b/ipf/form/db/manytomany.php
new file mode 100644 (file)
index 0000000..2188498
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+class IPF_Form_DB_Manytomany extends IPF_Form_DB
+{
+    public $type = 'manytomany';
+
+    function formField($def, $form_field='IPF_Form_Field_ModelMultipleChoice')
+    {
+        //print_r($def);
+        $list_objects = IPF_ORM::getTable($def['model'])->findAll();
+        $choices = array();
+        foreach($list_objects as $o){
+            $choices[$o->__toString()] = $o->id;
+        }
+        $def['choices'] = $choices;
+        if (!isset($def['widget'])) {
+            $def['widget'] = 'IPF_Form_Widget_SelectMultipleInput';
+        }
+        return parent::formField($def, $form_field);
+    }
+}
index 1ce1ce5edf14752773785e6e3f592579be84eaa6..47d832569e59a2ffe1bc841bccb7c14844ffe3d1 100644 (file)
@@ -6,7 +6,7 @@ class IPF_Form_Field_ModelChoice extends IPF_Form_Field_Choice{
 
     function __construct($params=array()){
         parent::__construct($params);
-        $this->model = $params['model'];
+        $this->_model = $params['model'];
         if (isset($params['queryset'])){
             $choices = array('--------'=>'');
             foreach ($params['queryset'] as $item) {
@@ -15,7 +15,7 @@ class IPF_Form_Field_ModelChoice extends IPF_Form_Field_Choice{
             $this->setChoices($choices);
         }
     }
-    
+
     public function clean($value){
         parent::clean($value);
         if (in_array($value, $this->empty_values)) {
@@ -24,7 +24,7 @@ class IPF_Form_Field_ModelChoice extends IPF_Form_Field_Choice{
         //print_r($this->model);
         //print $value;
         //$this->model->get($value);
-        $o = $this->model->getTable()->find($value);
+        $o = $this->_model->getTable()->find($value);
         return $o;
     }
 }
diff --git a/ipf/form/field/modelmultiplechoice.php b/ipf/form/field/modelmultiplechoice.php
new file mode 100644 (file)
index 0000000..644ac1d
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+class IPF_Form_Field_ModelMultipleChoice extends IPF_Form_Field_MultipleChoice{
+    public $widget = 'IPF_Form_Widget_SelectMultipleInput';
+    protected $_model;
+
+    function __construct($params=array()){
+        parent::__construct($params);
+        $this->_model = $params['model'];
+    }
+}
+
diff --git a/ipf/form/field/multiplechoice.php b/ipf/form/field/multiplechoice.php
new file mode 100644 (file)
index 0000000..b6da5b8
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+class IPF_Form_Field_MultipleChoice extends IPF_Form_Field_Choice{
+    public $widget = 'IPF_Form_Widget_SelectMultipleInput';
+
+    public function validValue($value){
+        foreach($value as $v){
+            $find = false;
+            foreach($this->_choices as $name=>$val){
+                if ($v==$val){
+                    $find = true;
+                    break;
+                }
+            }
+            if (!$find)
+                return false;
+        }
+        return true;
+    }
+
+    public function clean($value){
+        parent::clean($value);
+        if (in_array($value, $this->empty_values)) {
+            return '';
+        }
+        if (!$this->validValue($value))
+            throw new IPF_Exception_Form(__('Invalid choice'));
+        return $value;
+    }
+
+}
+
index 40d516448c9f2691ebfa88bf0453b772e1c71416..994d4d235aad08a029b3b55148943c4574b25608 100644 (file)
@@ -94,6 +94,14 @@ class IPF_Form_Model extends IPF_Form
             $defaults = array('blank' => true, 'verbose' => $name, 'help_text' => '', 'editable' => true, 'model'=>$relation->getClass());
             $form_field = $db_field->formField($defaults);
             $this->fields[$name] = $form_field;
+            return;
+        }
+        if ($relation->getType()==IPF_ORM_Relation::MANY_AGGREGATE){
+            $db_field = new IPF_Form_DB_ManyToMany('',$name);
+            $defaults = array('blank' => true, 'verbose' => $name, 'help_text' => '', 'editable' => true, 'model'=>$relation->getClass());
+            $form_field = $db_field->formField($defaults);
+            $this->fields[$name] = $form_field;
+            return;
         }
     }
 
@@ -105,6 +113,17 @@ class IPF_Form_Model extends IPF_Form
             $this->model->SetFromFormData($this->cleaned_data);
             try{
                 $this->model->save();
+                $rels = $this->model->getTable()->getRelations();
+
+                foreach($rels as $rname=>$rel){
+                    //print "$rname<br>";
+                    if (isset($this->cleaned_data[$rname])){
+                        //print $rel->getAlias();
+                        $this->model->unlink($rel->getAlias());
+                        if (is_array($this->cleaned_data[$rname]))
+                            $this->model->link($rel->getAlias(),$this->cleaned_data[$rname]);
+                    }
+                }
                 return $this->model;
             } catch(IPF_ORM_Exception_Validator $e) {
                 $erecords = $e->getInvalidRecords();
index e3526e542fd2f3f667f1833f80607b7a6bd73299..92d9bf239953534d6c105c1dca849e0919fc67e2 100644 (file)
@@ -11,23 +11,24 @@ class IPF_Form_Widget_SelectMultipleInput extends IPF_Form_Widget
         parent::__construct($attrs);
     }
 
-    public function render($name, $value, $extra_attrs=array(), 
+    public function render($name, $value, $extra_attrs=array(),
                            $choices=array())
     {
         $output = array();
         if ($value === null) {
             $value = array();
         }
-        $final_attrs = $this->buildAttrs(array('name' => $name.'[]'), 
+        $final_attrs = $this->buildAttrs(array('name' => $name.'[]'),
                                          $extra_attrs);
         $output[] = '<select multiple="multiple"'
             .IPF_Form_Widget_Attrs($final_attrs).'>';
         $choices = array_merge($this->choices, $choices);
+
         foreach ($choices as $option_label=>$option_value) {
             $selected = (in_array($option_value, $value)) ? ' selected="selected"':'';
             $output[] = sprintf('<option value="%s"%s>%s</option>',
                                 htmlspecialchars($option_value, ENT_COMPAT, 'UTF-8'),
-                                $selected, 
+                                $selected,
                                 htmlspecialchars($option_label, ENT_COMPAT, 'UTF-8'));
 
         }
index abeb5feb2676fa439dcdd61ba967a88356ebcbf6..887fa5d29758f1aabd31ce49b32d2e484db779dc 100644 (file)
@@ -23,7 +23,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module
             $record->preSave($event);
             $record->getTable()->getRecordListener()->preSave($event);
             $state = $record->state();
-            
+
             if ( ! $event->skipOperation) {
                 switch ($state) {
                     case IPF_ORM_Record::STATE_TDIRTY:
@@ -59,7 +59,6 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module
 
             if ($record->hasReference($alias)) {
                 $obj = $record->$alias;
-
                 // check that the related object is not an instance of IPF_ORM_Null
                 if ( ! ($obj instanceof IPF_ORM_Null)) {
                     $obj->save($conn);
@@ -71,7 +70,6 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module
         $this->saveAssociations($record);
 
         $record->state($state);
-
         $conn->commit();
 
         return true;
@@ -294,11 +292,12 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module
     {
         foreach ($record->getReferences() as $k => $v) {
             $rel = $record->getTable()->getRelation($k);
-
+            //print get_class($rel);
             if ($rel instanceof IPF_ORM_Relation_Association) {
                 $v->save($this->conn);
 
                 $assocTable = $rel->getAssociationTable();
+
                 foreach ($v->getDeleteDiff() as $r) {
                     $query = 'DELETE FROM ' . $assocTable->getTableName()
                            . ' WHERE ' . $rel->getForeign() . ' = ?'
index 12b42aa810e9ef314c83a17dee613a888f8a8658..e57b5d5c81ca27ab6c34dc573af511c2bab4f2b4 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 
 class IPF_ORM_Exception extends IPF_Exception_Base{
-{ 
     protected static $_errorMessages = array(
         IPF_ORM::ERR                    => 'unknown error',
         IPF_ORM::ERR_ALREADY_EXISTS     => 'already exists',
@@ -49,6 +48,6 @@ class IPF_ORM_Exception extends IPF_Exception_Base{
 
 }
 
-    
-    
-    
+
+
+
index deea2c9af436a7840a5b3b5bb33e3b7e18fec481..3eef7b0be8a9563bfbc1961db28c956c0a012c64 100644 (file)
@@ -1259,6 +1259,7 @@ abstract class IPF_ORM_Record extends IPF_ORM_Record_Abstract implements Countab
 
     public function SetFromFormData($cleaned_values)
     {
+        $names = $this->_table->getFieldNames();
         foreach ($cleaned_values as $key=>$val) {
             $validators = $this->getTable()->getFieldValidators($key);
             if (
@@ -1269,7 +1270,8 @@ abstract class IPF_ORM_Record extends IPF_ORM_Record_Abstract implements Countab
                 if (($val!==null) && ($val==''))
                     continue;
             }
-            $this->$key = $val;
+            if (array_search($key,$names))
+                $this->$key = $val;
         }
     }
 }
\ No newline at end of file