|
|
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();
}
|