301 lines
12 KiB
PHP
301 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* @file
|
|
* Provide functionality to upload csv for bulk update of payment data
|
|
*/
|
|
|
|
|
|
function booking_import_data_admin($form, &$form_state)
|
|
{
|
|
global $event;
|
|
$form = array();
|
|
|
|
$prefix = t("<p>Upload csv file containing data to import. Minimum fields present should be <strong>nid</strong> or <strong>booking_tempid</strong>, " .
|
|
" along with fields specified below. CSV Column names should match exactly (case sensitive).</p>");
|
|
$prefix .= "<p>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.</p>";
|
|
$prefix .= "<p>Also note that updating study group membership and roles requires nid to be present in the input file.</p>";
|
|
|
|
$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', "<pre>CSV import fields\n@info</pre>", 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', "<pre>Import data:\n@info</pre>", array('@info' => print_r( $csvdata, true)));
|
|
|
|
//process the input data
|
|
foreach ($csvdata as $record) {
|
|
$rows = 0;
|
|
//watchdog('booking', "<pre>Processing row data:\n@info</pre>", 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:<br />@info<br />Condition: @nid<br />Rows affected: @rows<br />Values: <br /><pre>@values</pre>",
|
|
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', "<pre>Processing row data:\n@info</pre>", 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', "<pre>Data Import concluded:\n" . implode("\n", $update_messages) . "</pre>");
|
|
|
|
/*
|
|
// 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;
|
|
} |