Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

fix issue #129 and #130 with BC break of generated form for M2M witho…

…ut isCrossRef parameters
  • Loading branch information...
commit d8e35efce88479ad43893beb30751d9f2cb92286 1 parent 6fc933a
Jérémie Augustin authored
59  lib/generator/sfPropelFormGenerator.class.php
@@ -124,6 +124,7 @@ public function generate($params = array())
124 124
   public function getManyToManyTables()
125 125
   {
126 126
     $tables = array();
  127
+    $middleTables = array();
127 128
     $foreignTables = array();
128 129
     $relations = array();
129 130
 
@@ -146,26 +147,62 @@ public function getManyToManyTables()
146 147
     {
147 148
       foreach ($foreignTable->getRelations() as $foreignRelation)
148 149
       {
149  
-        $foreignTableName = $foreignRelation->getLocalTable()->getClassname();
  150
+        $foreignTableClassname = $foreignRelation->getLocalTable()->getClassname();
150 151
 
151 152
         // Test if the foreign table has a common relation with our table
152  
-        // TODO: test if is CrossRef
153 153
         if (RelationMap::ONE_TO_MANY === $foreignRelation->getType()
154  
-            && array_key_exists($foreignTableName, $relations))
  154
+            && array_key_exists($foreignTableClassname, $relations))
155 155
         {
156  
-          $columns = $relations[$foreignTableName]->getLocalColumns();
  156
+          $columns = $relations[$foreignTableClassname]->getLocalColumns();
157 157
           $relatedColumns = $foreignRelation->getLocalColumns();
158 158
 
159  
-          $tables[] = array(
160  
-            'middleTable'   => $foreignRelation->getLocalTable(),
161  
-            'relatedTable'  => $foreignTable,
162  
-            'column'        => reset($columns),
163  
-            'relatedColumn' => reset($relatedColumns),
164  
-          );
165  
-          continue 2;
  159
+          $middleTable = $foreignRelation->getLocalTable();
  160
+          $middleTables[$middleTable->getClassname()] = $middleTable;
  161
+          if ($middleTable->isCrossRef())
  162
+          {
  163
+            $tables[] = array(
  164
+              'middleTable'   => $middleTable,
  165
+              'relatedTable'  => $foreignTable,
  166
+              'column'        => reset($columns),
  167
+              'relatedColumn' => reset($relatedColumns),
  168
+            );
  169
+            continue 2;
  170
+          }
166 171
         }
167 172
       }
168 173
     }
  174
+
  175
+    //Keep BC with M2M without isCrossRef = true
  176
+    foreach ($relations as $relation)
  177
+    {
  178
+      $middleTable = $relation->getLocalTable();
  179
+      //check if $middleTable is a Many 2 Many :
  180
+      // exclude already found middle table
  181
+      // if there it has 2  PKs
  182
+      // if there id only 2 columns in the table
  183
+      // if PKs are also FKs
  184
+      // if PKs point two different tables
  185
+      if (!isset($middleTables[$middleTable->getClassname()])
  186
+         && 2 === count($pks = $middleTable->getPrimaryKeyColumns())
  187
+         && 2 === count($middleTable->getColumns())
  188
+         && $pks[0]->isForeignKey()
  189
+         && $pks[1]->isForeignKey()
  190
+         && $pks[0]->getRelatedTableName() != $pks[1]->getRelatedTableName())
  191
+      {
  192
+        //We found a Many to Many middle table
  193
+        $foreignTable = $pks[0]->getRelatedTableName() != $this->table->getName() ? $pks[0]->getRelatedTable() : $pks[1]->getRelatedTable();
  194
+        $relatedColumn = $pks[0]->getRelatedTableName() != $this->table->getName() ? $pks[0] : $pks[1];
  195
+        $columns = $relation->getLocalColumns();
  196
+
  197
+        $tables[] = array(
  198
+          'middleTable'   => $middleTable,
  199
+          'relatedTable'  => $foreignTable,
  200
+          'column'        => reset($columns),
  201
+          'relatedColumn' => $relatedColumn,
  202
+        );
  203
+      }
  204
+    }
  205
+
169 206
     return $tables;
170 207
   }
171 208
 
62  lib/generator/sfPropelGenerator.class.php
@@ -66,11 +66,13 @@ public function getTableMap()
66 66
   public function getManyToManyTables()
67 67
   {
68 68
     $tables = array();
  69
+    $middleTables = array();
69 70
     $foreignTables = array();
70 71
     $relations = array();
71 72
 
72 73
     // go through all relations
73  
-    foreach  ($this->getTableMap()->getRelations() as $relation)
  74
+    $table = $this->getTableMap();
  75
+    foreach  ($table->getRelations() as $relation)
74 76
     {
75 77
       //we have a many to many Relation
76 78
       if (RelationMap::MANY_TO_MANY === $relation->getType())
@@ -88,26 +90,62 @@ public function getManyToManyTables()
88 90
     {
89 91
       foreach ($foreignTable->getRelations() as $foreignRelation)
90 92
       {
91  
-        $foreignTableName = $foreignRelation->getLocalTable()->getClassname();
  93
+        $foreignTableClassname = $foreignRelation->getLocalTable()->getClassname();
92 94
 
93 95
         // Test if the foreign table has a common relation with our table
94  
-        // TODO: test if is CrossRef
95 96
         if (RelationMap::ONE_TO_MANY === $foreignRelation->getType()
96  
-            && array_key_exists($foreignTableName, $relations))
  97
+            && array_key_exists($foreignTableClassname, $relations))
97 98
         {
98  
-          $columns = $relations[$foreignTableName]->getLocalColumns();
  99
+          $columns = $relations[$foreignTableClassname]->getLocalColumns();
99 100
           $relatedColumns = $foreignRelation->getLocalColumns();
100 101
 
101  
-          $tables[] = array(
102  
-            'middleTable'   => $foreignRelation->getLocalTable(),
103  
-            'relatedTable'  => $foreignTable,
104  
-            'column'        => reset($columns),
105  
-            'relatedColumn' => reset($relatedColumns),
106  
-          );
107  
-          continue 2;
  102
+          $middleTable = $foreignRelation->getLocalTable();
  103
+          $middleTables[$middleTable->getClassname()] = $middleTable;
  104
+          if ($middleTable->isCrossRef())
  105
+          {
  106
+            $tables[] = array(
  107
+              'middleTable'   => $middleTable,
  108
+              'relatedTable'  => $foreignTable,
  109
+              'column'        => reset($columns),
  110
+              'relatedColumn' => reset($relatedColumns),
  111
+            );
  112
+            continue 2;
  113
+          }
108 114
         }
109 115
       }
110 116
     }
  117
+
  118
+    //Keep BC with M2M without isCrossRef = true
  119
+    foreach ($relations as $relation)
  120
+    {
  121
+      $middleTable = $relation->getLocalTable();
  122
+      //check if $middleTable is a Many 2 Many :
  123
+      // exclude already found middle table
  124
+      // if there it has 2  PKs
  125
+      // if there id only 2 columns in the table
  126
+      // if PKs are also FKs
  127
+      // if PKs point two different tables
  128
+      if (!isset($middleTables[$middleTable->getClassname()])
  129
+        && 2 === count($pks = $middleTable->getPrimaryKeyColumns())
  130
+        && 2 === count($middleTable->getColumns())
  131
+        && $pks[0]->isForeignKey()
  132
+        && $pks[1]->isForeignKey()
  133
+        && $pks[0]->getRelatedTableName() != $pks[1]->getRelatedTableName())
  134
+      {
  135
+        //We found a Many to Many middle table
  136
+        $foreignTable = $pks[0]->getRelatedTableName() != $table->getName() ? $pks[0]->getRelatedTable() : $pks[1]->getRelatedTable();
  137
+        $relatedColumn = $pks[0]->getRelatedTableName() != $table->getName() ? $pks[0] : $pks[1];
  138
+        $columns = $relation->getLocalColumns();
  139
+
  140
+        $tables[] = array(
  141
+          'middleTable'   => $middleTable,
  142
+          'relatedTable'  => $foreignTable,
  143
+          'column'        => reset($columns),
  144
+          'relatedColumn' => $relatedColumn,
  145
+        );
  146
+      }
  147
+    }
  148
+
111 149
     return $tables;
112 150
   }
113 151
 
23  test/functional/fixtures/config/schema.xml
@@ -46,7 +46,7 @@
46 46
     <column name="hobbies" type="array" required="false" />
47 47
   </table>
48 48
 
49  
-  <table name="author_article" isCrossref="true">
  49
+  <table name="author_article">
50 50
     <behavior name="symfony">
51 51
       <parameter name="form" value="false"/>
52 52
       <parameter name="filter" value="false"/>
@@ -151,11 +151,12 @@
151 151
     <column name="enum_values" type="enum" valueSet="one, two, three space" />
152 152
   </table>
153 153
 
154  
-  <!-- model and data for testing many to many -->
  154
+  <!-- model and data for testing many to many without isCrossRef -->
155 155
   <table name="seller">
156 156
     <column name="id" type="integer" required="true" primaryKey="true" autoincrement="true" />
157 157
     <column name="name" type="varchar" size="255" />
158 158
   </table>
  159
+
159 160
   <table name="sale">
160 161
     <column name="seller_id" type="integer" primaryKey="true" />
161 162
     <column name="book_id" type="integer" primaryKey="true" />
@@ -167,4 +168,22 @@
167 168
       <reference local="book_id" foreign="id" />
168 169
     </foreign-key>
169 170
   </table>
  171
+
  172
+  <table name="extra_seller" isCrossRef="true">
  173
+    <column name="seller_id" type="integer" primaryKey="true" />
  174
+    <column name="extra_id" type="integer" primaryKey="true" />
  175
+    <column name="comment" type="varchar" size="255" required="false" />
  176
+    <foreign-key foreignTable="seller">
  177
+      <reference local="seller_id" foreign="id" />
  178
+    </foreign-key>
  179
+    <foreign-key foreignTable="extra">
  180
+      <reference local="extra_id" foreign="id" />
  181
+    </foreign-key>
  182
+  </table>
  183
+
  184
+  <table name="extra">
  185
+    <column name="id" type="integer" required="true" primaryKey="true" autoincrement="true" />
  186
+    <column name="name" type="varchar" size="255" />
  187
+    <column name="useless" type="varchar" size="255" />
  188
+  </table>
170 189
 </database>
3  test/functional/formTest.php
@@ -308,3 +308,6 @@
308 308
 } catch (InvalidArgumentException $e) {
309 309
     $b->test()->pass('The book form shoud not has sale_list field because it is not a many to many relation');
310 310
 }
  311
+
  312
+$form = new SellerForm();
  313
+$b->test()->isa_ok($form->getWidget('extra_seller_list'), 'sfWidgetFormPropelChoice', 'The Seller form should have a sfWidgetFormPropelChoice of extras when there is a isCrossRef on a middle table');

0 notes on commit d8e35ef

Please sign in to comment.
Something went wrong with that request. Please try again.