Index: import_export.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/import_export/import_export.module,v retrieving revision 1.4 diff -u -r1.4 import_export.module --- import_export.module 4 Sep 2005 23:10:46 -0000 1.4 +++ import_export.module 12 Sep 2006 19:05:53 -0000 @@ -7,34 +7,34 @@ function import_export_menu($may_cache) { if ($may_cache) { - $items[] = array('path' => 'import', - 'title' => t('import/export'), + $items[] = array('path' => 'admin/import_export', + 'title' => t('import_export'), 'callback' => 'import_export_page', 'access' => user_access('access import_export'), 'type' => MENU_NORMAL_ITEM); - $items[] = array('path' => 'import/cvs/export', - 'title' => t('CVS export'), - 'callback' => 'import_export_page_cvs_export', + $items[] = array('path' => 'admin/import_export/csv/export', + 'title' => t('CSV export'), + 'callback' => 'import_export_page_csv_export', 'access' => user_access('access import_export'), 'type' => MENU_CALLBACK); - $items[] = array('path' => 'import/xml', + $items[] = array('path' => 'admin/import_export/xml', 'title' => t('XML import/export'), 'callback' => 'import_export_page_xml', 'access' => user_access('access import_export'), 'type' => MENU_CALLBACK); - $items[] = array('path' => 'import/xml/vocabulary', + $items[] = array('path' => 'admin/import_export/xml/vocabulary', 'title' => t('XML export (vocabulary)'), 'callback' => 'import_export_page_xml_vocabulary', 'access' => user_access('access import_export'), 'type' => MENU_CALLBACK); - $items[] = array('path' => 'import/xml/book', + $items[] = array('path' => 'admin/import_export/xml/book', 'title' => t('XML export (book)'), 'callback' => 'import_export_page_xml_book', 'access' => user_access('access import_export'), 'type' => MENU_CALLBACK); - $items[] = array('path' => 'import/cvs/import', - 'title' => t('CVS import'), - 'callback' => 'import_export_page_cvs_import', + $items[] = array('path' => 'admin/import_export/csv/import', + 'title' => t('CSV import'), + 'callback' => 'import_export_page_csv_import', 'access' => user_access('access import_export'), 'type' => MENU_CALLBACK); } @@ -48,10 +48,12 @@ function import_export_help($section) { switch ($section) { + case 'admin/help#import_export': + return t('

Import_export module imports and exports nodes as XML or CSV files.


Import/Export from a CSV file or a XML formated file is supported. The CSV is suitable for simple nodes (weblinks, images, etc.), the XML for large ones (stories, books, etc.). There is support for common nodes, stories, books, pages, images, flexinodes directly into module.


Note that files must be UTF-8 encoded.


Form groups are divided into four actions in the first page of the wizard you can choose from:

CSV export:

  1. In the first step you need to choose from the listed node/content types to export, and click next.


  2. In the second step in the wizard there are more options you need to carefully choose from:

  3. There are two seperate buttons to choose from:

Requirements:

XML import/export requires XML support in PHP, see PHP documentation. Generally http://www.jclark.com/xml/expat.html support should be installed.


Credits:

This patch is provided by Turhan Ercil,
this work is sponsored by
Ashoka.org and CoopTools.ca

 



'); case 'admin/modules#description': - return t('Import/export nodes from XML or CSV files'); - case 'admin/modules/import_eport': - return t('Import/export nodes from XML or CSV files'); + return t('Imports and exports nodes as XML or CSV files.'); + case 'admin/import_export': + return t('

Import_export module imports and exports nodes as XML or CSV files.


Import/Export from a CSV file or a XML formated file is supported. The CSV is suitable for simple nodes (weblinks, images, etc.), the XML for large ones (stories, books, etc.). There is support for common nodes, stories, books, pages, images, flexinodes directly into module.


Note that files must be UTF-8 encoded.

'); } } @@ -61,19 +63,19 @@ function import_export_page() { - $types = node_invoke_nodeapi($node/*dummy*/, 'import_export', 'types', IMPORT_EXPORT_CVS); + $types = node_invoke_nodeapi($node/*dummy*/, 'import_export', 'types', IMPORT_EXPORT_CSV); asort($types); if (count($types)) { $group = form_select(t('Node type'), 'node_type', -1, $types, t('Node type to export'), 0, false, true); $group .= form_submit(t('Next')); - $group = form($group, 'post', '?q=import/cvs/export'); - $output .= form_group(t('CVS export'), $group); + $group = form($group, 'post', '?q=admin/import_export/csv/export'); + $output .= form_group(t('CSV export'), $group); - $group = l(t('Import from CVS file'), 'import/cvs/import'); - $output .= form_group(t('CVS import'), $group); + $group = l(t('Import from CSV file'), 'admin/import_export/csv/import'); + $output .= form_group(t('CSV import'), $group); } else { - $output .= t('CVS import/export not supported by any module').'

'; + $output .= t('CSV import/export not supported by any module').'

'; } if (module_exist('taxonomy')) { @@ -85,7 +87,7 @@ } $group = form_select(t('Vocabulary'), 'vid', -1, $arr, t('Export according vocabulary terms'), 0, false, true); $group .= form_submit(t('Next')); - $group = form($group, 'post', '?q=import/xml/vocabulary'); + $group = form($group, 'post', '?q=admin/import_export/xml/vocabulary'); $output .= form_group(t('XML export by vocabulary'), $group); } } @@ -95,12 +97,12 @@ if (count($books)) { $group = form_select(t('Book'), 'nid', -1, $books, t('A parent which nodes are to be exported'), 0, false, true); $group .= form_submit(t('Next')); - $group = form($group, 'post', '?q=import/xml/book'); + $group = form($group, 'post', '?q=admin/import_export/xml/book'); $output .= form_group(t('XML book export'), $group); } } - $group = l(t('Export according node ids / Import from XML file'), 'import/xml'); + $group = l(t('Export according node ids / Import from XML file'), 'admin/import_export/xml'); $output .= form_group(t('XML import/export'), $group); print theme('page', $output); @@ -145,14 +147,14 @@ } /** - * Implementation of CVS export page + * Implementation of CSV export page */ -function import_export_page_cvs_export() { +function import_export_page_csv_export() { $output = ''; $node = new StdClass(); $node->type = $_POST['edit']['node_type']; - _import_export_prepare_fields($node, IMPORT_EXPORT_CVS); + _import_export_prepare_fields($node, IMPORT_EXPORT_CSV); $arr = array(); foreach ($node->import_export_fields as $key=>$f) { @@ -165,29 +167,36 @@ $output .= t('No fields to export'); } else { - $group = form_item(t('Node type'), $_POST['edit']['node_type']); $arr = array(); foreach ($node->import_export_fields as $key=>$f) { if ($f['order']) { $arr[$key] = $f['caption']; } } - $group .= form_select(t('Fields'), 'fields', $_POST['edit']['fields'], $arr, t('Fields to export'), 0, true, true); + $group = form_select(t('Fields'), 'fields', $_POST['edit']['fields'], $arr, t('Fields to export'), 0, true, true); Unset($arr); - $group .= form_textfield(t('Max.field length'), 'maxlen', $_POST['edit']['maxlen'], 5, 5, t('Max.length of a CVS field')); +//New form fields START (Delimiter variations) + $group_extra = form_radios(t('Output format of the Taxonomy terms'), 'taxonomy_format', $_POST['edit']['taxonomy_format'], array(t('Term names e.g. "linux|new projects"'), t('Term ID (tid field) e.g. "34"'), t('Both e.g. "id=term_name"'))); + $group_extra .= form_textfield(t('Multiple-term delimiter'), 'delim_array', '|', 1, 2, t('Choose multiple term delimiter')); + $group .= form_group('Taxonomy Settings', $group_extra); + $group_extra = form_textfield(t('Field delimiter'), 'delim', ',', 1, 2, t('Choose delimiter')); + $group_extra .= form_textfield(t('Text delimiter'), 'delim_text', '"', 1, 2, t('Choose text delimiter')); + $group .= form_group('CSV Settings', $group_extra); +//New form fields END + $group .= form_textfield(t('Max. field length'), 'maxlen', $_POST['edit']['maxlen'], 5, 5, t('Max.length of a CSV field')); $group .= form_hidden('node_type', $_POST['edit']['node_type']); - $group .= form_submit(t('Export'), 'op_cvs[export]'); - $group .= form_submit(t('Friendly export'), 'op_cvs[friendly]'); + $group .= form_submit(t('Export'), 'op_csv[export]'); + $group .= form_submit(t('Friendly export'), 'op_csv[friendly]'); $group = form($group, 'post', 0); - $output .= form_group('', $group); + $output .= form_group(t('Node type').': '.$_POST['edit']['node_type'], $group); } $out = ''; - if ($_POST['op_cvs'] && !Count($_POST['edit']['fields'])) { + if ($_POST['op_csv'] && !Count($_POST['edit']['fields'])) { $output .= t('No fields selected'); } - else if ($_POST['op_cvs']) { + else if ($_POST['op_csv']) { foreach ($node->import_export_fields as $fid=>$fld) { if (!In_Array($fid, $_POST['edit']['fields'])) { @@ -201,17 +210,17 @@ $nodeids[] = $rec['nid']; } - $n = _import_export_prepare_cvs($nodeids, $node->import_export_fields, $_POST['edit']['maxlen'], $out); + $n = _import_export_prepare_csv($nodeids, $node->import_export_fields, $_POST['edit']['maxlen'], $out); Unset($nodeids); Unset($node->import_export_fields); $output .= "
\n";
     if ($n >= 0) {
-      $output .= sprintf(t('%d exported record(s)'), $n)."\n\n";
+      $output .= sprintf(t('%d exported record(s)'), $n)."\n"; // Deleted /n for symmetry
     }
     $output .= "
\n"; } - _import_export_print($output, $out, $_POST['op_cvs']['friendly'], 'text/plain', 'export.txt'); + _import_export_print($output, $out, $_POST['op_csv']['friendly'], 'text/plain', 'export.txt'); } /** @@ -378,27 +387,27 @@ } /** - * Implementation of common CVS import page + * Implementation of common CSV import page */ -function import_export_page_cvs_import() { +function import_export_page_csv_import() { $output = ''; - $group = form_textarea(t('CVS data'), 'cvs_data', $_POST['edit']['cvs_data'], 80, 10, t('CVS data to be imported, first raw is header containing field names (TAB/\'|\'..field delimiter, CR/LF..record delimiter, \':\'..array delimiter).')); + $group = form_textarea(t('CSV data'), 'csv_data', $_POST['edit']['csv_data'], 80, 10, t('CSV data to be imported, first raw is header containing field names (TAB/\'|\'..field delimiter, CR/LF..record delimiter, \':\'..array delimiter).')); $group .= _import_export_form_radios_action(); - $types = node_invoke_nodeapi($node, 'import_export', 'types', IMPORT_EXPORT_CVS); + $types = node_invoke_nodeapi($node, 'import_export', 'types', IMPORT_EXPORT_CSV); asort($types); $types = array_merge(array(''=>'<'.t('none').'>'), $types); - $group .= form_select(t('Node type'), 'def_type', $_POST['edit']['def_type'], $types, t('Default node type used unless specified in CVS field'), 0, false, true); - $group .= form_submit(t('Preview'), 'op_cvs[preview]'); - $group .= form_submit(t('Process'), 'op_cvs[import]'); + $group .= form_select(t('Node type'), 'def_type', $_POST['edit']['def_type'], $types, t('Default node type used unless specified in CSV field'), 0, false, true); + $group .= form_submit(t('Preview'), 'op_csv[preview]'); + $group .= form_submit(t('Process'), 'op_csv[import]'); $group = form($group, 'post', 0); $output .= form_group(t('Import'), $group); - if ($_POST['op_cvs']) { - _import_export_parse_cvs($_POST['edit']['cvs_data'], $_POST['op_cvs']['preview'], _import_export_form_radio2text(), $_POST['edit']['def_type'], $out, $cnt, $cnt1); + if ($_POST['op_csv']) { + _import_export_parse_csv($_POST['edit']['csv_data'], $_POST['op_csv']['preview'], _import_export_form_radio2text(), $_POST['edit']['def_type'], $out, $cnt, $cnt1); $output .= "
\n";
     $output .= sprintf(t('Processed %d of %d line(s)'), $cnt1, $cnt)."\n
\n".$out.'
'; } @@ -406,10 +415,10 @@ print theme('page', $output); } -// CVS delimiter definitions -define('CVS_FIELD_DELIM', '|'); -define('CVS_RECORD_DELIM', "\r\n"); -define('CVS_ARRAY_DELIM', ':'); +// CSV delimiter definitions +define('CSV_FIELD_DELIM', $_POST['edit']['delim']); +define('CSV_RECORD_DELIM', "\r\n"); +define('CSV_ARRAY_DELIM', $_POST['edit']['delim_array']); function _import_export_node2str(&$node, $fid, $fld, &$data) { @@ -428,7 +437,7 @@ } /** - * Export node data in CVS format + * Export node data in CSV format * @param $node * array od nids * @@ -439,7 +448,7 @@ * max. length of exported fields, leave blank or null to unlimited length * * @param $output - * exported CVS data + * exported CSV data * * @param field_delimiter * char delimiting fields @@ -448,7 +457,8 @@ * number of exported lines, -1..error */ -function _import_export_prepare_cvs($nodeids, $fields, $maxlen, &$output, $field_delimiter = CVS_FIELD_DELIM) { +function _import_export_prepare_csv($nodeids, $fields, $maxlen, &$output, $field_delimiter = CSV_FIELD_DELIM) { + $taxonomy_format = $_POST['edit']['taxonomy_format']; $cnt = 0; $output = ''; if (count($fields) == 0) { @@ -459,10 +469,12 @@ $arr = array(); foreach($fields as $fid=>$fld) { if ($fld['order']) { + $delim_text = $_POST['edit']['delim_text']; + $fld['name'] = $delim_text.str_replace('"', "'", $fld['name']).$delim_text; $arr[] = $fld['name']; } } - $output .= Implode($arr, $field_delimiter).CVS_RECORD_DELIM; + $output .= Implode($arr, $field_delimiter).CSV_RECORD_DELIM; foreach ($nodeids as $nodeid) { $node = _import_export_node_load($nodeid); @@ -472,6 +484,7 @@ $f_arr = array(); foreach($fields as $fid=>$fld) { + $delim_text = $_POST['edit']['delim_text']; if (!$fld['order']) { continue; } @@ -482,33 +495,37 @@ $tax = taxonomy_node_get_terms_by_vocabulary($node->nid, $fld['vid']); $arr = array(); foreach ($tax as $tid=>$term) { - switch ($fld['format']) { + switch ($taxonomy_format) { case IMPORT_EXPORT_TERM_FORMAT_NAME: $arr[] = preg_replace('/:/', '-', $term->name); break; case IMPORT_EXPORT_TERM_FORMAT_ID_NAME: $arr[] = sprintf('%d=%s', $tid, preg_replace('/:/', '-', $term->name)); break; - default: + case IMPORT_EXPORT_TERM_FORMAT_ID: $arr[] = $tid; break; } } - $s = Implode($arr, CVS_ARRAY_DELIM); + + $s = Implode($arr, CSV_ARRAY_DELIM); + $s = $delim_text.str_replace('"', "'", "$s").$delim_text; //Wrap around text delimiter } break; default: _import_export_node2str($node, $fid, $fld, $s); + $s = str_replace('"', "'", "$s"); if ($maxlen) { $s = SubStr($s, 0, $maxlen); } + $s = $delim_text.$s.$delim_text; //Wrap around text delimiter break; } - $f_arr[] = preg_replace(array('/\\'.CVS_FIELD_DELIM.'/', '/\\\\/', "/\r\n/", "/\r/", "/\n/"), - array(' ', '\\\\', '\\n', '', '\\n'), + $f_arr[] = preg_replace(array('/\\\\/', "/\r\n/", "/\r/", "/\n/"), + array('\\\\', '\\n', '', '\\n'), $s); } - $output .= Implode($f_arr, CVS_FIELD_DELIM).CVS_RECORD_DELIM; + $output .= Implode($f_arr, CSV_FIELD_DELIM).CSV_RECORD_DELIM; Unset($f_arr); $cnt++; } @@ -612,7 +629,7 @@ } if ($type!='' && $node->type!=$type) { - $output .= t('CVS/node type does not match'); + $output .= t('CSV/node type does not match'); return false; } $node->_taxonomy = array(); @@ -811,8 +828,8 @@ /** * Load current node (if exists) and check if $action can be processed * - * @param $cvs_data - * raw CVS data + * @param $csv_data + * raw CSV data * * @param $preview * do not save changes, only write log @@ -827,23 +844,23 @@ * text process log * * @param $num_lines - * counter of CVS data lines + * counter of CSV data lines * * @param $num_proc * counter of processed records/lines */ -function _import_export_parse_cvs($cvs_data, $preview, $action, $def_type, &$output, &$num_lines, &$num_proc) { +function _import_export_parse_csv($csv_data, $preview, $action, $def_type, &$output, &$num_lines, &$num_proc) { $output = ''; if ($preview) { $output .= '*** '.t('Preview mode, no data has been affected')." ***\n\n"; } - $cvs_data = preg_replace(array("/\t/", "/\r/", "/\n\n/"), - array(CVS_FIELD_DELIM, "\n", "\n"), - $cvs_data); - $rows = Explode("\n", $cvs_data); - Unset($cvs_data); - $flds = Explode(CVS_FIELD_DELIM, $rows[0]); + $csv_data = preg_replace(array("/\t/", "/\r/", "/\n\n/"), + array(CSV_FIELD_DELIM, "\n", "\n"), + $csv_data); + $rows = Explode("\n", $csv_data); + Unset($csv_data); + $flds = Explode(CSV_FIELD_DELIM, $rows[0]); $mandatory_idx = array(); $mandatory_import_fields = _import_export_get_mandatory_import_fields(); @@ -858,13 +875,13 @@ $fixups = _import_export_node_init_fixup(); $num_lines = $num_proc = 0; - $supported_types = node_invoke_nodeapi($node/*dummy*/, 'import_export', 'types', IMPORT_EXPORT_CVS); + $supported_types = node_invoke_nodeapi($node/*dummy*/, 'import_export', 'types', IMPORT_EXPORT_CSV); for ($i=1; $idata -// CVS taxonomy export format -define ('IMPORT_EXPORT_TERM_FORMAT_ID', 0); // id1:id2 -define ('IMPORT_EXPORT_TERM_FORMAT_NAME', 1); // name1:name2 +// CSV taxonomy export format +define ('IMPORT_EXPORT_TERM_FORMAT_ID', 1); // id1:id2 +define ('IMPORT_EXPORT_TERM_FORMAT_NAME', 0); // name1:name2 define ('IMPORT_EXPORT_TERM_FORMAT_ID_NAME', 2); // id1=name1:id2=name2 // $kind of import/export -define ('IMPORT_EXPORT_CVS', 1); +define ('IMPORT_EXPORT_CSV', 1); define ('IMPORT_EXPORT_XML', 2); // $level, defines group of fields for XML export @@ -1244,7 +1261,7 @@ function _import_export_prepare_fields(&$node, $kind) { $default_fields = array( - 'nid'=> array('type'=>IMPORT_EXPORT_ATTR /*'kind'=>IMPORT_EXPORT_CVS|IMPORT_EXPORT_XML*/), + 'nid'=> array('type'=>IMPORT_EXPORT_ATTR /*'kind'=>IMPORT_EXPORT_CSV|IMPORT_EXPORT_XML*/), 'type'=>array('type'=>IMPORT_EXPORT_ATTR), 'parent'=>array('type'=>IMPORT_EXPORT_ATTR, 'flags'=>XML_FLAGS_REMOVE_EMPTY), // 'parent', 'weight' outline field defined by book 'weight'=>array('type'=>IMPORT_EXPORT_ATTR), @@ -1271,7 +1288,7 @@ if (module_exist("taxonomy")) { foreach (taxonomy_get_vocabularies($node->type) as $vid => $voc) { $node->import_export_fields[(string) $vid] = array('type'=>IMPORT_EXPORT_TERMS, 'vid'=>$vid, 'caption'=>$voc->name .' *', 'level'=>IMPORT_EXPORT_TAXONOMY, 'order'=>$n++); - $node->import_export_fields[(string) $vid]['name'] = (($kind & IMPORT_EXPORT_CVS)?'*':'').$voc->name; + $node->import_export_fields[(string) $vid]['name'] = (($kind & IMPORT_EXPORT_CSV)?'*':'').$voc->name; } } node_invoke_nodeapi($node, 'import_export', 'fields', $kind); @@ -1285,7 +1302,7 @@ * node object * * @param $kind - * IMPORT_EXPORT_XML/CVS + * IMPORT_EXPORT_XML/CSV * * @param $default_fields * array of definitions, see exported data and definition in _import_export_prepare_fields() @@ -1303,7 +1320,7 @@ } foreach ($default_fields as $fld=>$opt) { - if ($kind == IMPORT_EXPORT_CVS && $opt['type'] == IMPORT_EXPORT_FAKE) { + if ($kind == IMPORT_EXPORT_CSV && $opt['type'] == IMPORT_EXPORT_FAKE) { continue; } if (!IsSet($opt['kind']) || $opt['kind'] & $kind) {