| Server IP : 173.209.174.21 / Your IP : 216.73.216.89 Web Server : Apache/2.4.58 (Ubuntu) System : Linux wcfs-server 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 User : nodor ( 1000) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/wcfs/tabs/categorize/ |
Upload File : |
<?php
session_start();
/* Paths */
$rules_file = __DIR__ . "/category_rules.json";
$uploads = __DIR__ . "/uploads/";
$output = __DIR__ . "/output/";
/* Ensure folders exist */
if (!is_dir($uploads)) mkdir($uploads, 0775, true);
if (!is_dir($output)) mkdir($output, 0775, true);
/* Load rules */
$rules = json_decode(file_get_contents($rules_file), true);
/* Categorization helper */
function categorize_item($item, $rules) {
$lower = strtolower($item);
foreach ($rules as $cat => $keywords) {
foreach ($keywords as $kw) {
if (strlen($kw) > 0 && strpos($lower, strtolower($kw)) !== false) {
return $cat;
}
}
}
return "Misc";
}
/* =======================
FILE UPLOAD HANDLING
======================= */
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csvfile'])) {
$target = $uploads . basename($_FILES['csvfile']['name']);
if (move_uploaded_file($_FILES['csvfile']['tmp_name'], $target)) {
$rows = array_map('str_getcsv', file($target));
$header = array_shift($rows);
$_SESSION['rows'] = $rows;
$_SESSION['header'] = $header;
$_SESSION['file'] = $target;
} else {
echo "<div style='color:red'>Error uploading file.</div>";
}
}
$rows = $_SESSION['rows'] ?? null;
$header = $_SESSION['header'] ?? null;
/* =======================
SAVE RULES ONLY
======================= */
if (isset($_POST['save_rules'])) {
$rules = json_decode($_POST['rules_json'], true);
file_put_contents($rules_file, json_encode($rules, JSON_PRETTY_PRINT));
$rules_saved = true; // marker to show success message
}
/* =======================
EXPORT CSV
======================= */
if (isset($_POST['export_csv'])) {
$rules = json_decode($_POST['rules_json'], true);
file_put_contents($rules_file, json_encode($rules, JSON_PRETTY_PRINT));
$rows = $_SESSION['rows'];
$header = $_SESSION['header'];
$header[] = "Category";
$filename = "categorized_" . date("Y-m-d_Hi") . ".csv";
$filepath = $output . $filename;
$fp = fopen($filepath, "w");
fputcsv($fp, $header);
foreach ($rows as $r) {
$cat = categorize_item($r[3], $rules);
$r[] = $cat;
fputcsv($fp, $r);
}
fclose($fp);
$export_done = $filename; // used to display link
}
?>
<!DOCTYPE html>
<html>
<head>
<title>CSV Categorizer</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f5f5f5;
padding: 20px;
}
.container {
max-width: 900px;
background: white;
padding: 20px;
margin: auto;
border-radius: 10px;
box-shadow: 0 0 10px #ccc;
}
/* Table styling */
table { width: 100%; border-collapse: collapse; margin-top: 15px; }
th, td { padding: 8px; border: 1px solid #ccc; }
/* CATEGORY COLORS */
.cat-NoTaxGrocery { background: #e8ffe8; }
.cat-GroceryTaxable { background: #fff3d6; }
.cat-Hardware { background: #e7f0ff; }
.cat-Feed { background: #fffbe0; }
.cat-Oil { background: #f3e8ff; }
.cat-Unleaded { background: #ffe6ef; }
.cat-Diesel { background: #e6fffb; }
.cat-OffRoadDiesel { background: #f2f2f2; }
.cat-Misc { background: #ffffff; }
/* Success message */
.success {
background: #d9ffd9;
border: 1px solid #77c977;
padding: 10px;
margin-bottom: 10px;
border-radius: 6px;
}
</style>
</head>
<body>
<div class="container">
<h2>Upload CSV</h2>
<form method="post" enctype="multipart/form-data">
<input type="file" name="csvfile" required>
<button type="submit">Upload & Process</button>
</form>
<?php if (!empty($export_done)): ?>
<div class="success">
Export complete!
➜ <a href="output/<?= $export_done ?>" download>Download <?= $export_done ?></a>
</div>
<?php endif; ?>
<?php if (!empty($rules_saved)): ?>
<div class="success">Rules updated successfully. You may continue editing or export.</div>
<?php endif; ?>
<?php if (!empty($rows)): ?>
<hr>
<h2>Preview & Edit Categories</h2>
Search: <input type="text" id="searchBox" onkeyup="filterTable()"><br><br>
<form method="post">
<input type="hidden" name="rules_json" id="rules_json">
<table id="previewTable">
<tr>
<th>Item</th>
<th>Category</th>
</tr>
<?php foreach ($rows as $index => $r):
$item = $r[3];
$cat = categorize_item($item, $rules);
$safeClass = "cat-" . preg_replace('/[^A-Za-z0-9]/', '', str_replace(" ", "", $cat));
?>
<tr class="<?= $safeClass ?>">
<td><?= htmlspecialchars($item) ?></td>
<td>
<select class="catSel" onchange="updateRowColor(this)">
<?php foreach ($rules as $cname => $junk): ?>
<option <?= $cat == $cname ? "selected" : "" ?>><?= $cname ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<?php endforeach; ?>
</table>
<br>
<button type="button" onclick="saveRulesOnly()">Save Rules Only</button>
<button type="button" onclick="exportCSV()">Export Categorized CSV</button>
</form>
</div>
<script>
function filterTable() {
let f = document.getElementById("searchBox").value.toLowerCase();
let rows = document.querySelectorAll("#previewTable tr");
rows.forEach((r, i) => {
if (i === 0) return;
let txt = r.cells[0].innerText.toLowerCase();
r.style.display = txt.includes(f) ? "" : "none";
});
}
function updateRowColor(sel) {
let row = sel.closest("tr");
row.className = "";
let cat = sel.value.replace(/[^A-Za-z0-9]/g, "");
row.classList.add("cat-" + cat);
}
function packageRules() {
let cats = document.querySelectorAll(".catSel");
let rows = <?php echo json_encode($rows); ?>;
let rules = <?php echo json_encode($rules); ?>;
cats.forEach((sel, i) => {
let item = rows[i][3].toLowerCase();
let chosen = sel.value;
if (!rules[chosen]) rules[chosen] = [];
if (!rules[chosen].includes(item)) rules[chosen].push(item);
});
document.getElementById("rules_json").value = JSON.stringify(rules);
}
function saveRulesOnly() {
packageRules();
let f = document.querySelector("form");
let h = document.createElement("input");
h.type = "hidden"; h.name = "save_rules"; h.value = "1";
f.appendChild(h);
f.submit();
}
function exportCSV() {
packageRules();
let f = document.querySelector("form");
let h = document.createElement("input");
h.type = "hidden"; h.name = "export_csv"; h.value = "1";
f.appendChild(h);
f.submit();
}
</script>
<?php endif; ?>
</body>
</html>