drafting the new relation model, still a lot of work
This commit is contained in:
parent
b3b1f617fe
commit
71338c3d09
@ -79,7 +79,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
||||
// skip self-referenced relations
|
||||
if ($name === $nm) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($rel instanceof Doctrine_Relation_ForeignKey) {
|
||||
if ($index2 !== false) {
|
||||
@ -257,10 +257,11 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
||||
}
|
||||
}
|
||||
/**
|
||||
* update
|
||||
* updates the given record
|
||||
*
|
||||
* @param Doctrine_Record $record
|
||||
* @return boolean
|
||||
* @param Doctrine_Record $record record to be updated
|
||||
* @return boolean whether or not the update was successful
|
||||
*/
|
||||
public function update(Doctrine_Record $record)
|
||||
{
|
||||
@ -301,7 +302,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
||||
. ' WHERE ' . implode(' = ? AND ', $record->getTable()->getPrimaryKeys())
|
||||
. ' = ?';
|
||||
|
||||
$stmt = $this->conn->getDBH()->prepare($sql);
|
||||
$stmt = $this->conn->getDbh()->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
|
||||
$record->assignIdentifier(true);
|
||||
@ -335,7 +336,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
|
||||
$id = $this->conn->sequence->nextId($seq);
|
||||
$name = $record->getTable()->getIdentifier();
|
||||
$array[$name] = $id;
|
||||
|
||||
|
||||
$record->assignIdentifier($id);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
$this->stmt = $stmt;
|
||||
|
||||
if ($stmt === false) {
|
||||
throw new Doctrine_Db_Exception('Unknown statement object given.');
|
||||
throw new Doctrine_Db_Exception('Unknown statement object given.');
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -205,7 +205,11 @@ class Doctrine_Db_Statement implements Doctrine_Adapter_Statement_Interface
|
||||
$skip = $this->adapter->getListener()->onPreExecute($event);
|
||||
|
||||
if ( ! $skip) {
|
||||
$this->stmt->execute($params);
|
||||
if (isset($params[0]) && is_array($params[0])) {
|
||||
print_r($params);
|
||||
throw new Exception();
|
||||
}
|
||||
$this->stmt->execute((array) $params);
|
||||
$this->adapter->incrementQueryCount();
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,13 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
|
||||
* @var array $_enumParams an array containing the keys of the parameters that should be enumerated
|
||||
*/
|
||||
protected $_enumParams = array();
|
||||
/**
|
||||
* @var array $_options an array of options
|
||||
*/
|
||||
protected $_options = array(
|
||||
'fetchMode' => Doctrine::FETCH_RECORD,
|
||||
'cacheMode' => null,
|
||||
);
|
||||
/**
|
||||
* @var array $_dqlParts an array containing all DQL query parts
|
||||
*/
|
||||
@ -483,7 +490,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
|
||||
$q = 'UPDATE ';
|
||||
break;
|
||||
case self::SELECT:
|
||||
$distinct = ($this->isDistinct()) ? 'DISTINCT ' : '';
|
||||
$distinct = ($this->parts['distinct']) ? 'DISTINCT ' : '';
|
||||
|
||||
$q = 'SELECT ' . $distinct . implode(', ', $this->parts['select']) . ' FROM ';
|
||||
break;
|
||||
@ -565,11 +572,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
|
||||
|
||||
// build the basic query
|
||||
|
||||
$str = '';
|
||||
if ($this->isDistinct()) {
|
||||
$str = 'DISTINCT ';
|
||||
}
|
||||
|
||||
$q = $this->getQueryBase();
|
||||
$q .= $this->buildFromPart();
|
||||
|
||||
|
@ -901,8 +901,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
}
|
||||
|
||||
foreach ($saveLater as $fk) {
|
||||
$table = $fk->getTable();
|
||||
$alias = $this->_table->getAlias($table->getComponentName());
|
||||
$alias = $fk->getAlias();
|
||||
|
||||
if (isset($this->_references[$alias])) {
|
||||
$obj = $this->_references[$alias];
|
||||
@ -1011,8 +1010,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
$a[$v] = $this->_table->enumIndex($v,$this->_data[$v]);
|
||||
break;
|
||||
default:
|
||||
if ($this->_data[$v] instanceof Doctrine_Record)
|
||||
if ($this->_data[$v] instanceof Doctrine_Record) {
|
||||
$this->_data[$v] = $this->_data[$v]->getIncremented();
|
||||
}
|
||||
|
||||
$a[$v] = $this->_data[$v];
|
||||
}
|
||||
@ -1273,48 +1273,61 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ownsOne
|
||||
* binds One-to-One composite relation
|
||||
*
|
||||
* @param string $objTableName
|
||||
* @param string $fkField
|
||||
* @return void
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Record this object
|
||||
*/
|
||||
final public function ownsOne($componentName, $foreignKey, $options = null)
|
||||
public function ownsOne()
|
||||
{
|
||||
$this->_table->bind($componentName, $foreignKey, Doctrine_Relation::ONE_COMPOSITE, $options);
|
||||
$this->_table->bind(func_get_args(), Doctrine_Relation::ONE_COMPOSITE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* binds One-to-Many composite relation
|
||||
* ownsMany
|
||||
* binds One-to-Many / Many-to-Many composite relation
|
||||
*
|
||||
* @param string $objTableName
|
||||
* @param string $fkField
|
||||
* @return void
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Record this object
|
||||
*/
|
||||
final public function ownsMany($componentName, $foreignKey, $options = null)
|
||||
public function ownsMany()
|
||||
{
|
||||
$this->_table->bind($componentName, $foreignKey, Doctrine_Relation::MANY_COMPOSITE, $options);
|
||||
$this->_table->bind(func_get_args(), Doctrine_Relation::MANY_COMPOSITE);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* hasOne
|
||||
* binds One-to-One aggregate relation
|
||||
*
|
||||
* @param string $objTableName
|
||||
* @param string $fkField
|
||||
* @return void
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Record this object
|
||||
*/
|
||||
final public function hasOne($componentName, $foreignKey, $options = null)
|
||||
public function hasOne()
|
||||
{
|
||||
$this->_table->bind($componentName, $foreignKey, Doctrine_Relation::ONE_AGGREGATE, $options);
|
||||
$this->_table->bind(func_get_args(), Doctrine_Relation::ONE_AGGREGATE);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* binds One-to-Many aggregate relation
|
||||
* hasMany
|
||||
* binds One-to-Many / Many-to-Many aggregate relation
|
||||
*
|
||||
* @param string $objTableName
|
||||
* @param string $fkField
|
||||
* @return void
|
||||
* @param string $componentName the name of the related component
|
||||
* @param string $options relation options
|
||||
* @see Doctrine_Relation::_$definition
|
||||
* @return Doctrine_Record this object
|
||||
*/
|
||||
final public function hasMany($componentName, $foreignKey, $options = null)
|
||||
public function hasMany()
|
||||
{
|
||||
$this->_table->bind($componentName, $foreignKey, Doctrine_Relation::MANY_AGGREGATE, $options);
|
||||
$this->_table->bind(func_get_args(), Doctrine_Relation::MANY_AGGREGATE);
|
||||
return $this;
|
||||
}
|
||||
/**
|
||||
* hasColumn
|
||||
|
@ -62,7 +62,7 @@ abstract class Doctrine_Relation
|
||||
'class' => true,
|
||||
'type' => true,
|
||||
'name' => false,
|
||||
'assocTable' => false,
|
||||
'refTable' => false,
|
||||
'onDelete' => false,
|
||||
'onUpdate' => false,
|
||||
'deferred' => false,
|
||||
@ -80,7 +80,7 @@ abstract class Doctrine_Relation
|
||||
*
|
||||
* table the foreign table object
|
||||
*
|
||||
* assocTable the association table object (if any)
|
||||
* refTable the reference table object (if any)
|
||||
*
|
||||
* onDelete referential delete action
|
||||
*
|
||||
|
@ -40,11 +40,11 @@ class Doctrine_Relation_Association extends Doctrine_Relation
|
||||
*/
|
||||
public function getAssociationFactory()
|
||||
{
|
||||
return $this->definition['assocTable'];
|
||||
return $this->definition['refTable'];
|
||||
}
|
||||
public function getAssociationTable()
|
||||
{
|
||||
return $this->definition['assocTable'];
|
||||
return $this->definition['refTable'];
|
||||
}
|
||||
/**
|
||||
* getRelationDql
|
||||
@ -54,7 +54,7 @@ class Doctrine_Relation_Association extends Doctrine_Relation
|
||||
*/
|
||||
public function getRelationDql($count, $context = 'record')
|
||||
{
|
||||
$component = $this->definition['assocTable']->getComponentName();
|
||||
$component = $this->definition['refTable']->getComponentName();
|
||||
switch ($context) {
|
||||
case "record":
|
||||
$sub = 'SQL:SELECT ' . $this->definition['foreign'].
|
||||
|
@ -43,17 +43,17 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association
|
||||
switch ($context) {
|
||||
case 'record':
|
||||
$sub = 'SELECT '.$this->definition['foreign']
|
||||
. ' FROM '.$this->definition['assocTable']->getTableName()
|
||||
. ' FROM '.$this->definition['refTable']->getTableName()
|
||||
. ' WHERE '.$this->definition['local']
|
||||
. ' = ?';
|
||||
|
||||
$sub2 = 'SELECT '.$this->definition['local']
|
||||
. ' FROM '.$this->definition['assocTable']->getTableName()
|
||||
. ' FROM '.$this->definition['refTable']->getTableName()
|
||||
. ' WHERE '.$this->definition['foreign']
|
||||
. ' = ?';
|
||||
|
||||
$dql = 'FROM ' . $this->definition['table']->getComponentName()
|
||||
. '.' . $this->definition['assocTable']->getComponentName()
|
||||
. '.' . $this->definition['refTable']->getComponentName()
|
||||
. ' WHERE ' . $this->definition['table']->getComponentName()
|
||||
. '.' . $this->definition['table']->getIdentifier()
|
||||
. ' IN (' . $sub . ')'
|
||||
@ -63,9 +63,9 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association
|
||||
break;
|
||||
case 'collection':
|
||||
$sub = substr(str_repeat('?, ', $count),0,-2);
|
||||
$dql = 'FROM '.$this->definition['assocTable']->getComponentName()
|
||||
$dql = 'FROM '.$this->definition['refTable']->getComponentName()
|
||||
. '.' . $this->definition['table']->getComponentName()
|
||||
. ' WHERE '.$this->definition['assocTable']->getComponentName()
|
||||
. ' WHERE '.$this->definition['refTable']->getComponentName()
|
||||
. '.' . $this->definition['local'] . ' IN (' . $sub . ')';
|
||||
};
|
||||
|
||||
|
@ -45,7 +45,7 @@ class Doctrine_Relation_ForeignKey extends Doctrine_Relation
|
||||
{
|
||||
$id = array();
|
||||
foreach ((array) $this->definition['local'] as $local) {
|
||||
$id = $record->get($local);
|
||||
$id[] = $record->get($local);
|
||||
}
|
||||
if ($this->isOneToOne()) {
|
||||
if (empty($id)) {
|
||||
@ -54,7 +54,7 @@ class Doctrine_Relation_ForeignKey extends Doctrine_Relation
|
||||
$dql = 'FROM ' . $this->getTable()->getComponentName()
|
||||
. ' WHERE ' . $this->getCondition();
|
||||
|
||||
$coll = $this->getTable()->getConnection()->query($dql, array($id));
|
||||
$coll = $this->getTable()->getConnection()->query($dql, $id);
|
||||
$related = $coll[0];
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ class Doctrine_Relation_ForeignKey extends Doctrine_Relation
|
||||
$related = new Doctrine_Collection($this->getTable());
|
||||
} else {
|
||||
$query = $this->getRelationDql(1);
|
||||
$related = $this->getTable()->getConnection()->query($query, array($id));
|
||||
$related = $this->getTable()->getConnection()->query($query, $id);
|
||||
}
|
||||
$related->setReference($record, $this);
|
||||
}
|
||||
|
@ -126,6 +126,8 @@ class Doctrine_Relation_Parser
|
||||
if (isset($this->_pending[$alias])) {
|
||||
$def = $this->_pending[$alias];
|
||||
|
||||
// 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()));
|
||||
@ -134,7 +136,10 @@ class Doctrine_Relation_Parser
|
||||
! isset($this->_relations[$def['refClass']])) {
|
||||
|
||||
$def['refTable']->getRelationParser()->bind($this->_table->getComponentName(),
|
||||
array('type' => Doctrine_Relation::ONE));
|
||||
array('type' => Doctrine_Relation::ONE,
|
||||
'local' => $def['local'],
|
||||
'foreign' => $this->_table->getIdentifier(),
|
||||
));
|
||||
|
||||
$this->bind($def['refClass'], array('type' => Doctrine_Relation::MANY,
|
||||
'foreign' => $def['local']));
|
||||
@ -145,15 +150,20 @@ class Doctrine_Relation_Parser
|
||||
$rel = new Doctrine_Relation_Association($def);
|
||||
}
|
||||
} else {
|
||||
// simple foreign key relation
|
||||
$def = $this->completeDefinition($def);
|
||||
if ( ! isset($def['foreign'])) {
|
||||
Doctrine::dump($def);
|
||||
}
|
||||
$rel = new Doctrine_Relation_ForeignKey($def);
|
||||
|
||||
if (isset($def['localKey'])) {
|
||||
$rel = new Doctrine_Relation_LocalKey($def);
|
||||
} else {
|
||||
$rel = new Doctrine_Relation_ForeignKey($def);
|
||||
}
|
||||
}
|
||||
if (isset($rel)) {
|
||||
unset($this->_pending[$name]);
|
||||
|
||||
// unset pending relation
|
||||
unset($this->_pending[$alias]);
|
||||
|
||||
$this->_relations[$alias] = $rel;
|
||||
return $rel;
|
||||
}
|
||||
}
|
||||
@ -288,6 +298,7 @@ class Doctrine_Relation_Parser
|
||||
// the foreign field is likely to be the
|
||||
// identifier of the foreign class
|
||||
$def['foreign'] = $def['table']->getIdentifier();
|
||||
$def['localKey'] = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -295,6 +306,7 @@ class Doctrine_Relation_Parser
|
||||
// local key not set, but foreign key is set
|
||||
// try to guess the local key
|
||||
if ($def['foreign'] === $def['table']->getIdentifier()) {
|
||||
$def['localKey'] = true;
|
||||
$def['local'] = $this->guessColumns($foreignClasses, $this->_table);
|
||||
} else {
|
||||
$def['local'] = $this->_table->getIdentifier();
|
||||
@ -316,6 +328,7 @@ class Doctrine_Relation_Parser
|
||||
if ($table2->hasColumn($column)) {
|
||||
$def['foreign'] = $column;
|
||||
$def['local'] = $table->getIdentifier();
|
||||
$def['localKey'] = true;
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
@ -334,8 +347,8 @@ class Doctrine_Relation_Parser
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
} Doctrine::dump($this->_table->getComponentName());
|
||||
Doctrine::dump($def);
|
||||
}
|
||||
Doctrine::dump($def);
|
||||
throw new Doctrine_Relation_Parser_Exception("Couldn't complete relation definition.");
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
* @var array $data temporary data which is then loaded into Doctrine_Record::$data
|
||||
*/
|
||||
private $data = array();
|
||||
/**
|
||||
* @var array $relations an array containing all the Doctrine_Relation objects for this table
|
||||
*/
|
||||
private $relations = array();
|
||||
/**
|
||||
* @var array $primaryKeys an array containing all primary key column names
|
||||
*/
|
||||
@ -96,14 +92,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
* keys as column aliases and values as column names
|
||||
*/
|
||||
protected $columnAliases = array();
|
||||
/**
|
||||
* @var array $bound bound relations
|
||||
*/
|
||||
private $bound = array();
|
||||
/**
|
||||
* @var array $boundAliases bound relation aliases
|
||||
*/
|
||||
private $boundAliases = array();
|
||||
/**
|
||||
* @var integer $columnCount cached column count, Doctrine_Record uses this column count in when
|
||||
* determining its state
|
||||
@ -161,9 +149,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
'treeImpl' => null,
|
||||
'treeOptions' => null,
|
||||
'indexes' => array(),
|
||||
'parents' => array(),
|
||||
);
|
||||
/**
|
||||
* @var Doctrine_Tree $tree tree object associated with this table
|
||||
* @var Doctrine_Tree $tree tree object associated with this table
|
||||
*/
|
||||
protected $tree;
|
||||
/**
|
||||
@ -207,6 +196,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
|
||||
// reverse names
|
||||
$names = array_reverse($names);
|
||||
// save parents
|
||||
array_pop($names);
|
||||
$this->options['parents'] = $names;
|
||||
|
||||
// create database table
|
||||
if (method_exists($record, 'setTableDefinition')) {
|
||||
@ -303,11 +295,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
if ($this->isTree()) {
|
||||
$this->getTree()->setUp();
|
||||
}
|
||||
|
||||
// save parents
|
||||
array_pop($names);
|
||||
$this->options['parents'] = $names;
|
||||
|
||||
$this->repository = new Doctrine_Table_Repository($this);
|
||||
}
|
||||
/**
|
||||
@ -472,6 +459,61 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
|
||||
return false;
|
||||
}
|
||||
public function bind($args, $type)
|
||||
{
|
||||
$options = array();
|
||||
$options['type'] = $type;
|
||||
|
||||
// the following is needed for backwards compatibility
|
||||
if (is_string($args[1])) {
|
||||
if ( ! isset($args[2])) {
|
||||
$args[2] = array();
|
||||
} elseif (is_string($args[2])) {
|
||||
$args[2] = (array) $args[2];
|
||||
}
|
||||
|
||||
$classes = array_merge($this->options['parents'], array($this->getComponentName()));
|
||||
|
||||
|
||||
$e = explode('.', $args[1]);
|
||||
if (in_array($e[0], $classes)) {
|
||||
$options['local'] = $e[1];
|
||||
} else {
|
||||
$e2 = explode(' as ', $args[0]);
|
||||
if ($e[0] !== $e2[0] && ( ! isset($e2[1]) || $e[0] !== $e2[1])) {
|
||||
$options['refClass'] = $e[0];
|
||||
}
|
||||
|
||||
$options['foreign'] = $e[1];
|
||||
}
|
||||
|
||||
$options = array_merge($args[2], $options);
|
||||
|
||||
$this->_parser->bind($args[0], $options);
|
||||
} else {
|
||||
$options = array_merge($args[1], $options);
|
||||
$this->_parser->bind($args[0], $options);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* getRelation
|
||||
*
|
||||
* @param string $alias relation alias
|
||||
*/
|
||||
public function getRelation($alias, $recursive = true)
|
||||
{
|
||||
return $this->_parser->getRelation($alias, $recursive);
|
||||
}
|
||||
/**
|
||||
* getRelations
|
||||
* returns an array containing all relation objects
|
||||
*
|
||||
* @return array an array of Doctrine_Relation objects
|
||||
*/
|
||||
public function getRelations()
|
||||
{
|
||||
return $this->_parser->getRelations();
|
||||
}
|
||||
/**
|
||||
* createQuery
|
||||
* creates a new Doctrine_Query object and adds the component name
|
||||
@ -683,148 +725,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
{
|
||||
return in_array($key,$this->primaryKeys);
|
||||
}
|
||||
/**
|
||||
* returns all bound relations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBounds()
|
||||
{
|
||||
return $this->bound;
|
||||
}
|
||||
/**
|
||||
* returns a bound relation array
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function getBound($name)
|
||||
{
|
||||
if ( ! isset($this->bound[$name])) {
|
||||
throw new Doctrine_Table_Exception('Unknown bound ' . $name);
|
||||
}
|
||||
return $this->bound[$name];
|
||||
}
|
||||
/**
|
||||
* returns a bound relation array
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function getBoundForName($name, $component)
|
||||
{
|
||||
foreach ($this->bound as $k => $bound) {
|
||||
$e = explode('.', $bound['field']);
|
||||
|
||||
if ($bound['class'] == $name && $e[0] == $component) {
|
||||
return $this->bound[$k];
|
||||
}
|
||||
}
|
||||
throw new Doctrine_Table_Exception('Unknown bound ' . $name);
|
||||
}
|
||||
/**
|
||||
* returns the alias for given component name
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public function getAlias($name)
|
||||
{
|
||||
if (isset($this->boundAliases[$name])) {
|
||||
return $this->boundAliases[$name];
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
* returns component name for given alias
|
||||
*
|
||||
* @param string $alias
|
||||
* @return string
|
||||
*/
|
||||
public function getAliasName($alias)
|
||||
{
|
||||
if ($name = array_search($alias, $this->boundAliases)) {
|
||||
return $name;
|
||||
}
|
||||
return $alias;
|
||||
}
|
||||
/**
|
||||
* unbinds all relations
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unbindAll()
|
||||
{
|
||||
$this->bound = array();
|
||||
$this->relations = array();
|
||||
$this->boundAliases = array();
|
||||
}
|
||||
/**
|
||||
* unbinds a relation
|
||||
* returns true on success, false on failure
|
||||
*
|
||||
* @param $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function unbind($name)
|
||||
{
|
||||
if ( ! isset($this->bound[$name])) {
|
||||
return false;
|
||||
}
|
||||
unset($this->bound[$name]);
|
||||
|
||||
if (isset($this->relations[$name])) {
|
||||
unset($this->relations[$name]);
|
||||
}
|
||||
if (isset($this->boundAliases[$name])) {
|
||||
unset($this->boundAliases[$name]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* binds a relation
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $field
|
||||
* @return void
|
||||
*/
|
||||
public function bind($name, $field, $type, $options = null)
|
||||
{
|
||||
if (isset($this->relations[$name])) {
|
||||
unset($this->relations[$name]);
|
||||
}
|
||||
|
||||
$lower = strtolower($name);
|
||||
|
||||
if (isset($this->columns[$lower])) {
|
||||
throw new Doctrine_Table_Exception("Couldn't bind relation. Column with name " . $lower . ' already exists!');
|
||||
}
|
||||
|
||||
$e = explode(' as ', $name);
|
||||
$name = $e[0];
|
||||
|
||||
if (isset($e[1])) {
|
||||
$alias = $e[1];
|
||||
$this->boundAliases[$name] = $alias;
|
||||
} else {
|
||||
$alias = $name;
|
||||
}
|
||||
|
||||
$this->bound[$alias] = array('field' => $field,
|
||||
'type' => $type,
|
||||
'class' => $name,
|
||||
'alias' => $alias);
|
||||
if ($options !== null) {
|
||||
$opt = array();
|
||||
if (is_string($options)) {
|
||||
$opt['local'] = $options;
|
||||
} else {
|
||||
$opt = (array) $options;
|
||||
}
|
||||
|
||||
$this->bound[$alias] = array_merge($this->bound[$alias], $opt);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return Doctrine_Connection
|
||||
*/
|
||||
@ -832,212 +732,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
|
||||
{
|
||||
return $this->conn;
|
||||
}
|
||||
/**
|
||||
* hasRelatedComponent
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasRelatedComponent($name, $component)
|
||||
{
|
||||
return (strpos($this->bound[$name]['field'], $component . '.') !== false);
|
||||
}
|
||||
/**
|
||||
* @param string $name component name of which a foreign key object is bound
|
||||
* @return boolean
|
||||
*/
|
||||
final public function hasRelation($name)
|
||||
{
|
||||
if (isset($this->bound[$name])) {
|
||||
return true;
|
||||
}
|
||||
foreach ($this->bound as $k=>$v) {
|
||||
if ($this->hasRelatedComponent($k, $name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* getRelation
|
||||
*
|
||||
* @param string $name component name of which a foreign key object is bound
|
||||
* @return Doctrine_Relation
|
||||
*/
|
||||
public function getRelation($name, $recursive = true)
|
||||
{
|
||||
if (isset($this->relations[$name])) {
|
||||
return $this->relations[$name];
|
||||
}
|
||||
|
||||
if ( ! $this->conn->hasTable($this->options['name'])) {
|
||||
$allowExport = true;
|
||||
} else {
|
||||
$allowExport = false;
|
||||
}
|
||||
|
||||
if (isset($this->bound[$name])) {
|
||||
|
||||
$definition = $this->bound[$name];
|
||||
|
||||
list($component, $tmp) = explode('.', $definition['field']);
|
||||
|
||||
if ( ! isset($definition['foreign'])) {
|
||||
$definition['foreign'] = $tmp;
|
||||
}
|
||||
|
||||
unset($definition['field']);
|
||||
|
||||
$definition['table'] = $this->conn->getTable($definition['class'], $allowExport);
|
||||
$definition['constraint'] = false;
|
||||
|
||||
if ($component == $this->options['name'] || in_array($component, $this->options['parents'])) {
|
||||
|
||||
// ONE-TO-ONE
|
||||
if ($definition['type'] == Doctrine_Relation::ONE_COMPOSITE ||
|
||||
$definition['type'] == Doctrine_Relation::ONE_AGGREGATE) {
|
||||
// tree structure parent relation found
|
||||
|
||||
if ( ! isset($definition['local'])) {
|
||||
$definition['local'] = $definition['foreign'];
|
||||
$definition['foreign'] = $definition['table']->getIdentifier();
|
||||
}
|
||||
|
||||
$relation = new Doctrine_Relation_LocalKey($definition);
|
||||
|
||||
} else {
|
||||
// tree structure children relation found
|
||||
|
||||
if ( ! isset($definition['local'])) {
|
||||
$tmp = $definition['table']->getIdentifier();
|
||||
|
||||
$definition['local'] = $tmp;
|
||||
}
|
||||
|
||||
//$definition['foreign'] = $tmp;
|
||||
$definition['constraint'] = true;
|
||||
|
||||
$relation = new Doctrine_Relation_ForeignKey($definition);
|
||||
}
|
||||
|
||||
} elseif ($component == $definition['class'] ||
|
||||
($component == $definition['alias'])) { // && ($name == $this->options['name'] || in_array($name,$this->parents))
|
||||
|
||||
if ( ! isset($defintion['local'])) {
|
||||
$definition['local'] = $this->identifier;
|
||||
}
|
||||
|
||||
$definition['constraint'] = true;
|
||||
|
||||
// ONE-TO-MANY or ONE-TO-ONE
|
||||
$relation = new Doctrine_Relation_ForeignKey($definition);
|
||||
|
||||
} else {
|
||||
// MANY-TO-MANY
|
||||
// only aggregate relations allowed
|
||||
|
||||
if ($definition['type'] != Doctrine_Relation::MANY_AGGREGATE) {
|
||||
throw new Doctrine_Table_Exception("Only aggregate relations are allowed for many-to-many relations");
|
||||
}
|
||||
|
||||
$classes = array_merge($this->options['parents'], array($this->options['name']));
|
||||
|
||||
foreach (array_reverse($classes) as $class) {
|
||||
try {
|
||||
$bound = $definition['table']->getBoundForName($class, $component);
|
||||
break;
|
||||
} catch(Doctrine_Table_Exception $exc) { }
|
||||
}
|
||||
if ( ! isset($bound)) {
|
||||
throw new Doctrine_Table_Exception("Couldn't map many-to-many relation for "
|
||||
. $this->options['name'] . " and $name. Components use different join tables.");
|
||||
}
|
||||
if ( ! isset($definition['local'])) {
|
||||
$definition['local'] = $this->identifier;
|
||||
}
|
||||
$e2 = explode('.', $bound['field']);
|
||||
$fields = explode('-', $e2[1]);
|
||||
|
||||
if ($e2[0] != $component) {
|
||||
throw new Doctrine_Table_Exception($e2[0] . ' doesn\'t match ' . $component);
|
||||
}
|
||||
$associationTable = $this->conn->getTable($e2[0], $allowExport);
|
||||
|
||||
if (count($fields) > 1) {
|
||||
// SELF-REFERENCING THROUGH JOIN TABLE
|
||||
|
||||
$def['table'] = $associationTable;
|
||||
$def['local'] = $this->identifier;
|
||||
$def['foreign'] = $fields[0];
|
||||
$def['alias'] = $e2[0];
|
||||
$def['class'] = $e2[0];
|
||||
$def['type'] = Doctrine_Relation::MANY_COMPOSITE;
|
||||
|
||||
$this->relations[$e2[0]] = new Doctrine_Relation_ForeignKey($def);
|
||||
|
||||
$definition['assocTable'] = $associationTable;
|
||||
$definition['local'] = $fields[0];
|
||||
$definition['foreign'] = $fields[1];
|
||||
$relation = new Doctrine_Relation_Association_Self($definition);
|
||||
} else {
|
||||
if($definition['table'] === $this) {
|
||||
|
||||
} else {
|
||||
// auto initialize a new one-to-one relationships for association table
|
||||
$associationTable->bind($this->getComponentName(),
|
||||
$associationTable->getComponentName(). '.' . $e2[1],
|
||||
Doctrine_Relation::ONE_AGGREGATE
|
||||
);
|
||||
|
||||
$associationTable->bind($definition['table']->getComponentName(),
|
||||
$associationTable->getComponentName(). '.' . $definition['foreign'],
|
||||
Doctrine_Relation::ONE_AGGREGATE
|
||||
);
|
||||
|
||||
// NORMAL MANY-TO-MANY RELATIONSHIP
|
||||
|
||||
$def['table'] = $associationTable;
|
||||
$def['foreign'] = $e2[1];
|
||||
$def['local'] = $definition['local'];
|
||||
$def['alias'] = $e2[0];
|
||||
$def['class'] = $e2[0];
|
||||
$def['type'] = Doctrine_Relation::MANY_COMPOSITE;
|
||||
$this->relations[$e2[0]] = new Doctrine_Relation_ForeignKey($def);
|
||||
|
||||
$definition['local'] = $e2[1];
|
||||
$definition['assocTable'] = $associationTable;
|
||||
$relation = new Doctrine_Relation_Association($definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->relations[$name] = $relation;
|
||||
|
||||
return $this->relations[$name];
|
||||
}
|
||||
|
||||
|
||||
// load all relations
|
||||
$this->getRelations();
|
||||
|
||||
if ($recursive) {
|
||||
return $this->getRelation($name, false);
|
||||
} else {
|
||||
throw new Doctrine_Table_Exception($this->options['name'] . " doesn't have a relation to " . $name);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* returns an array containing all foreign key objects
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
final public function getRelations()
|
||||
{
|
||||
foreach ($this->bound as $k => $v) {
|
||||
$this->getRelation($k);
|
||||
}
|
||||
|
||||
return $this->relations;
|
||||
}
|
||||
/**
|
||||
* create
|
||||
* creates a new record
|
||||
|
Loading…
x
Reference in New Issue
Block a user