Commit 00381380 authored by Jonathan.Wage's avatar Jonathan.Wage

Rewrote data loading to support I18n data, nested set data, and better...

Rewrote data loading to support I18n data, nested set data, and better relationship defining for fixtures. Also fixes ticket:528
parent 37898ac0
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
*/ */
class Doctrine_Data_Import extends Doctrine_Data class Doctrine_Data_Import extends Doctrine_Data
{ {
private $_importedObjects = array();
/** /**
* constructor * constructor
* *
...@@ -80,7 +82,28 @@ class Doctrine_Data_Import extends Doctrine_Data ...@@ -80,7 +82,28 @@ class Doctrine_Data_Import extends Doctrine_Data
$this->loadData($array); $this->loadData($array);
} }
protected function buildRows($className, $data)
{
$rows = array();
foreach ($data as $rowKey => $row) {
// do the same for the row information
$rows[$className][$rowKey] = $row;
foreach ($row as $key => $value) {
if (Doctrine::getTable($className)->hasRelation($key) && is_array($value)) {
$keys = array_keys($value);
// Skip associative arrays defining keys to relationships
if (!isset($keys[0])) {
$rows = array_merge($rows, $this->buildRows(Doctrine::getTable($className)->getRelation($key)->getTable()->getOption('name'), $value));
}
}
}
}
return $rows;
}
/** /**
* loadData * loadData
* *
...@@ -90,10 +113,7 @@ class Doctrine_Data_Import extends Doctrine_Data ...@@ -90,10 +113,7 @@ class Doctrine_Data_Import extends Doctrine_Data
protected function loadData(array $array) protected function loadData(array $array)
{ {
$specifiedModels = $this->getModels(); $specifiedModels = $this->getModels();
$rows = array();
$pendingRelations = array();
$primaryKeys = array();
foreach ($array as $className => $data) { foreach ($array as $className => $data) {
...@@ -101,50 +121,96 @@ class Doctrine_Data_Import extends Doctrine_Data ...@@ -101,50 +121,96 @@ class Doctrine_Data_Import extends Doctrine_Data
continue; continue;
} }
foreach ($data as $rowKey => $row) { // This is simple here to get the templates present for this model
$obj = new $className(); // better way?
$obj = new $className();
foreach ($row as $key => $value) { $templates = array_keys($obj->getTable()->getTemplates());
// If row key is a relation store it for later fixing once we have all primary keys
if ($obj->getTable()->hasRelation($key)) { if (in_array('Doctrine_Template_NestedSet', $templates)) {
$relation = $obj->getTable()->getRelation($key); $this->loadNestedSetData($className, $data);
} else {
$pendingRelations[] = array('key' => $value, 'obj' => $obj, 'local' => $relation['local'], 'foreign' => $relation['foreign']); $rows = array_merge($rows, $this->buildRows($className, $data));
// If we have a normal column
} else if ($obj->getTable()->hasColumn($key)) {
$obj->$key = $value;
// Otherwise lets move on
} else {
continue;
}
}
$identifier = is_array($obj->getTable()->getIdentifier()) ? $obj->getTable()->getIdentifier():array($obj->getTable()->getIdentifier());
// We only want to save the record if it is a single primary key.
// We can't save the composite primary key because neither of the foreign keys have been created yet
// We will satisfy these relationships later and save the record.
if (count($identifier) === 1) {
$obj->save();
}
$primaryKeys[$rowKey] = $obj->identifier();
} }
} }
// Satisfy all relationships $buildRows = array();
foreach ($pendingRelations as $rowKey => $pending) { foreach ($rows as $className => $classRows) {
$obj = $pending['obj']; foreach ($classRows as $rowKey => $row) {
$key = $pending['key']; $buildRows[$rowKey] = $row;
$local = $pending['local']; $this->_importedObjects[$rowKey] = new $className();
$pks = $primaryKeys[$key]; }
$obj->$local = $pks['id'];
} }
// Loop over all again to save them since we satisfied all pending relationships above foreach($buildRows as $rowKey => $row) {
foreach ($pendingRelations as $rowKey => $pending) { $obj = $this->_importedObjects[$rowKey];
$obj = $pending['obj'];
$obj->save(); foreach ($row as $key => $value) {
if ($obj->getTable()->hasColumn($key)) {
$obj->set($key, $value);
} else if ($obj->getTable()->hasRelation($key)) {
if (is_array($value)) {
if (isset($value[0])) {
foreach ($value as $link) {
if ($obj->getTable()->getRelation($key)->getType() === Doctrine_Relation::ONE) {
$obj->set($key, $this->_importedObjects[$link]);
} else if ($obj->getTable()->getRelation($key)->getType() === Doctrine_Relation::MANY) {
$relation = $obj->$key;
$relation[] = $this->_importedObjects[$link];
}
}
} else {
$obj->$key->fromArray($value);
}
} else if (isset($this->_importedObjects[$value])) {
$obj->set($key, $this->_importedObjects[$value]);
}
}
}
}
$manager = Doctrine_Manager::getInstance();
foreach ($manager as $connection) {
$connection->flush();
}
}
protected function loadNestedSetData($model, $nestedSetData, $parent = null)
{
$manager = Doctrine_Manager::getInstance();
foreach($nestedSetData AS $rowKey => $nestedSet)
{
$children = array();
$data = array();
if( array_key_exists('children', $nestedSet) )
{
$children = $nestedSet['children'];
unset($nestedSet['children']);
}
$record = new $model();
$this->_importedObjects[$rowKey] = $record;
if( is_array($nestedSet) AND !empty($nestedSet) )
{
$record->fromArray($nestedSet);
}
if( !$parent )
{
$manager->getTable($model)->getTree()->createRoot($record);
} else {
$parent->getNode()->addChild($record);
}
if( is_array($children) AND !empty($children) )
{
$this->loadNestedSetData($model, $children, $record);
}
} }
} }
......
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