Skip to content

Instantly share code, notes, and snippets.

@cookieguru
Last active April 11, 2017 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cookieguru/d26f737b04d463abbc597d14d6e40fe4 to your computer and use it in GitHub Desktop.
Save cookieguru/d26f737b04d463abbc597d14d6e40fe4 to your computer and use it in GitHub Desktop.
Interactive command line utility to convert a QIF (Quicken export) file to CSV or display on screen
<?php
//First check the current directory for any QIF files
//If one is found, use that name by default
foreach(scandir('.') as $file) {
if(strtolower(substr($file, -4)) == '.qif') {
$filename = $file;
break;
}
}
/**
* Prompts for user input
* @param string $msg Hint text for the user
* @return string The user's input
*/
function prompt($msg) {
if(function_exists('readline')) {
return readline("$msg: ");
}
echo "$msg: ";
return stream_get_line(STDIN, 1024, PHP_EOL);
}
//Prompt the user for the file to read, specifying the default name if a file was found
$prompt_filename = prompt('Filename' . (isset($filename) ? " [$filename]" : null));
if(empty($prompt_filename)) {
if(!isset($filename)) {
echo "No file to open\n";
exit(-1);
}
} else {
$filename = $prompt_filename;
}
//Prompt user for the destination and a filename that won't clobber unless told to do so
$destination = prompt('Output [C]SV or [s]creen? [c]');
if(strtolower($destination) != 's') {
$destination = 'c';
$output_filename = substr($filename, 0, -3) . 'csv';
$prompt_outfile = prompt("Output filename [$output_filename]");
if(!empty($prompt_outfile)) {
$output_filename = $prompt_outfile;
}
while(file_exists($output_filename) || empty($output_filename)) {
$prompt_overwrite = prompt("$output_filename exists; overwrite [y/n]? [n]");
if(strtolower($prompt_overwrite) == 'y' && !empty($output_filename)) {
break;
} else {
$output_filename = prompt("Output filename");
}
}
}
try {
$lines = new SplFileObject($filename);
$lines->setFlags(SplFileObject::DROP_NEW_LINE);
} catch(\RuntimeException $e) {
echo "Cannot open $filename\n";
exit(-1);
}
//Read data in to a 3D array
$data = [];
$row = 0;
foreach($lines as $line) {
$code = substr($line, 0, 1);
if($code == '!') {
continue;
}
if($code == '^') {
$row++;
continue;
}
$value = substr($line, 1);
if($code == 'D') {
$value = str_replace("'", '/20', $value);
}
if($code == 'T') {
$value = str_replace(",", NULL, $value);
}
$data[$row][$code] = $value;
}
//Calculate maximum column widths and remove rows without data
$maxlength = array_fill_keys(['a', 'D', 'N', 'P', 'T'], 1);
$account = 'Unknown';
foreach($data as $row => $values) {
if(!isset($values['P'])) {
unset($data[$row]);
$account = $values['N'];
continue;
}
foreach(['D', 'N', 'P', 'T'] as $code) {
if(!isset($values[$code])) {
$data[$row][$code] = null;
}
$maxlength[$code] = max($maxlength[$code], strlen($data[$row][$code]) + 1);
}
$data[$row]['a'] = $account;
$maxlength['a'] = max($maxlength['a'], strlen($data[$row]['a']) + 1);
}
//Output data
if($destination == 'c') {
$bytes = 0;
$file = new SplFileObject($output_filename, 'w+');
foreach($data as $values) {
if(!isset($values['P'])) {
continue;
}
$bytes += $file->fputcsv([$values['a'], $values['D'], $values['N'], $values['P'], $values['T']]);
}
echo "Wrote $bytes bytes to $output_filename\n";
} else {
foreach($data as $values) {
echo str_pad($values['a'], $maxlength['a']);
echo str_pad($values['D'], $maxlength['D']);
echo str_pad($values['N'], $maxlength['N']);
echo str_pad($values['P'], $maxlength['P']);
echo str_pad($values['T'], $maxlength['T'], ' ', STR_PAD_LEFT);
echo "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment