Commit c8c1397f authored by zYne's avatar zYne

fixes #133

Ticket: 133
parent 1ab5a4fc
......@@ -78,5 +78,22 @@ class Doctrine_Association extends Doctrine_Relation {
return $dql;
}
/**
* fetchRelatedFor
*
* fetches a component related to given record
*
* @param Doctrine_Record $record
* @return Doctrine_Record|Doctrine_Collection
*/
public function fetchRelatedFor(Doctrine_Record $record) {
$id = $record->getIncremented();
if(empty($id))
$coll = new Doctrine_Collection($this->table);
else
$coll = Doctrine_Query::create()->parseQuery($this->getRelationDql(1))->execute(array($id));
return $coll;
}
}
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine::autoload('Doctrine_Relation');
/**
* Foreign Key
* Doctrine_ForeignKey
* This class represents a foreign key relation
*
* @author Konsta Vesterinen
* @license LGPL
* @package Doctrine
*/
class Doctrine_ForeignKey extends Doctrine_Relation { }
class Doctrine_ForeignKey extends Doctrine_Relation {
/**
* fetchRelatedFor
*
* fetches a component related to given record
*
* @param Doctrine_Record $record
* @return Doctrine_Record|Doctrine_Collection
*/
public function fetchRelatedFor(Doctrine_Record $record) {
$id = $record->get($this->local);
if($this->isOneToOne()) {
if(empty($id)) {
$related = $this->table->create();
} else {
$dql = "FROM ".$this->table->getComponentName()." WHERE ".$this->table->getComponentName().".".$this->foreign." = ?";
$coll = $this->table->getConnection()->query($dql, array($id));
$related = $coll[0];
}
$related->set($this->foreign, $record, false);
} else {
if(empty($id)) {
$related = new Doctrine_Collection($this->table);
} else {
$query = $this->getRelationDql(1);
$related = $this->table->getConnection()->query($query, array($id));
}
$related->setReference($record, $this);
}
return $related;
}
}
......@@ -28,13 +28,26 @@ Doctrine::autoload('Doctrine_Relation');
* @package Doctrine
*/
class Doctrine_LocalKey extends Doctrine_Relation {
public function fetch($id = null) {
/**
* fetchRelatedFor
*
* fetches a component related to given record
*
* @param Doctrine_Record $record
* @return Doctrine_Record|Doctrine_Collection
*/
public function fetchRelatedFor(Doctrine_Record $record) {
$id = $record->get($this->local);
if(empty($id))
return $this->table->create();
$related = $this->table->create();
else {
$record = $this->table->find($id);
return ($record !== false) ? $record : $this->table->create();
if( ! ($related = $this->table->find($id)))
$related = $this->table->create();
}
$record->set($this->local, $related, false);
return $related;
}
}
......@@ -417,7 +417,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* parsers for each part
*
* @param string $query DQL query
* @return void
* @return Doctrine_Query
*/
public function parseQuery($query) {
$this->clear();
......@@ -483,6 +483,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
break;
endswitch;
}
return $this;
}
/**
* DQL ORDER BY PARSER
......
......@@ -731,46 +731,50 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
} else {
try {
$rel = $this->table->getRelation($name);
$this->coreSetRelated($name, $value);
} catch(Doctrine_Table_Exception $e) {
throw new Doctrine_Record_Exception("Unknown property / related component '$name'.");
}
// one-to-many or one-to-one relation
if($rel instanceof Doctrine_ForeignKey ||
$rel instanceof Doctrine_LocalKey) {
switch($rel->getType()):
case Doctrine_Relation::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
// one-to-many relation found
if( ! ($value instanceof Doctrine_Collection))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
$value->setReference($this,$rel);
break;
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
// one-to-one relation found
if( ! ($value instanceof Doctrine_Record))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references.");
if($rel->getLocal() == $this->table->getIdentifier()) {
$value->set($rel->getForeign(), $this, false);
} else {
$this->set($rel->getLocal(),$value);
}
break;
endswitch;
} elseif($rel instanceof Doctrine_Association) {
// join table relation found
if( ! ($value instanceof Doctrine_Collection))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
}
}
public function coreSetRelated($name, $value) {
$rel = $this->table->getRelation($name);
// one-to-many or one-to-one relation
if($rel instanceof Doctrine_ForeignKey ||
$rel instanceof Doctrine_LocalKey) {
switch($rel->getType()) {
case Doctrine_Relation::MANY_COMPOSITE:
case Doctrine_Relation::MANY_AGGREGATE:
// one-to-many relation found
if( ! ($value instanceof Doctrine_Collection))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
$value->setReference($this,$rel);
break;
case Doctrine_Relation::ONE_COMPOSITE:
case Doctrine_Relation::ONE_AGGREGATE:
// one-to-one relation found
if( ! ($value instanceof Doctrine_Record))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record when setting one-to-one references.");
if($rel->getLocal() == $this->table->getIdentifier()) {
$value->set($rel->getForeign(), $this, false);
} else {
$this->set($rel->getLocal(),$value);
}
break;
}
$this->references[$name] = $value;
} elseif($rel instanceof Doctrine_Association) {
// join table relation found
if( ! ($value instanceof Doctrine_Collection))
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting one-to-many references.");
}
$this->references[$name] = $value;
}
/**
* contains
......@@ -782,6 +786,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if(isset($this->data[$name]))
return true;
if(isset($this->id[$name]))
return true;
if(isset($this->references[$name]))
return true;
......@@ -1211,70 +1218,14 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
final public function loadReference($name) {
$fk = $this->table->getRelation($name);
$table = $fk->getTable();
$local = $fk->getLocal();
$foreign = $fk->getForeign();
$graph = $table->getQueryObject();
$type = $fk->getType();
if( ! $this->exists()) {
if($fk->isOneToOne()) {
// ONE-TO-ONE
$this->references[$name] = $table->create();
if($fk instanceof Doctrine_ForeignKey) {
$this->references[$name]->set($fk->getForeign(),$this);
} else {
$this->set($fk->getLocal(),$this->references[$name]);
}
} else {
$this->references[$name] = new Doctrine_Collection($table);
if($fk instanceof Doctrine_ForeignKey) {
// ONE-TO-MANY
$this->references[$name]->setReference($this,$fk);
}
$this->originals[$name] = new Doctrine_Collection($table);
}
} else {
if($fk->isOneToOne()) {
// ONE-TO-ONE
$id = $this->get($local);
if($fk instanceof Doctrine_LocalKey) {
$this->references[$name] = $fk->fetch($id);
$this->set($fk->getLocal(), $this->references[$name], false);
} elseif ($fk instanceof Doctrine_ForeignKey) {
if(empty($id)) {
$this->references[$name] = $table->create();
} else {
$dql = "FROM ".$table->getComponentName()." WHERE ".$table->getComponentName().".".$fk->getForeign()." = ?";
$coll = $graph->query($dql, array($id));
$this->references[$name] = $coll[0];
}
$this->references[$name]->set($fk->getForeign(), $this);
}
} else {
if($fk->isOneToOne()) {
$this->references[$name] = $fk->fetchRelatedFor($this);
} else {
$coll = $fk->fetchRelatedFor($this);
$query = $fk->getRelationDql(1);
// ONE-TO-MANY
if($fk instanceof Doctrine_ForeignKey) {
$id = $this->get($local);
$coll = $graph->query($query,array($id));
$coll->setReference($this, $fk);
} elseif($fk instanceof Doctrine_Association_Self) {
$coll = $fk->fetchRelatedFor($this);
} elseif($fk instanceof Doctrine_Association) {
$id = $this->getIncremented();
$coll = $graph->query($query, array($id));
}
$this->references[$name] = $coll;
$this->originals[$name] = clone $coll;
}
$this->references[$name] = $coll;
$this->originals[$name] = clone $coll;
}
}
/**
......
......@@ -26,7 +26,7 @@
* @url www.phpdoctrine.com
* @license LGPL
*/
class Doctrine_Relation {
abstract class Doctrine_Relation {
/**
* RELATION CONSTANTS
*/
......@@ -166,6 +166,10 @@ class Doctrine_Relation {
*
* We iterate through the old collection and get the records
* that do not exists in the new collection (Doctrine_Records that need to be deleted).
*
* @param Doctrine_Collection $old
* @param Doctrine_Collection $new
* @return array
*/
public static function getDeleteOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
$r = array();
......@@ -204,6 +208,10 @@ class Doctrine_Relation {
*
* We iterate through the old collection and get the records
* that exists only in the new collection (Doctrine_Records that need to be added).
*
* @param Doctrine_Collection $old
* @param Doctrine_Collection $new
* @return array
*/
public static function getInsertOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
$r = array();
......@@ -228,6 +236,15 @@ class Doctrine_Relation {
return $r;
}
/**
* fetchRelatedFor
*
* fetches a component related to given record
*
* @param Doctrine_Record $record
* @return Doctrine_Record|Doctrine_Collection
*/
abstract public function fetchRelatedFor(Doctrine_Record $record);
/**
* __toString
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment