2006-05-30 12:42:10 +04:00
|
|
|
<?php
|
2006-07-27 21:51:19 +04:00
|
|
|
/*
|
|
|
|
* $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>.
|
|
|
|
*/
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* Doctrine_Relation
|
2006-07-27 21:51:19 +04:00
|
|
|
* This class represents a relation between components
|
2006-05-30 12:42:10 +04:00
|
|
|
*
|
|
|
|
* @package Doctrine ORM
|
|
|
|
* @url www.phpdoctrine.com
|
|
|
|
* @license LGPL
|
|
|
|
*/
|
|
|
|
class Doctrine_Relation {
|
|
|
|
/**
|
|
|
|
* RELATION CONSTANTS
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* constant for ONE_TO_ONE and MANY_TO_ONE aggregate relationships
|
|
|
|
*/
|
|
|
|
const ONE_AGGREGATE = 0;
|
|
|
|
/**
|
|
|
|
* constant for ONE_TO_ONE and MANY_TO_ONE composite relationships
|
|
|
|
*/
|
|
|
|
const ONE_COMPOSITE = 1;
|
|
|
|
/**
|
|
|
|
* constant for MANY_TO_MANY and ONE_TO_MANY aggregate relationships
|
|
|
|
*/
|
|
|
|
const MANY_AGGREGATE = 2;
|
|
|
|
/**
|
|
|
|
* constant for MANY_TO_MANY and ONE_TO_MANY composite relationships
|
|
|
|
*/
|
|
|
|
const MANY_COMPOSITE = 3;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2006-06-22 00:02:40 +04:00
|
|
|
* @var Doctrine_Table $table foreign factory
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
2006-08-16 01:33:18 +04:00
|
|
|
protected $table;
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* @var string $local local field
|
|
|
|
*/
|
2006-08-16 01:33:18 +04:00
|
|
|
protected $local;
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* @var string $foreign foreign field
|
|
|
|
*/
|
2006-08-16 01:33:18 +04:00
|
|
|
protected $foreign;
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* @var integer $type bind type
|
|
|
|
*/
|
2006-08-16 01:33:18 +04:00
|
|
|
protected $type;
|
2006-06-25 22:34:53 +04:00
|
|
|
/**
|
|
|
|
* @var string $alias relation alias
|
|
|
|
*/
|
2006-08-16 01:33:18 +04:00
|
|
|
protected $alias;
|
2006-06-22 00:02:40 +04:00
|
|
|
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* @param Doctrine_Table $table
|
|
|
|
* @param string $local
|
|
|
|
* @param string $foreign
|
|
|
|
* @param integer $type
|
2006-06-22 00:02:40 +04:00
|
|
|
* @param string $alias
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
2006-06-26 22:55:42 +04:00
|
|
|
public function __construct(Doctrine_Table $table, $local, $foreign, $type, $alias) {
|
2006-05-30 12:42:10 +04:00
|
|
|
$this->table = $table;
|
|
|
|
$this->local = $local;
|
|
|
|
$this->foreign = $foreign;
|
|
|
|
$this->type = $type;
|
2006-06-26 22:55:42 +04:00
|
|
|
$this->alias = $alias;
|
2006-05-30 12:42:10 +04:00
|
|
|
}
|
2006-06-25 22:34:53 +04:00
|
|
|
/**
|
|
|
|
* @return string the relation alias
|
|
|
|
*/
|
2006-07-22 03:22:15 +04:00
|
|
|
final public function getAlias() {
|
2006-06-25 22:34:53 +04:00
|
|
|
return $this->alias;
|
|
|
|
}
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
2006-06-22 00:02:40 +04:00
|
|
|
* @return integer the relation type, either 0 or 1
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
2006-07-22 03:22:15 +04:00
|
|
|
final public function getType() {
|
2006-05-30 12:42:10 +04:00
|
|
|
return $this->type;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @return object Doctrine_Table foreign factory object
|
|
|
|
*/
|
2006-07-22 03:22:15 +04:00
|
|
|
final public function getTable() {
|
2006-05-30 12:42:10 +04:00
|
|
|
return $this->table;
|
|
|
|
}
|
|
|
|
/**
|
2006-06-22 00:02:40 +04:00
|
|
|
* @return string the name of the local column
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
2006-07-22 03:22:15 +04:00
|
|
|
final public function getLocal() {
|
2006-05-30 12:42:10 +04:00
|
|
|
return $this->local;
|
|
|
|
}
|
|
|
|
/**
|
2006-06-22 00:02:40 +04:00
|
|
|
* @return string the name of the foreignkey column where
|
|
|
|
* the localkey column is pointing at
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
2006-07-22 03:22:15 +04:00
|
|
|
final public function getForeign() {
|
2006-05-30 12:42:10 +04:00
|
|
|
return $this->foreign;
|
|
|
|
}
|
2006-08-16 01:33:18 +04:00
|
|
|
/**
|
|
|
|
* getRelationDql
|
|
|
|
*
|
|
|
|
* @param integer $count
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getRelationDql($count) {
|
|
|
|
$dql = "FROM ".$this->table->getComponentName().
|
|
|
|
" WHERE ".$this->table->getComponentName(). '.' . $this->foreign.
|
|
|
|
" IN (".substr(str_repeat("?, ", $count),0,-2).")";
|
|
|
|
|
|
|
|
return $dql;
|
|
|
|
}
|
2006-07-10 22:10:54 +04:00
|
|
|
/**
|
|
|
|
* getDeleteOperations
|
|
|
|
*
|
|
|
|
* get the records that need to be deleted in order to change the old collection
|
|
|
|
* to the new one
|
|
|
|
*
|
|
|
|
* The algorithm here is very simple and definitely not
|
|
|
|
* the fastest one, since we have to iterate through the collections twice.
|
|
|
|
* the complexity of this algorithm is O(n^2)
|
|
|
|
*
|
|
|
|
* 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).
|
|
|
|
*/
|
|
|
|
final public static function getDeleteOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
|
|
|
|
$r = array();
|
|
|
|
|
|
|
|
foreach($old as $k => $record) {
|
|
|
|
$id = $record->getIncremented();
|
|
|
|
|
|
|
|
if(empty($id))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
$found = false;
|
|
|
|
foreach($new as $k2 => $record2) {
|
|
|
|
if($record2->getIncremented() === $record->getIncremented()) {
|
|
|
|
$found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ! $found) {
|
|
|
|
$r[] = $record;
|
|
|
|
unset($old[$k]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* getInsertOperations
|
|
|
|
*
|
|
|
|
* get the records that need to be added in order to change the old collection
|
|
|
|
* to the new one
|
|
|
|
*
|
|
|
|
* The algorithm here is very simple and definitely not
|
|
|
|
* the fastest one, since we have to iterate through the collections twice.
|
|
|
|
* the complexity of this algorithm is O(n^2)
|
|
|
|
*
|
|
|
|
* We iterate through the old collection and get the records
|
|
|
|
* that exists only in the new collection (Doctrine_Records that need to be added).
|
|
|
|
*/
|
|
|
|
final public static function getInsertOperations(Doctrine_Collection $old, Doctrine_Collection $new) {
|
|
|
|
$r = array();
|
|
|
|
|
|
|
|
foreach($new as $k => $record) {
|
|
|
|
$found = false;
|
|
|
|
|
|
|
|
$id = $record->getIncremented();
|
|
|
|
if( ! empty($id)) {
|
|
|
|
foreach($old as $k2 => $record2) {
|
|
|
|
if($record2->getIncremented() === $record->getIncremented()) {
|
|
|
|
$found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( ! $found) {
|
|
|
|
$old[] = $record;
|
|
|
|
$r[] = $record;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $r;
|
|
|
|
}
|
2006-05-30 12:42:10 +04:00
|
|
|
/**
|
|
|
|
* __toString
|
2006-07-22 03:22:15 +04:00
|
|
|
*
|
|
|
|
* @return string
|
2006-05-30 12:42:10 +04:00
|
|
|
*/
|
|
|
|
public function __toString() {
|
|
|
|
$r[] = "<pre>";
|
|
|
|
$r[] = "Class : ".get_class($this);
|
|
|
|
$r[] = "Component : ".$this->table->getComponentName();
|
|
|
|
$r[] = "Table : ".$this->table->getTableName();
|
|
|
|
$r[] = "Local key : ".$this->local;
|
|
|
|
$r[] = "Foreign key : ".$this->foreign;
|
|
|
|
$r[] = "Type : ".$this->type;
|
|
|
|
$r[] = "</pre>";
|
|
|
|
return implode("\n", $r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
?>
|