'status',
'pri' => 'priority',
'id' => 'ticket',
'type' => 'classification',
);
$supported_fields = array(
'classification',
'ticket',
'milestone',
'-milestone',
'+milestone',
'summary',
'status',
'priority',
'owner',
'type',
'component',
'-component',
'+component',
'description'
);
foreach ($supported_fields as $i => $f) {
unset($supported_fields[$i]);
$supported_fields[$f] = $f;
}
$C = MTrackTicket_CustomFields::getInstance();
foreach ($C->fields as $f) {
$name = substr($f->name, 2);
$supported_fields[$f->name] = $f->name;
if (!isset($field_aliases[$name])) {
$field_aliases[$name] = $f->name;
}
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_FILES['csvfile']) && $_FILES['csvfile']['error'] == 0
&& is_uploaded_file($_FILES['csvfile']['tmp_name'])) {
ini_set('auto_detect_line_endings', true);
$fp = fopen($_FILES['csvfile']['tmp_name'], 'r');
$header = fgetcsv($fp);
$err = array();
$output = array();
foreach ($header as $i => $name) {
$name = strtolower($name);
if (isset($field_aliases[$name])) {
$name = $field_aliases[$name];
}
if (!isset($supported_fields[$name])) {
$err[] = "Unsupported field: $name";
}
$header[$i] = $name;
}
$db = MTrackDB::get();
$db->beginTransaction();
MTrackChangeset::$use_txn = false;
$todo = array();
do {
$line = fgetcsv($fp);
if ($line === false) break;
$item = array();
foreach ($header as $i => $name) {
$item[$name] = $line[$i];
}
if (isset($item['ticket'])) {
$id = $item['ticket'];
if ($id[0] == '#') {
$id = substr($id, 1);
}
try {
$tkt = MTrackIssue::loadByNSIdent($id);
if ($tkt == null) {
$err[] = "No such ticket $id";
continue;
}
} catch (Exception $e) {
$err[] = $e->getMessage();
continue;
}
$output[] = "Updating ticket $tkt->nsident
\n";
} else {
$tkt = new MTrackIssue;
$tkt->priority = 'normal';
list($tkt->nsident) = MTrackDB::q(
'select max(cast(nsident as integer)) + 1 from tickets')
->fetchAll(PDO::FETCH_COLUMN, 0);
if ($tkt->nsident === null) {
$tkt->nsident = 1;
}
$output[] = "Creating ticket $tkt->nsident
\n";
}
$CS = MTrackChangeset::begin("ticket:X", $_POST['comment']);
if (strlen(trim($_POST['comment']))) {
$tkt->addComment($_POST['comment']);
}
foreach ($item as $name => $value) {
if ($name == 'ticket') {
continue;
}
$output[] = "$name => $value
\n";
try {
switch ($name) {
case 'summary':
case 'description':
case 'classification':
case 'priority':
case 'severity':
case 'changelog':
case 'owner':
case 'cc':
$tkt->$name = strlen($value) ? $value : null;
break;
case 'milestone':
if (strlen($value)) {
foreach ($tkt->getMilestones() as $mid) {
$tkt->dissocMilestone($mid);
}
$tkt->assocMilestone($value);
}
break;
case '+milestone':
if (strlen($value)) {
$tkt->assocMilestone($value);
}
break;
case '-milestone':
if (strlen($value)) {
$tkt->dissocMilestone($value);
}
break;
case 'component':
if (strlen($value)) {
foreach ($tkt->getComponents() as $mid) {
$tkt->dissocComponent($mid);
}
$tkt->assocComponent($value);
}
break;
case '+component':
if (strlen($value)) {
$tkt->assocComponent($value);
}
break;
case '-component':
if (strlen($value)) {
$tkt->dissocComponent($value);
}
break;
default:
if (!strncmp($name, 'x_', 2)) {
$tkt->{$name} = $value;
}
break;
}
} catch (Exception $e) {
$err[] = $e->getMessage();
}
}
$tkt->save($CS);
$CS->setObject("ticket:" . $tkt->tid);
} while (true);
$_SESSION['admin.import.result'] = array($err, $output);
if (count($err)) {
$db->rollback();
} else {
$db->commit();
}
}
header("Location: {$ABSWEB}admin/importcsv.php");
exit;
}
if (isset($_SESSION['admin.import.result'])) {
list($err, $info) = $_SESSION['admin.import.result'];
unset($_SESSION['admin.import.result']);
mtrack_head(count($err) ? 'Import Failed' : 'Import Complete');
foreach ($info as $line) {
echo $line;
}
if (count($err)) {
echo "The following errors were encountered:
\n";
foreach ($err as $msg) {
echo htmlentities($msg) . "
\n";
}
echo "
No changes were committed
\n";
} else {
echo "
Done!\n";
}
mtrack_foot();
exit;
}
mtrack_head('Import');
?>
Import/Update via CSV
You may use this facility to change ticket properties en-masse by uploading a CSV file.
The input file must be a CSV file with the field names on the first line.
The following fields are supported:
Enter a comment in the box below; it will be added as a comment to all affected tickets