function data_export_import_import_nodes in Data export import 7
Import a dataset file and make current nodes match exactly.
The purpose of this function is to effectively 'import' the nodes stored in a dataset file.
NB - When this import has finished the nodes in the receiving instance should be an exact match with the nodes in the imported dataset file. Think in terms of rsync with the '--delete' option. This means that as well as importing new nodes we need to delete nodes in the receiving instance which are not in the imported dataset.
This synchronization will be carried out by two passes.
First we will loop through the nodes in the receiving instance and check against the the imported dataset. If the node exists in the dataset then it will be updated in the receiving instance. If it doesn't exist in the dataset then it will be deleted from the receiving Drupal instance.
The second pass will be a loop through the dataset - any terms which are in the dataset but are not in the receiving Drupal instance will be created.
This will effectively mean that the terms have been sychronised completely.
NB - There is some deeper logic here we need to be aware of. The node ID's need to match exactly otherwise the related items will not match. So when the new nodes are created they will need to have their old ID's set to match exactly - again due to the related terms.
Parameters
string $file: The dataset file which is being imported.
Return value
bool TRUE if the import process ran without errors.
1 call to data_export_import_import_nodes()
- data_export_import_import_nodes_form_submit in includes/
profiles/ nodes.inc - Function to process form to import nodes.
File
- includes/
profiles/ nodes.inc, line 535 - Enables nodes to be exported and imported.
Code
function data_export_import_import_nodes($file) {
// Read the first line - decode the object and check that the content types
// are an exact match.
$file_path = variable_get('file_public_path', conf_path() . '/files') . "/data_export_import/nodes/" . $file;
$handle = fopen($file_path, "r");
if ($handle) {
$content_type_line_from_file = fgets($handle);
fclose($handle);
}
$node_content_type_object_from_file = unserialize(base64_decode($content_type_line_from_file));
// Check that the content types match.
$node_content_type = $node_content_type_object_from_file->type;
node_types_rebuild();
$node_types = node_type_get_types();
// Check that the content type exists in the receiving instance.
if (is_null($node_types[$node_content_type])) {
drupal_set_message(t("The content type of the content being imported does not exist in the receiving site for content type of: %content_type", array(
'%content_type' => $node_content_type,
)), 'error');
return FALSE;
}
// Here we are going to unset the description fields. If the
// description has been changed but everything else about the
// content type is the same then we will assume that this is just an
// edit to the description.
unset($node_content_type_object_from_file->description);
unset($node_types[$node_content_type]->description);
if ($node_content_type_object_from_file != $node_types[$node_content_type]) {
drupal_set_message(t("When the dataset was created the node content type was different from this site's node content type. Please manually compare the content type: %content_type", array(
'%content_type' => $node_content_type,
)), 'error');
return FALSE;
}
// Loop through all the lines in the file and put the nid's into an array.
// Then loop through all the current nodes (in the receiving instance)
// and check the nid value. If it doesn't match an nid from the dataset file
// then delete the existing node in the receiving instance. This will delete
// test nodes which have been created.
$line_number = 0;
$handle = fopen($file_path, "r");
if ($handle) {
while (($buffer = fgets($handle)) !== FALSE) {
$line_number++;
if ($line_number > 1) {
// @todo Here we will need to unencode the line extracted.
$node_from_file = unserialize(base64_decode($buffer));
$nids_from_file[] = $node_from_file->nid;
}
}
if (!feof($handle)) {
drupal_set_message(t("Unexpected error when reading file."), 'error');
}
fclose($handle);
}
// Loop through the existing nodes (for that content type) and if
// they don't exist in the dataset then delete them. Here we are
// going to be a bit simpler but harsher. If a node of *any*
// content type exists with the matching ID then delete it. And
// we're going to allow the user running the import to be able to
// delete any nodes so that the data keeps consistent.
$results = db_query('SELECT nid FROM {node} WHERE type = :type', array(
':type' => $node_content_type,
));
foreach ($results as $row) {
if (!in_array($row->nid, $nids_from_file)) {
// Delete node as it does not exist in the dataset being
// imported.
node_delete($row->nid);
}
}
// Here we are going to get a list of fields which are of type 'file' for the
// content type selected.
$fields_of_type_file = array();
$fields_info = field_info_instances('node', $node_content_type);
foreach ($fields_info as $field_name => $field_value) {
$field_info = field_info_field($field_name);
$type = $field_info['type'];
if ($type == 'file' || $type == 'image') {
$fields_of_type_file[] = $field_name;
}
}
// Loop through all the lines in the dataset file and extract each
// node line. If the receiving instance has a node with a matching
// nid then update it - or if not then create a new node with the
// same nid. We will use a batch function to process the lines from
// the file.
$batch = array(
'operations' => array(
array(
'data_export_import_batch_import_dataset_lines',
array(
$file_path,
$fields_of_type_file,
),
),
),
'finished' => 'data_export_import_batch_import_dataset_lines_finished',
'title' => t('Processing Import of nodes from file Batch'),
'init_message' => t('Batch of node importing starting.'),
'progress_message' => t('Processed @current out of @total.'),
'error_message' => t('Batch importing of nodes from file has encountered an error.'),
'file' => drupal_get_path('module', 'data_export_import') . '/includes/profiles/nodes.inc',
);
batch_set($batch);
// Since this is not called from a file then we need to call the
// batch process function.
batch_process('admin/config/system/data_export_import/nodes/import');
return TRUE;
}