Upload csv file containing data to import. Minimum fields present should be nid or booking_tempid, " . " along with fields specified below. CSV Column names should match exactly (case sensitive).
"); $prefix .= "Note that only registration specific data like phone numbers, barcodes, etc can be updated. Other data like room allocations cannot be uploaded at this time.
"; $prefix .= "Also note that updating study group membership and roles requires nid to be present in the input file.
"; $form['file'] = array( '#type' => 'file', '#title' => t('CSV data'), '#description' => t('Upload CSV data to be processed'), ); // Get the database fields and sort them alphabetically to make it easier to find $booking_view_fields = _booking_get_person_fields(); sort($booking_view_fields, SORT_NATURAL | SORT_FLAG_CASE); //$nid_index = array_search("nid", $booking_view_fields); $select_array = array_combine($booking_view_fields, $booking_view_fields); $form['booking_import_data_fields'] = array( '#type' => 'select', '#multiple' => TRUE, '#title' => t('Select database fields for this import'), '#description' => t('Select database fields to import from an uploaded CSV file. Ensure you hold down control/command when selecting multiple options. ' . 'Fields are sorted alphabetically.'), '#options' => $select_array, '#size' => 10, '#default_value' => isset($form_state['input']['booking_import_data_fields']) ? $form_state['input']['booking_import_data_fields'] : 'nid', //'#default_value' => variable_get('booking_import_include_fields_dynamic', ''), ); $form['submit'] = array ( '#type' => 'submit', '#value' => t('Submit'), ); return array ( 'first_para' => array ( '#type' => 'markup', '#markup' => $prefix, ), 'form' => $form, ); } function booking_import_data_admin_validate($form, &$form_state) { $file = file_save_upload('file', array( 'file_validate_extensions' => array('txt csv'), // Validate extensions. )); // If the file passed validation: if ($file) { // Move the file, into the Drupal file system if ($file = file_move($file, 'public://', FILE_EXISTS_REPLACE )) { // Save the file for use in the submit handler. $form_state['storage']['file'] = $file; } else { form_set_error('file', t('Failed to write the uploaded file to the site\'s file folder.')); } } else { form_set_error('file', t('No file was uploaded.')); } } function booking_import_data_admin_submit($form, &$form_state) { global $event; $csvdata = array(); //$expected_fields = array('nid', 'booking_amount_paid', 'booking_total_pay_reqd', 'booking_status'); $error = false; $update_counter = 0; $delimiter = ","; $result_array = array(); $update_messages = array(); $datetime_fields = array('booking_outflight_origin_ts', 'booking_outflight_destination_ts', 'booking_rtrnflight_origin_ts', 'booking_rtrnflight_destination_ts','booking_dob', 'booking_passport_expiry_date'); $builtin_fields_to_import = array('nid'); // These are fields we can use to key the update $unique_fields = array('nid', 'booking_tempid'); $update_key = ""; //$custom_fields_to_import = explode(";", variable_get('booking_import_include_fields', '')); $data = $form_state['input']; $import_fields = $data['booking_import_data_fields']; $fields_to_import = array_merge($builtin_fields_to_import, $import_fields); watchdog('booking_debug', "CSV import fields\n@info", array('@info' => print_r($fields_to_import, true))); //get the file name from temporary storage field $file = $form_state['storage']['file']; // We are done with the file, remove it from storage. unset($form_state['storage']['file']); drupal_set_message(t('Input file uploaded successfully, filename: "@filename"', array('@filename' => $file->filename))); $filename = drupal_realpath($file->uri); //as per http://stackoverflow.com/questions/4541749/fgetcsv-fails-to-read-line-ending-in-mac-formatted-csv-file-any-better-solution ini_set("auto_detect_line_endings", "1"); //convert csv to associative array //based on http://stackoverflow.com/questions/4801895/csv-to-associative-array if( ($handle = fopen( $filename, "r")) !== FALSE) { $rowCounter = 0; while (($rowData = fgetcsv($handle, 0, $delimiter)) !== FALSE) { if( 0 === $rowCounter) { $headerRecord = $rowData; } else { foreach( $rowData as $key => $value) { $csvdata[$rowCounter - 1][ $headerRecord[$key] ] = $value; } } $rowCounter++; } fclose($handle); } else //unable to open file { drupal_set_message("Error: Unable to open input file " . $filename, 'error', FALSE); return; } //watchdog('booking', "
Import data:\n@info", array('@info' => print_r( $csvdata, true))); //process the input data foreach ($csvdata as $record) { $rows = 0; //watchdog('booking', "
Processing row data:\n@info", array('@info' => print_r( $record, true))); $update_counter++; $update_text = ""; $update_array = array(); $studygroups_update_array = array(); $studygroup_roles_update_array = array(); // Check that there is a key we can use to perform the update foreach ($unique_fields as $key) { if (array_key_exists($key, $record)) { $update_key = $key; } } // Check that we found a key, otherwise the update can't be processed if ($key === "") { drupal_set_message("Error: Unable to locate any unique identifier in input file for record number $update_counter.", 'error', FALSE); break; } // Pre-process some data foreach($fields_to_import as $field) { //make sure to skip the nid field since we can't update that if (in_array($field, $unique_fields)) { //Don't add this identifier to the list of updates } //convert the booking status to the number used internally elseif ($field == 'booking_status') { $update_text .= " set booking status to '" . $record[$field] . "'; "; $update_array[$field] = _booking_status_lookup($record[$field]); } //check for fields that need to be converted to a timestamp from text elseif (in_array($field, $datetime_fields)) { $update_array[$field] = _datetime_to_ts_nonstrict($record[$field]); $update_text .= " set '" . $field . "' to '" . $update_array[$field] . "'; "; } elseif ( (! isset($record[$field])) || $record[$field] == '') { //drupal_set_message("Error: Unable to locate expected field '$field' in input file for record number $update_counter.", 'error', FALSE); //watchdog('booking', 'Processing user record: @info', array ('@info' => $record['nid'])); //$error = true; //skip to the next record //continue 2; } elseif (preg_match('/session(\d{1,2})_role/i', $field, $matches)) { $session_id = $matches[1]; //drupal_set_message(t('Setting session id !field role to value: !info', array ('!field' => $session_id, '!info' => var_export($record[$field], TRUE)))); $studygroup_roles_update_array[$session_id] = $record[$field]; } elseif (preg_match('/session(\d{1,2})$/i', $field, $matches)) { $session_id = $matches[1]; //drupal_set_message(t('Setting session id !field group to value: !info', array ('!field' => $session_id, '!info' => var_export($record[$field], TRUE)))); $studygroups_update_array[$session_id] = $record[$field]; } else { $update_text .= " set '" . $field . "' to '" . $record[$field] . "'; "; $update_array[$field] = $record[$field]; } } // Perform the actual update if (count($update_array) > 0) { $query = db_update('booking_person') ->fields($update_array) ->condition($key, $record[$key]); $rows = $query->execute(); $update_messages[] = t("Update Query:
@values", array('@info' => (string) $query, '@nid' => $record[$key], '@rows' => $rows, '@values' => print_r( $update_array, true) )); } //handle study group processing only if the node id was used as a key if (isset($record['nid'])) { $update_text .= _booking_import_studygroup_info($record['nid'], $studygroups_update_array, $studygroup_roles_update_array); } drupal_set_message(t("Updating record !nid as follows: !update", array('!nid' => $record[$key], '!update' => $update_text))); } //end processing input data //output our results to watchdog watchdog('booking', "
Processing row data:\n@info", array('@info' => print_r($update_array, true))); //delete the uploaded file file_delete($file); //let the user know we finished drupal_set_message(t("Finished processing @count records from input file \"@filename\"", array('@count' => $update_counter, '@filename' => $file->filename))); watchdog('booking', "
Data Import concluded:\n" . implode("\n", $update_messages) . ""); /* // Make the storage of the file permanent $file->status = FILE_STATUS_PERMANENT; // Save file status. file_save($file); // Set a response to the user. drupal_set_message(t('The form has been submitted and the image has been saved, filename: @filename.', array('@filename' => $file->filename))); */ } /** * Function for processing CSV import data for study groups */ function _booking_import_studygroup_info($nid, $studygroups_update_array, $studygroup_roles_update_array) { global $event; $update_text = ""; $studygroup_roles = _booking_studygroup_role_lookup(); //update the study group mapping info if imported foreach ($studygroup_roles_update_array as $key => $value) { //turn leader/helper/reserve text into the number used internally in the database if (!is_numeric($value)) { $role = array_search($value, $studygroup_roles); } else { $role = $value; } //confirm that the data is valid if (is_numeric($key) && is_numeric($studygroups_update_array[$key])) { //check whether there is already a record to be updated or if it is a new record $record_check = db_query("SELECT * FROM {booking_studygroup_mapping} WHERE booking_eventid = :eid and booking_node_id = :nid and booking_studygroup_id = :sid", array(':eid' => $event->eid, ':nid' => $nid, ':sid' => $studygroups_update_array[$key]))->fetchObject(); //no existing record, so run a db_insert if (! $record_check) { $update_text .= t('Running DB insert for nid !nid, studygroup session id !id, for study group with ID !sid, for role !role;', array ('!nid' => $nid, '!id' => $key, '!sid' => $studygroups_update_array[$key], '!role' => $role)); db_insert('booking_studygroup_mapping') ->fields(array( 'booking_eventid' => $event->eid, 'booking_node_id' => $nid, 'booking_studygroup_id' => $key, 'booking_session_id' => $studygroups_update_array[$key], 'booking_studygroup_role' => $role, )) ->execute(); } //we found an existing record so just update it else { $update_text .= t('Running DB update for nid !nid, studygroup session id !id, for study group with ID !sid, for role !role;', array ('!nid' => $nid, '!id' => $key, '!sid' => $studygroups_update_array[$key], '!role' => $role)); db_update('booking_studygroup_mapping') ->fields(array ( 'booking_session_id' => $studygroups_update_array[$key], 'booking_studygroup_role' => $role, )) ->condition('booking_node_id', $nid) ->condition('booking_studygroup_id', $key) ->execute(); } } } return $update_text; }