Rewrote data loading to support I18n data, nested set data, and better relationship defining for fixtures. Also fixes ticket:528
This commit is contained in:
parent
37898ac06a
commit
0038138095
@ -32,6 +32,8 @@
|
|||||||
*/
|
*/
|
||||||
class Doctrine_Data_Import extends Doctrine_Data
|
class Doctrine_Data_Import extends Doctrine_Data
|
||||||
{
|
{
|
||||||
|
private $_importedObjects = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
*
|
*
|
||||||
@ -81,6 +83,27 @@ 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
|
|||||||
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
|
|||||||
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();
|
||||||
|
$templates = array_keys($obj->getTable()->getTemplates());
|
||||||
|
|
||||||
foreach ($row as $key => $value) {
|
if (in_array('Doctrine_Template_NestedSet', $templates)) {
|
||||||
// If row key is a relation store it for later fixing once we have all primary keys
|
$this->loadNestedSetData($className, $data);
|
||||||
if ($obj->getTable()->hasRelation($key)) {
|
} else {
|
||||||
$relation = $obj->getTable()->getRelation($key);
|
$rows = array_merge($rows, $this->buildRows($className, $data));
|
||||||
|
|
||||||
$pendingRelations[] = array('key' => $value, 'obj' => $obj, 'local' => $relation['local'], 'foreign' => $relation['foreign']);
|
|
||||||
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user