Report abuse


			
Index: tests/run.php
===================================================================
--- tests/run.php	(revision 4799)
+++ tests/run.php	(working copy)
@@ -118,6 +118,7 @@
 $tickets->addTestCase(new Doctrine_Ticket_1296_TestCase());
 $tickets->addTestCase(new Doctrine_Ticket_1304_TestCase());
 $tickets->addTestCase(new Doctrine_Ticket_1305_TestCase());
+$tickets->addTestCase(new Doctrine_Ticket_1323_TestCase());
 $test->addTestCase($tickets);

 // Connection Tests (not yet fully tested)
Index: tests/Relation/ManyToManyTestCase.php
===================================================================
--- tests/Relation/ManyToManyTestCase.php	(revision 4799)
+++ tests/Relation/ManyToManyTestCase.php	(working copy)
@@ -35,6 +35,7 @@
             $rel = $component->getTable()->getRelation('M2MTest2');
             $this->pass();
         } catch(Doctrine_Exception $e) {
+            echo $e->getMessage();
             $this->fail();
         }
         $this->assertEqual($rel->getForeign(), 'oid');
Index: tests/Ticket/1323TestCase.php
===================================================================
--- tests/Ticket/1323TestCase.php	(revision 0)
+++ tests/Ticket/1323TestCase.php	(revision 0)
@@ -0,0 +1,225 @@
+tables = array();
+        $this->tables[] = "T1323User";
+        $this->tables[] = "T1323UserReference";
+        parent::prepareTables();
+    }
+    
+    public function prepareData() {}
+
+    public function resetData()
+    {
+      $q = Doctrine_Query::create();
+      $q->delete()->from("T1323UserReference")->execute();
+      $q = Doctrine_Query::create();
+      $q->delete()->from("T1323User")->execute();
+
+      $m = new T1323User();
+      $m->name = "Mother";
+      $m->save();
+      $f = new T1323User();
+      $f->name = "Father";
+      $f->save();
+      $s = new T1323User();
+      $s->name = "Son";
+      $s->save();
+      $d = new T1323User();
+      $d->name = "Daughter";
+      $d->save();
+      $gf = new T1323User();
+      $gf->name = "Grandfather";
+      $gf->save();
+      $gm = new T1323User();
+      $gm->name = "Grandmother";
+      $gm->save();
+      
+      $f->Children[] = $s;
+      $f->Children[] = $d;
+      
+      $f->Parents[] = $gf;
+      $f->Parents[] = $gm;
+      
+      $f->save();
+      
+      $m->Children[] = $s;
+      $m->Children[] = $d;
+      
+      $m->save();      
+
+    }
+    
+    public function testRelationsAreCorrect() {
+        $this->resetData();
+        
+        $f = Doctrine::getTable("T1323User")->findOneByName("Father");
+        $childLinks = $f->childLinks;
+        $this->assertEqual(2, count($childLinks));
+        $this->assertEqual($f->id, $childLinks[0]->parent_id);
+        $this->assertEqual($f->id, $childLinks[1]->parent_id);
+        
+        $parentLinks = $f->parentLinks;
+        $this->assertEqual(2, count($parentLinks));
+        $this->assertEqual($f->id, $parentLinks[0]->child_id);
+        $this->assertEqual($f->id, $parentLinks[1]->child_id);
+        
+        $m = Doctrine::getTable("T1323User")->findOneByName("Mother");
+        $childLinks = $m->childLinks;
+        $this->assertEqual(2, count($childLinks));
+        $this->assertEqual($m->id, $childLinks[0]->parent_id);
+        $this->assertEqual($m->id, $childLinks[1]->parent_id);
+        
+        $parentLinks = $m->parentLinks;
+        $this->assertEqual(0, count($parentLinks));
+        
+        $s = Doctrine::getTable("T1323User")->findOneByName("Son");
+        $childLinks = $s->childLinks;
+        $this->assertEqual(0, count($childLinks));
+        $parentLinks = $s->parentLinks;
+        $this->assertEqual(2, count($parentLinks));
+        $this->assertEqual($s->id, $parentLinks[0]->child_id);
+        $this->assertEqual($s->id, $parentLinks[1]->child_id);
+        
+        $d = Doctrine::getTable("T1323User")->findOneByName("Daughter");
+        $childLinks = $d->childLinks;
+        $this->assertEqual(0, count($childLinks));
+        $parentLinks = $d->parentLinks;
+        $this->assertEqual(2, count($parentLinks));
+        $this->assertEqual($d->id, $parentLinks[0]->child_id);
+        $this->assertEqual($d->id, $parentLinks[1]->child_id);
+        
+        $gm = Doctrine::getTable("T1323User")->findOneByName("Grandmother");
+        $childLinks = $gm->childLinks;
+        $this->assertEqual(1, count($childLinks));
+        $this->assertEqual($gm->id, $childLinks[0]->parent_id);
+        $parentLinks = $gm->parentLinks;
+        $this->assertEqual(0, count($parentLinks));
+        
+        $gf = Doctrine::getTable("T1323User")->findOneByName("Grandfather");
+        $childLinks = $gf->childLinks;
+        $this->assertEqual(1, count($childLinks));
+        $this->assertEqual($gf->id, $childLinks[0]->parent_id);
+        $parentLinks = $gf->parentLinks;
+        $this->assertEqual(0, count($parentLinks));
+    }
+
+   /**
+    * this test will fail
+    */       
+   public function testWithShow() {
+      $this->resetData();
+      
+      T1323User::showAllRelations();
+      $this->runTests();
+   }
+
+   /**
+    * this test will pass
+    */       
+   public function testWithoutShow() {
+      $this->resetData();
+      
+      $this->runTests();
+   }
+
+    
+    public function runTests() {
+        
+      // change "Father"'s name...
+      $f = Doctrine::getTable("T1323User")->findOneByName("Father");
+      $f->name = "Dad";
+      $f->save(); 
+      
+      /*  just playing; makes no difference: 
+          remove "Dad"'s relation to "Son"... */
+      //$s = Doctrine::getTable("T1323User")->findOneByName("Son");
+      //$f->unlink("Children", array($s->id));
+      //$f->save();
+      
+      $relations = Doctrine::getTable("T1323UserReference")->findAll();
+      foreach ($relations as $relation) {
+        /*  never directly touched any relation; so no user should have 
+            himself as parent or child */ 
+        $this->assertNotEqual($relation->parent_id, $relation->child_id);
+      }
+    }
+}
+  
+
+  
+class T1323User extends Doctrine_Record
+{
+    public function setTableDefinition()
+    {
+        $this->hasColumn('name', 'string', 30);
+    }
+
+    public function setUp()
+    {
+        $this->hasMany('T1323User as Parents', array('local' => 'child_id',
+                                                'foreign'  => 'parent_id',
+                                                'refClass' => 'T1323UserReference',
+                                                'refClassRelation' => 'childLinks'
+                                                ));
+
+        $this->hasMany('T1323User as Children', array('local' => 'parent_id',
+                                                 'foreign'  => 'child_id',
+                                                 'refClass' => 'T1323UserReference',
+                                                 'refClassRelation' => 'parentLinks'
+                                                 ));
+    }
+    
+    /**
+     * just a little function to show all users and their relations
+     */         
+    public static function showAllRelations() {
+        $users = Doctrine::getTable("T1323User")->findAll();
+        
+        //echo "=========================================
".PHP_EOL; + //echo "list of all existing users and their relations:
".PHP_EOL; + //echo "=========================================

".PHP_EOL.PHP_EOL; + + foreach ($users as $user) { + $parents = $user->Parents; + $children = $user->Children; + + /*echo "user: "; + echo $user->name; + echo PHP_EOL."
"; + + echo "parents:"; + echo PHP_EOL."
"; + foreach ($parents as $parent) { + echo $parent->name; + echo PHP_EOL."
"; + } + echo PHP_EOL."
"; + + echo "children:"; + echo PHP_EOL."
"; + foreach ($children as $child) { + echo $child->name; + echo PHP_EOL."
"; + } + echo PHP_EOL."
"; + echo "--------------".PHP_EOL."
"; + echo PHP_EOL."
";*/ + } + } +} + +class T1323UserReference extends Doctrine_Record +{ + public function setTableDefinition() + { + //$this->hasColumn('id', 'integer', null, array('primary' => true, 'autoincrement' => true)); + $this->hasColumn('parent_id', 'integer', null, array('primary' => true)); + $this->hasColumn('child_id', 'integer', null, array('primary' => true)); + } +} + + + +?> Index: lib/Doctrine/Relation.php =================================================================== --- lib/Doctrine/Relation.php (revision 4799) +++ lib/Doctrine/Relation.php (working copy) @@ -79,6 +79,7 @@ 'equal' => false, 'cascade' => array(), // application-level cascades 'owningSide' => false, // whether this is the owning side + 'refClassRelation' => null, ); /** Index: lib/Doctrine/Relation/Nest.php =================================================================== --- lib/Doctrine/Relation/Nest.php (revision 4799) +++ lib/Doctrine/Relation/Nest.php (working copy) @@ -38,7 +38,7 @@ * @param integer $count * @return string */ - public function getRelationDql($count, $context = 'record') + /*public function getRelationDql($count, $context = 'record') { switch ($context) { case 'record': @@ -72,9 +72,8 @@ }; return $dql; - } + }*/ - /** public function fetchRelatedFor(Doctrine_Record $record) { $id = $record->getIncremented(); @@ -82,32 +81,6 @@ if (empty($id) || ! $this->definition['table']->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) { return new Doctrine_Collection($this->getTable()); } else { - $q = new Doctrine_Query(); - - $c = $this->getTable()->getComponentName(); - $a = substr($c, 0, 1); - $c2 = $this->getAssociationTable()->getComponentName(); - $a2 = substr($c2, 0, 1); - - $q->from($c) - ->innerJoin($c . '.' . $c2) - - $sub = 'SELECT ' . $this->getForeign() - . ' FROM ' . $c2 - . ' WHERE ' . $this->getLocal() - . ' = ?'; - } - } - */ - - public function fetchRelatedFor(Doctrine_Record $record) - { - $id = $record->getIncremented(); - - - if (empty($id) || ! $this->definition['table']->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) { - return new Doctrine_Collection($this->getTable()); - } else { $q = new Doctrine_RawSql($this->getTable()->getConnection()); $assocTable = $this->getAssociationFactory()->getTableName(); @@ -136,11 +109,17 @@ ->from($tableName . ' INNER JOIN ' . $assocTable . ' ON ' . implode(' OR ', $joinCondition)) ->where(implode(' OR ', $condition)); $q->addComponent($tableName, $record->getTable()->getComponentName()); - $q->addComponent($assocTable, $record->getTable()->getComponentName(). '.' . $this->getAssociationFactory()->getComponentName()); + + $path = $record->getTable()->getComponentName(). '.' . $this->getAssociationFactory()->getComponentName(); + if ($this->definition['refClassRelation']) { + $path = $record->getTable()->getComponentName(). '.' . $this->definition['refClassRelation']; + } + $q->addComponent($assocTable, $path); $params = ($this->definition['equal']) ? array($id, $id) : array($id); + $res = $q->execute($params); - return $q->execute($params); + return $res; } } } \ No newline at end of file Index: lib/Doctrine/Relation/Parser.php =================================================================== --- lib/Doctrine/Relation/Parser.php (revision 4799) +++ lib/Doctrine/Relation/Parser.php (working copy) @@ -155,22 +155,24 @@ if (isset($this->_relations[$alias])) { return $this->_relations[$alias]; } - + if (isset($this->_pending[$alias])) { $def = $this->_pending[$alias]; $identifierColumnNames = $this->_table->getIdentifierColumnNames(); $idColumnName = array_pop($identifierColumnNames); - + // check if reference class name exists // if it does we are dealing with association relation if (isset($def['refClass'])) { $def = $this->completeAssocDefinition($def); $localClasses = array_merge($this->_table->getOption('parents'), array($this->_table->getComponentName())); + + $backRefRelationName = isset($def['refClassRelation']) ? + $def['refClassRelation'] : $def['refClass']; + if ( ! isset($this->_pending[$backRefRelationName]) && ! isset($this->_relations[$backRefRelationName])) { - if ( ! isset($this->_pending[$def['refClass']]) && - ! isset($this->_relations[$def['refClass']])) { - $parser = $def['refTable']->getRelationParser(); + if ( ! $parser->hasRelation($this->_table->getComponentName())) { $parser->bind($this->_table->getComponentName(), array('type' => Doctrine_Relation::ONE, @@ -180,10 +182,18 @@ )); } - if ( ! $this->hasRelation($def['refClass'])) { - $this->bind($def['refClass'], array('type' => Doctrine_Relation::MANY, - 'foreign' => $def['local'], - 'local' => $idColumnName)); + if ( ! $this->hasRelation($backRefRelationName)) { + if (in_array($def['class'], $localClasses)) { + $this->bind($def['refClass'] . " as " . $backRefRelationName, array( + 'type' => Doctrine_Relation::MANY, + 'foreign' => $def['foreign'], + 'local' => $idColumnName)); + } else { + $this->bind($def['refClass'] . " as " . $backRefRelationName, array( + 'type' => Doctrine_Relation::MANY, + 'foreign' => $def['local'], + 'local' => $idColumnName)); + } } } if (in_array($def['class'], $localClasses)) { @@ -212,7 +222,6 @@ if (isset($rel)) { // unset pending relation unset($this->_pending[$alias]); - $this->_relations[$alias] = $rel; return $rel; } @@ -292,7 +301,6 @@ if ( ! isset($def['local'])) { // foreign key not set // try to guess the foreign key - $def['local'] = ($def['foreign'] === $id[0]) ? $id[1] : $id[0]; } } else { Index: lib/Doctrine/Collection.php =================================================================== --- lib/Doctrine/Collection.php (revision 4799) +++ lib/Doctrine/Collection.php (working copy) @@ -263,8 +263,7 @@ $this->relation = $relation; if ($relation instanceof Doctrine_Relation_ForeignKey || - $relation instanceof Doctrine_Relation_LocalKey) { - + $relation instanceof Doctrine_Relation_LocalKey) { $this->referenceField = $relation->getForeignFieldName(); $value = $record->get($relation->getLocalFieldName()); @@ -441,7 +440,6 @@ { if (isset($this->referenceField)) { $value = $this->reference->get($this->relation->getLocalFieldName()); - if ($value !== null) { $record->set($this->referenceField, $value, false); } else { Index: lib/Doctrine/Record.php =================================================================== --- lib/Doctrine/Record.php (revision 4799) +++ lib/Doctrine/Record.php (working copy) @@ -958,7 +958,7 @@ $old = $this->_data[$fieldName]; } - if ($this->_isValueModified($type, $old, $value)) { + if ($this->_isValueModified($type, $old, $value)) { if ($value === null) { $default = $this->_table->getDefaultValueOf($fieldName); $value = ($default === null) ? self::$_null : $default; @@ -1142,7 +1142,7 @@ * @return void */ public function save(Doctrine_Connection $conn = null) - { + { if ($conn === null) { $conn = $this->_table->getConnection(); }