So many changes... I wanted to do this piece by piece, but once I

got started, I couldn't stop:
Update Smarty
Update bootstrap
Switch to using cards
Set up themes
Improve sorting (add direction)
Use modals for viewing, editing, adding items.
Add Help page
Add bookmarklet
Add footer
This commit is contained in:
Michael Erdely 2024-10-18 22:07:51 -04:00
parent a3855e078c
commit 1044fa8ccb
692 changed files with 40696 additions and 35959 deletions

View file

@ -20,7 +20,7 @@ $opt = $smarty->opt();
session_start();
if (!isset($_SESSION["userid"])) {
header("Location: " . getFullPath("login.php"));
header("Location: " . getFullPath("login.php") . "?from=shop.php");
exit;
}
else {
@ -29,35 +29,67 @@ else {
$opt['show_helptext'] = $_SESSION['show_helptext'];
if (isset($_GET["shopfor"])) {
$shopfor = filter_var(trim($_GET["shopfor"]), FILTER_SANITIZE_NUMBER_INT);
if (filter_var($shopfor, FILTER_SANITIZE_NUMBER_INT) === false || $shopfor == "" || !is_numeric($shopfor) || $shopfor < 0) {
die("Invalid shopfor ({$_GET["shopfor"]})");
}
$shopfor = (int) $shopfor;
//} else {
// header("Location: " . getFullPath("index.php"));
}
if ($shopfor == $userid) {
echo "Nice try! (You can't shop for yourself.)";
exit;
}
$action = "";
if (!empty($_GET["action"])) {
$action = $_GET["action"];
$itemid = (int) $_GET["itemid"];
if (isset($_GET["itemid"])) {
$itemid = filter_var(trim($_GET["itemid"]), FILTER_SANITIZE_NUMBER_INT);
if (filter_var($itemid, FILTER_SANITIZE_NUMBER_INT) === false || $itemid == "" || !is_numeric($itemid) || $itemid < 0) {
die("Invalid itemid ({$_GET["itemid"]})");
}
$itemid = (int) $itemid;
}
$stmt = $smarty->dbh()->prepare("SELECT items.name, users.fullname FROM {$opt["table_prefix"]}items JOIN {$opt["table_prefix"]}users ON items.userid = users.userid WHERE items.itemid = ?");
$stmt->bindParam(1, $itemid, PDO::PARAM_INT);
$stmt->execute();
if ($row = $stmt->fetch()) {
$name = $row["name"];
$fullname = $row["fullname"];
}
if ($action == "reserve") {
adjustAllocQuantity($itemid,$userid,0,+1, $smarty->dbh(), $smarty->opt());
header("Location: " . getFullPath("shop.php?shopfor=$shopfor&message='$name'+reserved+for+$fullname"));
}
else if ($action == "purchase") {
// decrement reserved.
adjustAllocQuantity($itemid,$userid,0,-1, $smarty->dbh(), $smarty->opt());
// increment purchased.
adjustAllocQuantity($itemid,$userid,1,+1, $smarty->dbh(), $smarty->opt());
header("Location: " . getFullPath("shop.php?shopfor=$shopfor&message='$name'+purchased+for+$fullname"));
}
else if ($action == "return") {
// increment reserved.
adjustAllocQuantity($itemid,$userid,0,+1, $smarty->dbh(), $smarty->opt());
// decrement purchased.
adjustAllocQuantity($itemid,$userid,1,-1, $smarty->dbh(), $smarty->opt());
header("Location: " . getFullPath("shop.php?shopfor=$shopfor&message='$name'+returned+for+$fullname"));
}
else if ($action == "release") {
adjustAllocQuantity($itemid,$userid,0,-1, $smarty->dbh(), $smarty->opt());
header("Location: " . getFullPath("shop.php?shopfor=$shopfor&message='$name'+released+for+$fullname"));
}
else if ($action == "copy") {
/*
/*
can't do this because MySQL 3.x doesn't seem to support it (at least the version i was using).
$query = "INSERT INTO items(userid,description,price,source,url,category) SELECT $userid, description, price, source, url, category FROM items WHERE itemid = " . $_GET["itemid"];
*/
/* TODO: copy the image too? */
$stmt = $smarty->dbh()->prepare("SELECT userid, name, description, price, source, url, category, comment FROM {$opt["table_prefix"]}items WHERE itemid = ?");
$stmt = $smarty->dbh()->prepare("SELECT userid, name, description, price, source, url, category, comment, ranking, quantity, image_filename FROM {$opt["table_prefix"]}items WHERE itemid = ?");
$stmt->bindParam(1, $itemid, PDO::PARAM_INT);
$stmt->execute();
if ($row = $stmt->fetch()) {
@ -68,8 +100,30 @@ if (!empty($_GET["action"])) {
$comment = $row["comment"];
$price = (float) $row["price"];
$cat = (int) $row["category"];
$stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}items(userid,name,description,price,source,url,comment,category,ranking,quantity) VALUES(?, ?, ?, ?, ?, ?, ?, 1, 1)");
$quantity = (int) $row["quantity"];
$image_filename = $row["image_filename"];
// Copy the image
// what's the extension?
$parts = pathinfo($image_filename);
$file_ext = $parts['extension'];
// what is full path to store images? get it from the currently executing script.
$parts = pathinfo($_SERVER["SCRIPT_FILENAME"]);
$upload_dir = $parts['dirname'];
// generate a temporary file in the configured directory.
$temp_name = tempnam($upload_dir . "/" . $opt["image_subdir"],"");
// unlink it, we really want an extension on that.
unlink($temp_name);
// here's the name we really want to use. full path is included.
$new_image_filename = $temp_name . "." . $file_ext;
// copy the original file
copy($upload_dir . "/" . $opt["image_subdir"] . "/" . $image_filename, $new_image_filename);
// fix permissions on the new file
chmod($new_image_filename, 0644);
// the name we're going to record in the DB is the filename without the path.
$image_base_filename = basename($new_image_filename);
$stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}items(userid,name,description,price,source,url,comment,category,ranking,quantity,image_filename) VALUES(?, ?, ?, ?, ?, ?, ?, 1, 3, ?, ?)");
$stmt->bindParam(1, $userid, PDO::PARAM_INT);
$stmt->bindParam(2, $name, PDO::PARAM_STR);
$stmt->bindParam(3, $desc, PDO::PARAM_STR);
@ -77,9 +131,10 @@ if (!empty($_GET["action"])) {
$stmt->bindParam(5, $source, PDO::PARAM_STR);
$stmt->bindParam(6, $url, PDO::PARAM_STR);
$stmt->bindParam(7, $comment, PDO::PARAM_STR);
$stmt->bindParam(8, $cat, PDO::PARAM_INT);
$stmt->bindParam(8, $quantity, PDO::PARAM_INT);
$stmt->bindParam(9, $image_base_filename, PDO::PARAM_STR);
$stmt->execute();
stampUser($userid, $smarty->dbh(), $smarty->opt());
$message = "Added '" . $name . "' to your gift list.";
@ -87,11 +142,6 @@ if (!empty($_GET["action"])) {
}
}
$shopfor = (int) $_GET["shopfor"];
if ($shopfor == $userid) {
echo "Nice try! (You can't shop for yourself.)";
exit;
}
$stmt = $smarty->dbh()->prepare("SELECT * FROM {$opt["table_prefix"]}shoppers WHERE shopper = ? AND mayshopfor = ? AND pending = 0");
$stmt->bindParam(1, $userid, PDO::PARAM_INT);
$stmt->bindParam(2, $shopfor, PDO::PARAM_INT);
@ -101,35 +151,42 @@ if (!($stmt->fetch())) {
exit;
}
if (!empty($_GET["sortdir"])) {
$sortdir = strtoupper(trim($_GET["sortdir"])) == "DESC" ? "DESC" : "ASC";
} else {
$sortdir = "ASC";
}
if (!isset($_GET["sort"])) {
$sortby = "rankorder DESC, name";
$sortby = "rankorder, name";
$sort = "ranking";
}
else {
$sort = $_GET["sort"];
$sort = filter_var(trim($_GET["sort"], FILTER_SANITIZE_STRING));;
$sort = htmlspecialchars($sort, ENT_QUOTES, 'UTF-8');
switch ($sort) {
case "ranking":
$sortby = "rankorder DESC, name";
break;
case "name":
$sortby = "name";
$sortby = "name $sortdir";
$sort = "name";
break;
case "source":
$sortby = "source, rankorder DESC, name";
$sortby = "source $sortdir, rankorder, name";
$sort = "source";
break;
case "price":
$sortby = "price, rankorder DESC, name";
break;
case "url":
$sortby = "url, rankorder DESC, name";
$sortby = "price $sortdir, rankorder, name";
$sort = "price";
break;
case "status":
$sortby = "reservedid DESC, boughtid DESC, rankorder DESC, name";
$sortby = "reservedid $sortdir, boughtid DESC, rankorder, name";
$sort = "status";
break;
case "category":
$sortby = "c.category, rankorder DESC, name";
$sortby = "c.category $sortdir, rankorder, name";
$sort = "category";
break;
default:
$sortby = "rankorder DESC, name";
$sortby = "rankorder $sortdir, name";
$sort = "ranking";
}
}
@ -137,7 +194,7 @@ else {
for those items with a quantity of 1. if the item's quantity > 1 we'll query alloc when we
get to that record. the theory is that most items will have quantity = 1 so we'll make the least
number of trips. */
$stmt = $smarty->dbh()->prepare("SELECT i.itemid, name, description, price, source, c.category, url, image_filename, " .
$stmt = $smarty->dbh()->prepare("SELECT i.itemid, name, description, price, price as pricenum, source, i.category as catid, c.category, url, r.title as rank, i.ranking as rankid, image_filename, " .
"ub.fullname AS bfullname, ub.userid AS boughtid, " .
"ur.fullname AS rfullname, ur.userid AS reservedid, " .
"rendered, i.comment, i.quantity " .
@ -206,6 +263,7 @@ while ($row = $stmt->fetch()) {
$row['ibought'] = $ibought;
$row['ireserved'] = $ireserved;
}
$row['urlhost'] = preg_replace("/^(https?:\/\/)?(www\.)?([^\/]+)(\/.*)?$/", "$3", $row['url']);
$shoprows[] = $row;
}
@ -213,17 +271,26 @@ while ($row = $stmt->fetch()) {
except that I wouldn't get it if he had no items, so I *could* LEFT OUTER
JOIN, but then it would complicate the iteration logic, so let's just
hit the DB again. */
$stmt = $smarty->dbh()->prepare("SELECT fullname FROM {$opt["table_prefix"]}users WHERE userid = ?");
$stmt = $smarty->dbh()->prepare("SELECT fullname, email, comment FROM {$opt["table_prefix"]}users WHERE userid = ?");
$stmt->bindParam(1, $shopfor, PDO::PARAM_INT);
$stmt->execute();
if ($row = $stmt->fetch()) {
$ufullname = $row["fullname"];
$ucomment = $row["comment"];
$uemail = $row["email"];
}
$smarty->assign('sort', $sort);
$smarty->assign('sortdir', $sortdir);
$smarty->assign('ufullname', $ufullname);
$smarty->assign('uemail', $uemail);
$smarty->assign('ucomment', $ucomment);
$smarty->assign('shopfor', $shopfor);
$smarty->assign('shoprows', $shoprows);
$smarty->assign('userid', $userid);
if (isset($_GET["message"])) {
$message = $_GET["message"];
}
if (isset($message)) {
$smarty->assign('message', $message);
}