0) // not empty (redundant w/ERR)
&& (($fp = fopen($_FILES['csvfile']['tmp_name'], "r")) !== false) // open ok
) {
// retrieve existing reviewer IDs, usernames, email addresses
$reviewerIdAR = array();
$usernameAR = array();
$emailAR = array();
$r = ocsql_query("SELECT `reviewerid`, `username`, `email` FROM `" . OCC_TABLE_REVIEWER . "`");
while ($l = ocsql_fetch_assoc($r)) {
$reviewerIdAR[] = $l['reviewerid'];
$usernameAR[] = $l['username'];
$emailAR[] = $l['email'];
}
// set list of field names to ID mapping
$fieldIdAR = array(
'id' => 'reviewerid',
'onprogramcommittee' => 'onprogramcommittee',
'password' => 'password'
);
$fieldNameAR = array(
'id' => 'reviewerid',
'onprogramcommittee' => 'onprogramcommittee',
'password' => 'password'
);
foreach ($OC_reviewerFieldAR as $fid => $far) {
$lowshort = strtolower($far['short']);
$fieldIdAR[$fid] = $lowshort;
$fieldNameAR[$lowshort] = $fid;
}
// retieve and check header row
$fieldMapAR = array();
$errAR = array();
$row = fgetcsv($fp, 0, $_POST['delimiter'], $_POST['enclosure'], $_POST['escape']);
foreach ($row as $rowid => $rowval) {
$col = strtolower($rowval);
if (isset($fieldIdAR[$col])) {
$fieldMapAR[$rowid] = $col;
} elseif (isset($fieldNameAR[$col])) {
$fieldMapAR[$rowid] = $fieldNameAR[$col];
} elseif (!isset($_POST['skipunknown']) || ($_POST['skipunknown'] != 1)) {
$errAR[] = 'Unknown column ' . safeHTMLstr($rowval);
}
}
// get short topics
$shortTopicAR = array();
$shorttopr = ocsql_query("SELECT `topicid`, `short` FROM `" . OCC_TABLE_TOPIC . "`") or err('unable to retrieve short topics');
while ($shorttopl = ocsql_fetch_assoc($shorttopr)) {
if (empty($shorttopl['short'])) { continue; }
$shortTopicAR[$shorttopl['topicid']] = $shorttopl['short'];
}
// check for missing required field columns
if (!in_array('name_last', $fieldMapAR) || !in_array('email', $fieldMapAR)) {
$errAR[] = 'Email and Last Name field columns not found';
}
if (count($errAR) > 0) {
print '
- ' . implode('
- ', $errAR) . '
';
} else {
// retrieve and check data
$importAR = array();
$rownum = 2; // skip header -- value for human consumption only
$reverseFieldMapAR = array_flip($fieldMapAR);
$reverseTopicAR = array_flip($topicAR);
$reverseShortTopicAR = array_flip($shortTopicAR);
while (($row = fgetcsv($fp, 0, $_POST['delimiter'], $_POST['enclosure'], $_POST['escape'])) !== false) {
if (count($row) < 2) { continue; }
if (!isset($row[$reverseFieldMapAR['name_last']]) || empty(trim($row[$reverseFieldMapAR['name_last']]))
|| !isset($row[$reverseFieldMapAR['email']]) || empty(trim($row[$reverseFieldMapAR['email']]))
) {
$errAR[] = 'Row ' . $rownum++ . ' missing Last Name or Email';
continue;
}
$recordAR = array();
foreach ($fieldMapAR as $colid => $fid) {
if (empty(trim($row[$colid]))) {
continue;
}
// check/convert encoding
if (isset($_POST['encoding']) && ($_POST['encoding'] != 'UTF-8')) {
$row[$colid] = mb_convert_encoding($row[$colid], 'UTF-8', $_POST['encoding']);
}
if (
(function_exists('mb_detect_encoding') && (mb_detect_encoding($row[$colid], 'UTF-8', true) != 'UTF-8'))
||
!preg_match("//u", $row[$colid])
) {
$errAR[] = 'Row ' . $rownum . ' Invalid UTF-8 encoding for field id ' . $fid;
}
if ($fid == 'password') {
if (preg_match("/^[a-f0-9]{50}$/", $row[$colid]) || preg_match("/^\$\w\w\$\w\w\$/", $row[$colid])) { // OC encrypted password
$recordAR['password'] = $row[$colid];
} elseif (!preg_match("/^$/", $row[$colid])) {
$recordAR['password'] = oc_password_hash($row[$colid]);
}
} elseif ($fid == 'topics') {
if (($topics = preg_split("/\n/", $row[$colid])) && (count($topics) > 0)) {
$recordAR['topics'] = array();
foreach ($topics as $topic) {
if (empty(trim($topic))) { continue; }
if (isset($reverseShortTopicAR[$topic])) { // short topic name
$recordAR['topics'][] = $reverseShortTopicAR[$topic];
} elseif (preg_match("/^\d+$/", $topic) && isset($topicAR[$topic])) { // topic ID
$recordAR['topics'][] = $topic;
} elseif (isset($reverseTopicAR[$topic])) { // full topic name
$recordAR['topics'][] = $reverseTopicAR[$topic];
} else {
$errAR[] = 'Row ' . $rownum . ' Topic invalid: ' . $topic;
}
}
} else {
$errAR[] = 'Row ' . $rownum . ' Topics invalid';
}
} elseif ($fid == 'id') {
if (preg_match("/^\d+$/", $row[$colid]) && !in_array($row[$colid], $reviewerIdAR)) {
$recordAR['reviewerid'] = $row[$colid];
$reviewerIdAR[] = $row[$colid];
} else {
$errAR[] = 'Row ' . $rownum . ' ID already exists or invalid';
}
} elseif ($fid == 'email') {
if (validEmail($row[$colid]) && !in_array($row[$colid], $emailAR)) {
$recordAR['email'] = $row[$colid];
$emailAR[] = $row[$colid];
} else {
$errAR[] = 'Row ' . $rownum . ' Email already exists or invalid';
}
} elseif ($fid == 'username') {
if (preg_match("/^[\p{L}\p{Nd}_\.\-\@]{5,50}$/u", $row[$colid]) && !in_array($row[$colid], $usernameAR)) {
$recordAR['username'] = $row[$colid];
$usernameAR[] = $row[$colid];
} else {
$errAR[] = 'Row ' . $rownum . ' Username already exists or invalid';
}
} elseif ($fid == 'onprogramcommittee') {
if (preg_match("/^[TF]$/i", $row[$colid])) {
$recordAR['onprogramcommittee'] = strtoupper($row[$colid]);
} else {
$errAR[] = 'Row ' . $rownum . ' OnProgramCommittee invalid';
}
} else {
if (preg_match("/^(?:checkbox|picklist)$/", $OC_reviewerFieldAR[$fid]['type'])) { // multi-select field
if (($values = preg_split("/\n/", $row[$colid])) && (count($values) > 0)) {
$recordAR[$fid] = array();
$reverseValuesAR = array_flip($OC_reviewerFieldAR[$fid]['values']);
foreach ($values as $value) {
if (empty(trim($value))) { continue; }
if (!isset($OC_reviewerFieldAR[$fid]['usekey']) || $OC_reviewerFieldAR[$fid]['usekey']) {
if (isset($OC_reviewerFieldAR[$fid]['values'][$value])) {
$recordAR[$fid][] = $value;
} elseif (isset($reverseValuesAR[$value])) {
$recordAR[$fid][] = $reverseValuesAR[$value];
}
} elseif (in_array($value, $OC_reviewerFieldAR[$fid]['values'])) {
$recordAR[$fid][] = $value;
} elseif ($fid == 'consent') { // override in case translated value saved
$recordAR[$fid][] = $value;
} else {
$errAR[] = 'Row ' . $rownum . ' ' . $OC_reviewerFieldAR[$fid]['short'] . ' invalid value: ' . $value;
}
}
} else {
$errAR[] = 'Row ' . $rownum . ' ' . $OC_reviewerFieldAR[$fid]['short'] . ' invalid';
}
} else { // not multi-select field (e.g., text, textarea, dropdown, radio)
if (isset($OC_reviewerFieldAR[$fid]['values']) && !empty($OC_reviewerFieldAR[$fid]['values'])) {
if (!isset($OC_reviewerFieldAR[$fid]['usekey']) || $OC_reviewerFieldAR[$fid]['usekey']) {
$reverseValuesAR = array_flip($OC_reviewerFieldAR[$fid]['values']);
if (isset($OC_reviewerFieldAR[$fid]['values'][$row[$colid]])) {
$recordAR[$fid] = $row[$colid];
} elseif (isset($reverseValuesAR[$row[$colid]])) {
$recordAR[$fid] = $reverseValuesAR[$row[$colid]];
} else {
$errAR[] = 'Row ' . $rownum . ' ' . $OC_reviewerFieldAR[$fid]['short'] . ' invalid value: ' . $row[$colid];
}
} elseif (in_array($row[$colid], $OC_reviewerFieldAR[$fid]['values'])) {
$recordAR[$fid] = $row[$colid];
} else {
$errAR[] = 'Row ' . $rownum . ' ' . $OC_reviewerFieldAR[$fid]['short'] . ' invalid value: ' . $row[$colid];
}
} else {
$recordAR[$fid] = $row[$colid];
}
}
}
}
// fill in missing fields
if (!isset($recordAR['password'])) {
$recordAR['password'] = oc_password_hash(oc_password_generate()); // filler password
}
if (!isset($recordAR['username']) && isset($recordAR['email'])) { // if not present, default username to email
if (!in_array($recordAR['email'], $usernameAR)) {
$recordAR['username'] = $recordAR['email'];
$usernameAR[] = $recordAR['username'];
} else {
$errAR[] = 'Row ' . $rownum . ' cannot use email for username';
}
}
if (!isset($recordAR['onprogramcommittee'])) { // default to not being on program committee
$recordAR['onprogramcommittee'] = 'F';
}
if (count($recordAR) > 0) {
$importAR[] = $recordAR;
}
$rownum++;
}
if (count($errAR) == 0) {
if (count($importAR) > 0) {
// import'em Danno
foreach($importAR as $recordID => $record) {
$reviewerid = 0;
$q = "INSERT INTO `" . OCC_TABLE_REVIEWER . "` SET ";
foreach ($record as $fid => $fval) {
if ($fid == 'topics') {
continue;
} elseif ($fid == 'reviewerid') {
$reviewerid = $fval;
}
$q .= "`" . $fid . "`='" . safeSQLstr((is_array($fval) ? implode(',', $fval) : $fval)) . "', ";
}
$q .= "`lastupdate`='" . safeSQLstr(date('Y-m-d')) . "'";
$r = ocsql_query($q) or warn('Import DB failure: (' . $recordID . ') ' . safeHTMLstr(ocsql_error()));
if ($reviewerid === 0) {
$reviewerid = ocsql_insert_id();
}
if (
preg_match("/^[1-9][0-9]*$/", $reviewerid)
&& isset($record['topics'])
&& is_array($record['topics'])
&& (count($record['topics']) > 0)
) {
$tq = "";
foreach ($record['topics'] as $topic) {
if (preg_match("/^\d+$/", $topic)) {
$tq .= "(" . $reviewerid . "," . $topic . "),";
}
}
if (!empty($tq)) {
$tq = "INSERT INTO `" . OCC_TABLE_REVIEWERTOPIC . "` (`reviewerid`, `topicid`) VALUES " . rtrim($tq, ',');
ocsql_query($tq) or warn('Topic import DB failure: (' . $recordID . ') ' . safeHTMLstr(ocsql_error()));
}
}
}
print '' . safeHTMLstr(count($importAR)) . ' records imported
';
} else {
print 'No valid reviewer records found
';
}
} else {
print '- ' . implode('
- ', $errAR) . '
';
}
}
} else {
print 'File did not upload properly or size too large
';
}
// clear out file
if (isset($_FILES['csvfile']['tmp_name']) && is_file($_FILES['csvfile']['tmp_name'])) {
unlink($_FILES['csvfile']['tmp_name']);
}
print '
';
}
// Display form
print '
Select the CSV file, then click the Import Committee Members button. The file must be in standard CSV format and have a header row that matches the committee profile form field (short) names or IDs. For a CSV file template, see below.
Template:
Import rules:
- The CSV file is assumed to be plain text with one committee member record per row
- Row 1 is assumed to be the title row with a unique field (short) name or ID per column, UTF-8 encoded
- The committee member\'s Last Name and Email Address must be included
- If no Username value is present, the Email Address will be used
- The Username and Email Address must be unique
- If no ID value is present, one will be automatically assigned
- If no Password value is present, the committee member will need to use the "forgot password" feature to have a new one issued
- The OnProgramCommittee value must be T for true or F for false; if neither of these, F is assumed
- For multi-value fields (e.g., Topics, checkboxes, picklist), separate values with a newline (\n)
';
printFooter();
?>