. */ Doctrine::autoload('Doctrine_Connection_Module'); /** * Doctrine_Connection_UnitOfWork * * @package Doctrine * @subpackage Connection * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @link www.phpdoctrine.com * @since 1.0 * @version $Revision$ * @author Konsta Vesterinen * @todo package:orm. Figure out a useful implementation. */ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module { protected $_autoflush = true; protected $_inserts = array(); protected $_updates = array(); protected $_deletes = array(); public function flush() { // get the flush tree $tree = $this->buildFlushTree($this->conn->getMappers()); // save all records foreach ($tree as $name) { $mapper = $this->conn->getMapper($name); foreach ($mapper->getRepository() as $record) { //echo $record->getOid() . "
"; $mapper->saveSingleRecord($record); } } // save all associations foreach ($tree as $name) { $mapper = $this->conn->getMapper($name); foreach ($mapper->getRepository() as $record) { $mapper->saveAssociations($record); } } } public function addInsert() { } public function addUpdate() { } public function addDelete() { } /** * buildFlushTree * builds a flush tree that is used in transactions * * The returned array has all the initialized components in * 'correct' order. Basically this means that the records of those * components can be saved safely in the order specified by the returned array. * * @param array $tables an array of Doctrine_Table objects or component names * @return array an array of component names in flushing order */ public function buildFlushTree(array $mappers) { $tree = array(); foreach ($mappers as $k => $mapper) { if ( ! ($mapper instanceof Doctrine_Mapper)) { $mapper = $this->conn->getMapper($mapper); } $nm = $mapper->getComponentName(); $index = array_search($nm, $tree); if ($index === false) { $tree[] = $nm; $index = max(array_keys($tree)); } $rels = $mapper->getTable()->getRelations(); // group relations foreach ($rels as $key => $rel) { if ($rel instanceof Doctrine_Relation_ForeignKey) { unset($rels[$key]); array_unshift($rels, $rel); } } foreach ($rels as $rel) { $name = $rel->getTable()->getComponentName(); $index2 = array_search($name,$tree); $type = $rel->getType(); // skip self-referenced relations if ($name === $nm) { continue; } if ($rel instanceof Doctrine_Relation_ForeignKey) { if ($index2 !== false) { if ($index2 >= $index) continue; unset($tree[$index]); array_splice($tree,$index2,0,$nm); $index = $index2; } else { $tree[] = $name; } } else if ($rel instanceof Doctrine_Relation_LocalKey) { if ($index2 !== false) { if ($index2 <= $index) continue; unset($tree[$index2]); array_splice($tree,$index,0,$name); } else { array_unshift($tree,$name); $index++; } } else if ($rel instanceof Doctrine_Relation_Association) { $t = $rel->getAssociationFactory(); $n = $t->getComponentName(); if ($index2 !== false) unset($tree[$index2]); array_splice($tree, $index, 0, $name); $index++; $index3 = array_search($n, $tree); if ($index3 !== false) { if ($index3 >= $index) continue; unset($tree[$index]); array_splice($tree, $index3, 0, $n); $index = $index2; } else { $tree[] = $n; } } } } return array_values($tree); } /** * saveAll * persists all the pending records from all tables * * @throws PDOException if something went wrong at database level * @return void * @deprecated */ public function saveAll() { return $this->flush(); } }