<?php
/*
 * display a CSV file in a webpage.
 *  - add checkboxes to choose columns to be displayed.
 *  - add input boxes to allow for search strings per field.
 *  - add option to download the result of filtering as a new CSV.
 *
 * NB. 1st line of CSV is expected to be column headers (Excel style?)
 *
 * [ my first PHP script:  sorry for any sloppiness or dumb mistakes ]
 *
 * $Id: display.php,v 1.13 2014/11/21 17:28:13 pkern Exp $
 */


# expects my_paths["CSV"]
# expects my_paths["INCLUDE"]


/* ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== */

$onlyshow = False; $onlyRows = False;
$savebtn = "Save this view as a CSV";

$headers = $_POST["column"];
if (!empty($headers)) {	$onlyshow = True; }

$matches = $_POST["search"];
if (!empty($matches)) { $onlyRows = True; }

$do_filter = $_POST["do_filter"];
$show_all = $_POST["show_all"];

if (!empty($show_all)) {
	if ($onlyshow or $onlyRows) {
		$savebtn = "Save filtered view as a CSV";
	}
	$onlyshow = False; $onlyRows = False;
}

$download = $_POST["download"];
if (!empty($download)) {
	$savecsv = True;
	$csvlines = 0;
}
else {
$top = $my_paths["INCLUDE"];
?>
<html>
<head>
<script type="text/javascript" src="<?php echo $top; ?>/jquery-latest.js"></script>
<script type="text/javascript" src="<?php echo $top; ?>/jquery.tablesorter.js"></script>
<script type="text/javascript" id="js">$(document).ready(function() { 
        $("table").tablesorter(); 
}); </script>
</head>
<body>
<?php
}

# if ($_SERVER) { echo '<br> SERVER <pre>' . htmlspecialchars(print_r($_SERVER, true)) . '</pre>'; }
# if ($_GET) { echo '<br> GET <pre>' . htmlspecialchars(print_r($_GET, true)) . '</pre>'; }
# if ($_POST) { echo '<br> POST <pre>' . htmlspecialchars(print_r($_POST, true)) . '</pre>'; }
# if ($_FILES) { echo '<br> FILES <pre>' . htmlspecialchars(print_r($_FILES, true)) . '</pre>'; }
# if ($_REQUEST) { echo '<br> REQUEST <pre>' . htmlspecialchars(print_r($_REQUEST, true)) . '</pre>'; }
# if ($_SESSION) { echo '<br> SESSION <pre>' . htmlspecialchars(print_r($_SESSION, true)) . '</pre>'; }
# if ($_ENV) { echo '<br> ENV <pre>' . htmlspecialchars(print_r($_ENV, true)) . '</pre>'; }
# if ($_COOKIES) { echo '<br> COOKIES <pre>' . htmlspecialchars(print_r($_COOKIES, true)) . '</pre>'; }

$ruser = $_SERVER["REMOTE_USER"];
#if (!empty($ruser)) { echo "<br>Hello " . $ruser . ". <p>"; }

/* ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== =====
 *
 * http://stackoverflow.com/questions/518795/dynamically-display-a-csv-file-as-an-html-table-on-a-web-page
 *
 * $Id: display.php,v 1.13 2014/11/21 17:28:13 pkern Exp $
 */

$form = htmlspecialchars($_SERVER["PHP_SELF"]);
$form = '<form id="inventory" name="inventory" method="post" action="' . $form . '"' . ">\n";

$mod = filemtime($my_paths["CSV"]);
date_default_timezone_set("EST5EDT");

$stamp = strftime("%Y-%m-%d (%a) %H:%M  %Z", $mod);

$form .= "\n<ul><p>\n" ;
$form .= "<li>Click checkboxes to choose the fields to be displayed.\n";
$form .= "<li>Enter search strings to find matches within fields.</li>\n";
$form .= "Search strings are treated as PCRE regular expressions:<br>\n";
$form .= "<ul><li>enter '^$' to match empty fields.\n";
$form .= "<li>enter '.' to match non-empty fields.</ul>\n";
$form .= "<p>Note: fields being displayed need not include fields being matched.<p>\n";
$form .= "</ul><p>\n";

$f = fopen($my_paths["CSV"], "r");

$before = array ('/\n *-/', '/\n/', '/#/');
$after = array (' <li>-', '<br>', '<br>+ ');

$linenum = 0;
$showrow = 0;
if (($line = fgetcsv($f)) !== false) {
	$cn = 0;
	$linenum++;
	$h_row = "<thead>\n<tr>\n";
	$form .= "<table>\n";
        foreach ($line as $cell) {

		$px = $cn % 3;
		if ($cn == 0) { $form .= "<tr>\n"; }
		elseif ($px == 0) { $form .= "</tr>\n<tr>\n"; }
		$form .= "<td>\n";
		$form .= '<input type="text" name="search[' . $cell . ']" value="' . $matches[$cell] . '"> &nbsp; ' . "\n";
		$form .= $cell . "\n";
		$form .= '<input type="checkbox" name="column[' . $cell . ']" value="checked" ' . $headers[$cell] . '> ' . " \n";
		$form .= "</td>\n";
		
		$cn ++;

		if ($onlyRows) {
			$pattern = $matches[$cell];
			$plen = strlen($pattern);
			$showrow += $plen;

			$findrow['len'][$cn] = $plen;
			$findrow['val'][$cn] = $pattern;
		}
		if ($onlyshow) {
			if ( $headers[$cell] != "checked" ) {
				$skipcol[$cn] = True;
				continue;
			}
			$skipcol[$cn] = False;
		}

		$pltext = htmlspecialchars($cell);
		$httext = preg_replace($before, $after, $pltext);
		$seg = "<th>" . $httext . "&nbsp&plusmn</th>\n";
		$h_row .= $seg;

		if ($savecsv) { $xcsv[$csvlines][$cn] = $cell; }
	}
        $h_row .= "</tr>\n</thead>\n";

	$form .= "</table><p>\n";
	$form .= '<input type="submit" name="do_filter" value="Apply filtering">&nbsp;';
	$form .= '<input type="submit" name="show_all" value="Show everything">';
	$form .= " &nbsp; [ source CSV file was written: &nbsp; " . $stamp . " ] &nbsp";
	$form .= '<p><input type="submit" name="download" value="' . $savebtn . '">';
	$form .= "\n</form><p>\n";

	# if no patterns to match then show all rows.
	if ($onlyRows and $showrow == 0) { $onlyRows = False; }
}
if ($savecsv) { $csvlines++; }
elseif ($linenum > 0) {
	echo $form;
	echo '<table border="1" class="tablesorter">' . "\n";
	echo $h_row;
	echo "<tbody>\n";
}
while (($line = fgetcsv($f)) !== false) {
	$cn = 0;
	$linenum++;
	$showrow = 0;
	$h_row = "<tr>\n";
        foreach ($line as $cell) {
		$cn ++;
		if ($onlyRows and $findrow['len'][$cn] > 0 ) {
			$re = "/" . $findrow['val'][$cn] . "/";
			if ( preg_match($re, $cell) == 1 ) { $showrow++ ; }
		}
		if ($onlyshow and $skipcol[$cn]) { continue; }

		$pltext = htmlspecialchars($cell);
		$httext = preg_replace($before, $after, $pltext);
		$seg = "<td><pre>" . $httext . "</pre></td>\n";
		$h_row .= $seg;

		if ($savecsv) { $xcsv[$csvlines][$cn] = $cell; }
        }
        $h_row .= "</tr>\n";
	if ($onlyRows and $showrow == 0) { continue; }
	if ($savecsv) { $csvlines++; }
	else { echo $h_row; }
}
fclose($f);
if ($savecsv) {
	ob_start();

	date_default_timezone_set("EST5EDT");
	$savefn = strftime("inventory-%Y%m%d-%H%M.csv");
	header('Content-Description: File Transfer');
	header('Content-Type: application/octet-stream');
	header('Content-Disposition: attachment; filename=' . $savefn);
	header('Content-Transfer-Encoding: binary');

	$fpout = fopen("php://output", "w");
	for ($i = 0 ; $i < $csvlines ; $i++ ) {
		$cs = "" ; $cline = "";
		# fputcsv() will not enclose everything (sigh).
		foreach ($xcsv[$i] as $xcell) {
			## XXX - what if xcell contains '"' ... ?
			$cline .= $cs . '"' . $xcell .'"' ;
			$cs = ",";
		}
		fwrite($fpout, $cline . "\n");
	}
	fclose($fpout);

	ob_end_flush();
}
elseif ($linenum > 1) {
	echo "</tbody>\n</table>\n</body>\n</html>\n";
}
?>
