node_export_dsv.module in Node export 6.3
The Node export DSV module.
Adds DSV format to Node export.
File
modules/node_export_dsv/node_export_dsv.moduleView source
<?php
/**
* @file
* The Node export DSV module.
*
* Adds DSV format to Node export.
*/
/**
* Implementation of hook_form_FORM_ID_alter().
*/
function node_export_dsv_form_node_export_settings_alter(&$form, $form_state) {
$form['basic']['dsv'] = array(
'#type' => 'fieldset',
'#title' => t('DSV format settings'),
'#description' => t('Select how your DSV output will be formatted - this must be configured the
same on both sites. By default this is configured to RFC4180 CSV format
where the delimiter is a comma (,), the enclosure is a double-quote ("),
and the seperator is CRLF (\\r\\n). Not all configurations may be possible,
use wisely. Enclosure will only be used to escape values that contain any
of the configured strings. Additionally single-quotes will be used to
escape values that are equivalent to reserved words (NULL, TRUE, FALSE).'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['basic']['dsv']['node_export_dsv_delimiter'] = array(
'#type' => 'textfield',
'#title' => t('Value delimiter'),
'#size' => 5,
'#maxlength' => 255,
'#default_value' => variable_get('node_export_dsv_delimiter', ','),
'#required' => TRUE,
);
$form['basic']['dsv']['node_export_dsv_enclosure'] = array(
'#type' => 'textfield',
'#title' => t('Escape enclosure'),
'#size' => 5,
'#maxlength' => 255,
'#default_value' => variable_get('node_export_dsv_enclosure', '"'),
'#required' => TRUE,
);
$form['basic']['dsv']['node_export_dsv_seperator'] = array(
'#type' => 'textfield',
'#title' => t('Record seperator'),
'#size' => 5,
'#maxlength' => 255,
'#default_value' => variable_get('node_export_dsv_seperator', '\\r\\n'),
'#required' => TRUE,
);
$form['basic']['dsv']['node_export_dsv_escape_eol'] = array(
'#type' => 'checkbox',
'#title' => t('Always escape values containing line breaks'),
'#default_value' => variable_get('node_export_dsv_escape_eol', 1),
'#description' => t('This is to overcome problems where Windows injects CRLF line breaks.'),
);
}
/**
* Replace special character strings with special character.
*/
function node_export_dsv_string($string) {
$replace = array(
'\\n' => "\n",
'\\r' => "\r",
'\\t' => "\t",
'\\v' => "\v",
'\\e' => "\33",
'\\f' => "\f",
);
return str_replace(array_keys($replace), array_values($replace), $string);
}
/**
* Implements hook_node_export_format_handlers().
*
* @see hook_node_export_format_handlers()
*/
function node_export_dsv_node_export_format_handlers() {
return array(
'dsv' => array(
'#title' => t('DSV'),
'#module' => 'node_export_dsv',
),
);
}
/**
* Implements hook_module_implements_alter().
*
* @see hook_module_implements_alter()
*/
function node_export_dsv_module_implements_alter(&$implementations, $hook) {
if ($hook == 'node_export_import') {
// Move node_export_dsv_node_export_import() to the end of the list.=
// Node export DSV is slow to fire on imports, so this allows other
// modules to respond first.
$group = $implementations['node_export_dsv'];
unset($implementations['node_export_dsv']);
$implementations['node_export_dsv'] = $group;
}
}
/**
* Implements hook_node_export().
*
* @see hook_node_export()
*/
function node_export_dsv_node_export($nodes, $format) {
$delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
$enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
$seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\\r\\n'));
$escape_eol = variable_get('node_export_dsv_escape_eol', 1);
return node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol);
}
/**
* Build DSV string.
*/
function node_export_dsv_encode($nodes, $delimiter, $enclosure, $seperator, $escape_eol) {
$encoded_nodes = array();
$dsv_lines = array();
$node_keys = array();
foreach (array_keys($nodes) as $node_key) {
$new_node_key = 'node_' . $node_key;
$node_keys[] = $new_node_key;
node_export_dsv_encode_node($encoded_nodes, $new_node_key, $nodes[$node_key]);
}
$dsv_lines['node_export_dsv_header'] = array_keys($encoded_nodes);
foreach (array_keys($encoded_nodes) as $header_value) {
$encoded_nodes[$header_value] = array_merge(array_fill_keys($node_keys, NULL), $encoded_nodes[$header_value]);
foreach (array_keys($encoded_nodes[$header_value]) as $encoded_node_key) {
$dsv_lines[$encoded_node_key][$header_value] = $encoded_nodes[$header_value][$encoded_node_key];
}
}
return node_export_dsv_array_to_dsv($dsv_lines, $delimiter, $enclosure, $seperator, $escape_eol);
}
/**
* Process a node and update $header and $encoded_nodes accordingly.
*/
function node_export_dsv_encode_node(&$encoded_nodes, $node_key, $var, $parent = NULL) {
foreach ($var as $k => &$v) {
// Get the new header value.
$header_value = node_export_dsv_encode_header_value($parent, $var, $k);
if (is_object($v) || is_array($v)) {
// Recurse through the structure.
node_export_dsv_encode_node($encoded_nodes, $node_key, $v, $header_value);
}
else {
// Create a safe text version of this value and store it against the header using a safe key.
$encoded_nodes[$header_value][$node_key] = node_export_dsv_encode_sanitize_value($v);
}
}
}
/**
* Encode a value.
*/
function node_export_dsv_encode_sanitize_value($var) {
if (is_numeric($var)) {
return $var;
}
elseif (is_bool($var)) {
return $var ? 'TRUE' : 'FALSE';
}
elseif (is_null($var)) {
return 'NULL';
}
elseif (is_string($var) && !empty($var)) {
// Single-quote strings that could be confused for null or boolean.
if (in_array(strtoupper($var), array(
'TRUE',
'FALSE',
'NULL',
))) {
$var = "'" . $var . "'";
}
return $var;
}
else {
return '';
}
}
/**
* Decode a value.
*/
function node_export_dsv_decode_sanitize_value($var) {
// Allow numeric, bool, and null values to pass right back as is.
if (is_numeric($var) || is_bool($var) || is_null($var)) {
return $var;
}
elseif (in_array(strtoupper($var), array(
"'TRUE'",
"'FALSE'",
"'NULL'",
))) {
return $var;
}
// Assume this is a string.
return "'" . str_replace("'", "\\'", $var) . "'";
}
/**
* Create header value from $parents, $var, and $k.
*/
function node_export_dsv_encode_header_value($parents, $var, $k) {
if (is_null($parents)) {
// Special case; on the first level do not prefix the key.
$header_value = $k;
}
elseif (is_object($var)) {
$header_value = $parents . "->" . $k;
}
elseif (is_array($var)) {
$header_value = $parents . "['" . $k . "']";
}
return $header_value;
}
/**
* Implements hook_node_export_import().
*
* @see hook_node_export_import()
*/
function node_export_dsv_node_export_import($code_string) {
$delimiter = node_export_dsv_string(variable_get('node_export_dsv_delimiter', ','));
$enclosure = node_export_dsv_string(variable_get('node_export_dsv_enclosure', '"'));
$seperator = node_export_dsv_string(variable_get('node_export_dsv_seperator', '\\r\\n'));
return node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator);
}
/**
* Interpret a DSV string.
*/
function node_export_dsv_decode($code_string, $delimiter, $enclosure, $seperator) {
// Get array data from DSV.
$array = @node_export_dsv_dsv_to_array($code_string, $delimiter, $enclosure, $seperator);
// If the first two rows are of equal length, we can assume this is a DSV.
// Also checks there are a decent number of fields.
if (!empty($array[0]) && !empty($array[1]) && count($array[0]) > 10 && count($array[0]) == count($array[1])) {
$nodes = array();
// Assume row 0 is the header, and the rest of the rows are the nodes.
$header = array_shift($array);
// Build the nodes.
foreach ($array as &$row) {
$node = (object) array();
foreach ($row as $key => $item) {
$item = node_export_dsv_decode_sanitize_value($item);
eval('$node->' . $header[$key] . ' = ' . $item . ';');
}
$nodes[] = $node;
}
return $nodes;
}
}
/**
* Encode DSV.
*/
function node_export_dsv_array_to_dsv($array, $delimiter, $enclosure, $seperator, $escape_eol) {
$lines = array();
foreach ($array as $line) {
$out_item = array();
foreach ($line as $item) {
if (stripos($item, $enclosure) !== FALSE) {
$item = str_replace($enclosure, $enclosure . $enclosure, $item);
}
if (stripos($item, $delimiter) !== FALSE || stripos($item, $enclosure) !== FALSE || stripos($item, $seperator) !== FALSE || $escape_eol && stripos($item, "\n") !== FALSE) {
$item = $enclosure . $item . $enclosure;
}
$out_item[] = $item;
}
$lines[] = implode($delimiter, $out_item);
}
return implode($seperator, $lines);
}
/**
* Decode DSV.
*/
function node_export_dsv_dsv_to_array($string, $delimiter, $enclosure, $seperator) {
$lines = array();
$out_item = array();
$count = strlen($string);
$escape = FALSE;
$double_escape = FALSE;
$position = 0;
$i = 0;
$seperators = str_split($seperator);
while ($i < $count) {
$c = $string[$i];
// Determine whether this is an EOL.
$is_eol = TRUE;
for ($j = 0; $j < count($seperators); $j++) {
if (!isset($string[$i + $j]) || $string[$i + $j] != $seperators[$j]) {
$is_eol = FALSE;
break;
}
}
if ($is_eol) {
if ($escape) {
$out_item[$position] .= $c;
}
else {
$i += count($seperators);
$lines[] = $out_item;
$out_item = array();
$position = 0;
continue;
}
}
elseif ($c == $delimiter) {
if ($escape) {
$out_item[$position] .= $c;
}
else {
if ($string[$i - 1] == $delimiter) {
$out_item[$position] .= '';
}
$position++;
$escape = FALSE;
$double_escape = FALSE;
}
}
elseif ($c == $enclosure) {
if ($double_escape) {
$out_item[$position] .= $enclosure;
$double_escape = FALSE;
}
if ($escape) {
$escape = FALSE;
$double_escape = TRUE;
}
else {
$escape = TRUE;
$double_escape = FALSE;
}
}
else {
if ($double_escape) {
$out_item[$position] .= $enclosure;
$double_escape = FALSE;
}
$out_item[$position] .= $c;
}
$i++;
}
if (!empty($out_item)) {
$lines[] = $out_item;
}
return $lines;
}
Functions
Name | Description |
---|---|
node_export_dsv_array_to_dsv | Encode DSV. |
node_export_dsv_decode | Interpret a DSV string. |
node_export_dsv_decode_sanitize_value | Decode a value. |
node_export_dsv_dsv_to_array | Decode DSV. |
node_export_dsv_encode | Build DSV string. |
node_export_dsv_encode_header_value | Create header value from $parents, $var, and $k. |
node_export_dsv_encode_node | Process a node and update $header and $encoded_nodes accordingly. |
node_export_dsv_encode_sanitize_value | Encode a value. |
node_export_dsv_form_node_export_settings_alter | Implementation of hook_form_FORM_ID_alter(). |
node_export_dsv_module_implements_alter | Implements hook_module_implements_alter(). |
node_export_dsv_node_export | Implements hook_node_export(). |
node_export_dsv_node_export_format_handlers | Implements hook_node_export_format_handlers(). |
node_export_dsv_node_export_import | Implements hook_node_export_import(). |
node_export_dsv_string | Replace special character strings with special character. |