Index: README.txt =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/node_import/README.txt,v retrieving revision 1.1 diff -c -r1.1 README.txt *** README.txt 13 Oct 2004 13:01:40 -0000 1.1 --- README.txt 27 Mar 2006 09:55:31 -0000 *************** *** 1,13 **** ! This module enables importing of nodes of any type into Drupal. It accepts as input a comma separated values (CSV) file. ! Your CSV file must contain field names in its first row. The following fields are required: ! - title ! - uid or name [both are ignored if current user does not have 'administer nodes' permission. if user does have this permission, name is used if available, otherwise uid, otherwise 'anonymous user' is assumed] ! - type ! Your CSV file should use quotes around strings that contain a comma. Parsing is handled by the fgetcsv function. See http://www.php.net/fgetcsv for details. ! Field names should match columns in your database. Field values should match those usually entered into your DB. ! This module adds a 'node import' link to your Navigation menu which is viewable by users who have the 'node import' permission. --- 1,34 ---- ! Updated for Drupal 4.7 2006/3/27 by ! njivy ! dado ! Robrecht ! This module enables importing of nodes of any type into Drupal. ! It accepts as input a comma separated values (CSV) file. ! Your CSV file must contain field names in its first row. ! Your CSV file should use double quotes around strings that contain a comma. ! Parsing is handled by the fgetcsv function. See http://www.php.net/fgetcsv for details. ! This module adds an 'import' link to your navigation menu under "admin->content", ! which is viewable by users who have the 'node import' permission. ! This module provides a wizard, which walks the admin/user through the importation process. ! First, the admin/user selects the CSV file to upload. ! Next, she selects the node type she wishes to import this data into. ! Next, she maps the fields in the CSV file to fields for the selected node type. ! Next, she previews the nodes that would be imported. ! Finally, she imports the nodes. This module does not overwrite nodes of the selected type, with the identical title. + This module provides an easy API to permit any node type to be imported. To make your node type importable via + this module, you must create 2 or more functions, to tell which fields exist, etc. See + node_import_hook_docs.php + + As of 2006/3/27, this module is not fully tested. These node types are importable. + flexinodes + cck nodes + event-enabled nodes + location-enabled nodes + weblink + story + page \ No newline at end of file Index: import_flexinode.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/node_import/import_flexinode.inc,v retrieving revision 1.5 diff -c -r1.5 import_flexinode.inc *** import_flexinode.inc 1 Jul 2005 23:37:02 -0000 1.5 --- import_flexinode.inc 27 Mar 2006 09:55:31 -0000 *************** *** 23,45 **** } function flexinode_node_import_static($type) { - global $user; $type = explode('-', $type); if ($type[0] == 'flexinode') { - // Use the current user's information for importing stories. return array('ctype_id' => $type[1]); } } - function flexinode_node_import_global($type) { - $type = explode('-', $type); - - if ($type[0] == 'flexinode') { - return implode('', taxonomy_node_form('flexinode-'. $type[1])); - } - } - function flexinode_node_import_prepare(&$node, $preview = FALSE) { $type = explode('-', $node->type); --- 23,35 ---- *************** *** 58,63 **** --- 48,54 ---- $node->{'flexinode_'. $field->field_id .'hour'} = $time['hours']; $node->{'flexinode_'. $field->field_id .'minute'} = $time['minutes']; } + // Hmm. unset($node->$whatdate); } } Index: node_import.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/node_import/node_import.module,v retrieving revision 1.16 diff -c -r1.16 node_import.module *** node_import.module 28 Jun 2005 00:28:55 -0000 1.16 --- node_import.module 27 Mar 2006 09:55:32 -0000 *************** *** 3,14 **** --- 3,23 ---- ini_set('auto_detect_line_endings', TRUE); + if (module_exist('taxonomy')) { + include_once('import_taxonomy.inc'); + } if (module_exist('flexinode')) { include_once('import_flexinode.inc'); } + if (module_exist('content')) { + include_once('import_cck.inc'); + } if (module_exist('event')) { include_once('import_event.inc'); } + if (module_exist('location')) { + include_once('import_location.inc'); + } if (module_exist('weblink')) { include_once('import_weblink.inc'); } *************** *** 42,48 **** function node_import_menu($may_cache) { $links = array(); if ($may_cache) { ! $links[] = array('path' => 'admin/node/node_import', 'title' => t('import'), 'callback' => 'node_import_page', 'weight' => 5, 'access' => user_access('import nodes')); } return $links; } --- 51,61 ---- function node_import_menu($may_cache) { $links = array(); if ($may_cache) { ! $links[] = array('path' => 'admin/node/node_import', ! 'title' => t('import'), ! 'callback' => 'node_import_page', ! 'weight' => 5, ! 'access' => user_access('import nodes')); } return $links; } *************** *** 52,66 **** } function node_import_page() { ! $edit = array_merge($_SESSION['node_import'], $_POST['edit']); // validate the form if ($_SESSION['node_import_page'] && $_POST) { $function = $_SESSION['node_import_page'] .'_validate'; $function($_POST['op'], $edit); } else { $_SESSION['node_import_page'] = '_node_import_start'; } $output = $_SESSION['node_import_page']($edit); --- 65,84 ---- } function node_import_page() { ! $edit = array_merge((array)$_SESSION['node_import'], (array)$_POST['edit']); ! ! // This prevents drupal_get_form() from performing extra validation. ! unset($_POST['edit']); // validate the form if ($_SESSION['node_import_page'] && $_POST) { + // Hmm. $function = $_SESSION['node_import_page'] .'_validate'; $function($_POST['op'], $edit); } else { $_SESSION['node_import_page'] = '_node_import_start'; + //dado: need to validate per 4 lines above? } $output = $_SESSION['node_import_page']($edit); *************** *** 69,97 **** $_SESSION['node_import'] = $edit; if ($_POST['op'] == t('Download rows with errors')) { ! print $output; } else { ! print theme('page', $output); } } function _node_import_start($edit) { if ($edit['file']) { ! $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .')
'. form_submit(t('Use a different file'))); } else { ! $output .= form_file(t('Upload CSV file'), 'file', 48, t('Comma separated values file containing the data to be imported.')); } $types = module_invoke_all('node_import_types'); $types['node_import'] = t('raw data (advanced)'); ! $output .= form_select(t('Type'), 'type', $edit['type'], $types); ! // todo add an insert/update option ! $output .= form_submit(t('Next')); ! return form($output, 'post', 0, array('enctype' => 'multipart/form-data')); } function _node_import_start_validate($op, &$edit) { --- 87,138 ---- $_SESSION['node_import'] = $edit; if ($_POST['op'] == t('Download rows with errors')) { ! return $output; } else { ! return $output; } } function _node_import_start($edit) { if ($edit['file']) { ! $form[] = array( ! '#type' => 'item', ! '#title' => t('File'), ! '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .')' ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Use a different file') ! ); } else { ! $form['file'] = array( ! '#type' => 'file', ! '#title' => t('Upload CSV file'), ! '#size' => 48, ! '#description' => t('Comma separated values file containing the data to be imported.'), ! ); } $types = module_invoke_all('node_import_types'); $types['node_import'] = t('raw data (advanced)'); ! $form['type'] = array( ! '#type' => 'select', ! '#title' => t('Type'), ! '#default_value' => $edit['type'], ! '#options' => $types, ! ); // todo add an insert/update option ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Next'), ! ); ! $form['#method'] = 'post'; ! $form['#action'] = 0; ! $form['#attributes'] = array('enctype' => 'multipart/form-data'); ! return drupal_get_form('node_import_start', $form); } function _node_import_start_validate($op, &$edit) { *************** *** 129,140 **** } function _node_import_options($edit) { ! $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') '); // todo add in a place to select fields to match on for update if ($edit['type'] != 'node_import') { ! $output .= '

'. t('Field matching') .'

'; $fields = array_merge(array('' => t('')), module_invoke_all('node_import_fields', $edit['type'])); $header = array(t('CSV header'), t('Import to field'), t('Sample data')); $data = array(); --- 170,189 ---- } function _node_import_options($edit) { ! $form[] = array( ! '#type' => 'item', ! '#title' => t('File'), ! '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ', ! ); // todo add in a place to select fields to match on for update if ($edit['type'] != 'node_import') { ! $form[] = array( ! '#type' => 'item', ! '#title' => t('Field matching'), ! '#value' => '' ! ); $fields = array_merge(array('' => t('')), module_invoke_all('node_import_fields', $edit['type'])); $header = array(t('CSV header'), t('Import to field'), t('Sample data')); $data = array(); *************** *** 146,152 **** } } foreach ($csvheader as $i => $value) { ! $data[] = array($value, form_select('', 'match]['. $i, $edit['match'][$i], $fields)); } $j = 0; while (($row = fgetcsv($handle, 10000, ',')) && $j++ < 5) { --- 195,208 ---- } } foreach ($csvheader as $i => $value) { ! $form['match]['. $i] = array( ! '#type' => 'select', ! '#title' => '', ! '#default_value' => $edit['match'][$i], ! '#options' => $fields ! ); ! $form = form_builder('node_import_options', $form); ! $data[] = array($value, form_render($form['match]['. $i])); } $j = 0; while (($row = fgetcsv($handle, 10000, ',')) && $j++ < 5) { *************** *** 158,173 **** foreach ($datatmp as $i => $value) { $data[$i][] = implode(', ', $value); } - $output .= theme('table', $header, $data); ! if ($global = implode('', module_invoke_all('node_import_global', $edit['type']))) { ! $output .= form_group(t('Global fields'), str_replace('edit[', 'edit[global][', $global)); } } ! $output .= form_submit(t('Preview')); ! $output .= form_submit(t('Back')); ! return form($output); } function _node_import_options_validate($op, &$edit) { --- 214,245 ---- foreach ($datatmp as $i => $value) { $data[$i][] = implode(', ', $value); } ! $form[] = array( ! '#type' => 'item', ! '#title' => '', ! '#value' => theme('table', $header, $data) ! ); ! ! if ($global = module_invoke_all('node_import_global', $edit['type'])) { ! $form['global'] = array( ! '#type' => 'fieldset', ! '#title' => t('Global fields'), ! '#tree' => TRUE, ! 'global' => $global, ! ); } } ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Preview'), ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Back'), ! ); ! return drupal_get_form('node_import_opts', $form); } function _node_import_options_validate($op, &$edit) { *************** *** 180,201 **** } function _node_import_preview($edit) { ! $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') '); ! ! $output .= '

'. t('Preview') .'

'; ! $output .= form_select(t('Number of entries'), 'preview_count', $edit['preview_count'], drupal_map_assoc(array(5, 10, 15, 25, 50, 100, 150, 200))); if (!$edit['preview_count']) { $edit['preview_count'] = 5; } - $output .= form_submit(t('Apply')); - - $output .= _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['preview_count']); - - $output .= '

'. t('Importing may take awhile, do not click \'Import\' more than once. To see progress, look at the Administer >> Content page in a new window.') .'

'; ! $output .= form_submit(t('Import')); ! $output .= form_submit(t('Back')); ! return form($output); } function _node_import_preview_validate($op, &$edit) { --- 252,296 ---- } function _node_import_preview($edit) { ! $form[] = array( ! '#type' => 'item', ! '#title' => 'Preview', ! '#value' => '

'. t('Importing may take awhile, do not click \'Import\' more than once. To see progress, look at the Administer >> Content page in a new window.') .'

' ! ); ! $form[] = array( ! '#type' => 'item', ! '#title' => t('File'), ! '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ', ! ); if (!$edit['preview_count']) { $edit['preview_count'] = 5; } ! $form[] = array( ! '#type' => 'item', ! '#title' => '', ! '#value' => _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global']['global'], $edit['preview_count']) ! ); ! ! $form['preview_count'] = array( ! '#type' => 'select', ! '#title' => t('Number of entries to preview'), ! '#default_value' => $edit['preview_count'], ! '#options' => drupal_map_assoc(array(5, 10, 15, 25, 50, 100, 150, 200)), ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Apply'), ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Import'), ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Back'), ! ); ! return drupal_get_form('_node_import_prev', $form); } function _node_import_preview_validate($op, &$edit) { *************** *** 210,226 **** else if ($op == t('Import')) { $_SESSION['node_import_page'] = '_node_import_import'; } } function _node_import_import(&$edit) { ! $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') '); ! $output .= form_submit(t('Delete CSV file from server')); $edit['errors'] = 0; ! $output .= _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['errors']); unset($edit['match']); ! return form($output); } function _node_import_import_validate($op, &$edit) { --- 305,335 ---- else if ($op == t('Import')) { $_SESSION['node_import_page'] = '_node_import_import'; } + else if ($op == t('Apply')) { + $_SESSION['node_import_page'] = '_node_import_preview'; + } } function _node_import_import(&$edit) { ! $form[] = array( ! '#type' => 'item', ! '#title' => t('File'), ! '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ', ! ); ! $form[] = array( ! '#type' => 'submit', ! '#value' => t('Delete CSV file from server'), ! ); $edit['errors'] = 0; ! $form[] = array( ! '#type' => 'item', ! '#title' => '', ! '#value' => _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global']['global'], $edit['errors']) ! ); unset($edit['match']); ! return drupal_get_form('node_import_import', $form); } function _node_import_import_validate($op, &$edit) { *************** *** 263,271 **** $j = 0; $success = 0; while (($row = fgetcsv($handle, 10000, ',')) && ($j++ < $preview || $preview == 0)) { ! $node = array2object(array_merge(array('type' => $type), module_invoke_all('node_import_static', $type), $global)); foreach ($row as $i => $value) { ! $node->$match[$i] = $value; if ($match[$i] == 'name') { if ($account = user_load(array('name' => $value))) { $node->uid = $account->uid; --- 372,381 ---- $j = 0; $success = 0; while (($row = fgetcsv($handle, 10000, ',')) && ($j++ < $preview || $preview == 0)) { ! $node = (object) array_merge(array('type' => $type), (array)module_invoke_all('node_import_static', $type), (array)$global, (array)_node_import_static()); ! foreach ($row as $i => $value) { ! if( !empty($match[$i])) $node->$match[$i] = $value; if ($match[$i] == 'name') { if ($account = user_load(array('name' => $value))) { $node->uid = $account->uid; *************** *** 286,297 **** } } ! $node = node_validate($node); if (!node_access('create', $node)) { drupal_set_message(t('You are not authorized to post this type of node.'), 'error'); // todo be more specific about what type } if ($preview) { if (form_get_errors()) { $output .= theme('status_messages'); unset($GLOBALS['form']); --- 396,408 ---- } } ! node_validate($node); if (!node_access('create', $node)) { drupal_set_message(t('You are not authorized to post this type of node.'), 'error'); // todo be more specific about what type } if ($preview) { + userreview_debug('Node:', $node, false, false); if (form_get_errors()) { $output .= theme('status_messages'); unset($GLOBALS['form']); *************** *** 326,329 **** --- 437,451 ---- return $output; } + /** + * Returns array of static fields for all nodes + */ + function _node_import_static() { + return array( + 'date' => date('c'), + 'created' => time(), + 'changed' => time() + ); + } + ?> Index: import_cck.inc =================================================================== RCS file: import_cck.inc diff -N import_cck.inc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- import_cck.inc 1 Jan 1970 00:00:00 -0000 *************** *** 0 **** --- 1,40 ---- + $type) { + $types[$id] = $type->label; + } + return $types; + } + + function content_node_import_fields($type) { + $types = _content_types(); + if (!isset($types[$type])) return; + + $content_type = $types[$type]; + $fields = array(); + + //add the title field + $fields['title'] = $content_type->title_label; + + //add all cck widget fields + foreach ($content_type->fields as $field) { + $fields[$field['field_name']] = $field['widget']['label']; + } + return $fields; + } + + function content_node_import_prepare(&$node, $preview = FALSE) { + $types = _content_types(); + if (!isset($types[$node->type])) return; + $content_type = $types[$node->type]; + //add all cck widget fields + foreach ($content_type->fields as $field) { + $thisval = $node->$field['field_name']; + $node->$field['field_name'] = array('value' => $thisval); + } + return; + } + ?> Index: import_location.inc =================================================================== RCS file: import_location.inc diff -N import_location.inc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- import_location.inc 1 Jan 1970 00:00:00 -0000 *************** *** 0 **** --- 1,60 ---- + t('Location name'), + 'street' => t('Street'), + 'additional' => t('Additional Address'), + 'city' => t('City'), + 'province' => t('State or Province'), + 'postal_code' => t('Zip or Postal Code'), + 'country' => t('Country'), + 'latitude' => t('Latitude'), + 'longitude' => t('Longitude'), + ); + return $fields; + } + + + /** + * Hook that is called before node_validate. This allows a module to + * change the imported field from a user readable format to a format + * node_save understands. + * + * See import_taxonomy.inc for an example. + * + * @param &$node + * A node object which can be changed if needed. + * @param $preview + * Boolean. If TRUE this function is only run in a preview stage. The + * function should then avoid making permanent changes to any database + * table. If FALSE the function may commit permanent changes to the + * database that are needed to import the node. + * @return + * Nothing. + */ + function location_node_import_prepare(&$node, $preview = FALSE) { + if (!variable_get('location_'. $node->type, 0)) { + return; + } + $location = array(); + $location['name'] = $node->location_name; + $location['street'] = $node->street; + $location['additional'] = $node->additional; + $location['city'] = $node->city; + $location['province'] = $node->province; + $location['postal_code'] = $node->postal_code; + $location['country'] = $node->country; + $location['lat'] = $node->latitude; + $location['lon'] = $node->longitude; + if ($location['lat'] && $location['lon']) { + $location['source'] = LOCATION_LATLON_USER_SUBMITTED; + } + $node->location = $location; + return; + } + + ?> Index: import_taxonomy.inc =================================================================== RCS file: import_taxonomy.inc diff -N import_taxonomy.inc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- import_taxonomy.inc 1 Jan 1970 00:00:00 -0000 *************** *** 0 **** --- 1,14 ---- + type = $type; + $form['type']['#value'] = $node->type; + $form['#node']->type = $node->type; + + taxonomy_form_alter($node->type .'_node_form', $form); + unset($form['#node']); + unset($form['type']); + return $form; + } + ?>