opt(); $public_view = 0; if (isset($_GET["list"])) { $list = filter_var(strtolower(trim($_GET["list"])), FILTER_SANITIZE_EMAIL);; $list = htmlspecialchars($list, ENT_QUOTES, 'UTF-8'); if (filter_var($list, FILTER_SANITIZE_EMAIL) === false || $list == "") { die("Invalid listid ({$_GET["list"]})"); } $stmt = $smarty->dbh()->prepare("SELECT userid FROM {$opt["table_prefix"]}users WHERE email = ?"); $stmt->bindParam(1, $list, PDO::PARAM_STR); $stmt->execute(); if ($row = $stmt->fetch()) { $shopfor = (int) $row["userid"]; $public_view = 1; } else { die("Invalid listid ({$_GET["list"]})"); } } if ($public_view == 0) { session_start(); if (!isset($_SESSION["userid"])) { header("Location: " . getFullPath("login.php") . "?from=shop.php"); exit; } else { $userid = $_SESSION["userid"]; } $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"]; 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"]; */ $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()) { $name = $row["name"]; $desc = $row["description"]; $source = $row["source"]; $url = $row["url"]; $comment = $row["comment"]; $price = (float) $row["price"]; $cat = (int) $row["category"]; $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); $stmt->bindParam(4, $price); $stmt->bindParam(5, $source, PDO::PARAM_STR); $stmt->bindParam(6, $url, PDO::PARAM_STR); $stmt->bindParam(7, $comment, PDO::PARAM_STR); $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."; } } } if (!$opt["auto_connect_family_members"]) { if ($public_view == 0) { $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); $stmt->execute(); if (!($stmt->fetch())) { echo "Nice try! (You can't shop for someone who hasn't approved it.)"; exit; } } } if (!empty($_GET["sortdir"])) { $sortdir = strtoupper(trim($_GET["sortdir"])) == "DESC" ? "DESC" : "ASC"; } else { $sortdir = "ASC"; } if (!isset($_GET["sort"])) { $sortby = "rankorder, name"; $sort = "ranking"; } else { $sort = filter_var(trim($_GET["sort"], FILTER_SANITIZE_STRING));; $sort = htmlspecialchars($sort, ENT_QUOTES, 'UTF-8'); switch ($sort) { case "name": $sortby = "name $sortdir"; $sort = "name"; break; case "source": $sortby = "source $sortdir, rankorder, name"; $sort = "source"; break; case "quantity": $sortby = "quantity $sortdir, rankorder, name"; $sort = "quantity"; break; case "price": $sortby = "price $sortdir, rankorder, name"; $sort = "price"; break; case "status": $sortby = "reservedid $sortdir, boughtid DESC, rankorder, name"; $sort = "status"; break; case "category": $sortby = "c.category $sortdir, rankorder, name"; $sort = "category"; break; default: $sortby = "rankorder $sortdir, name"; $sort = "ranking"; } } /* here's what we're going to do: we're going to pull back the shopping list along with any alloc record 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. */ $sql = "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, public, " . "ub.fullname AS bfullname, ub.userid AS boughtid, " . "ur.fullname AS rfullname, ur.userid AS reservedid, " . "rendered, i.comment, i.quantity, created " . "FROM {$opt["table_prefix"]}items i " . "LEFT OUTER JOIN {$opt["table_prefix"]}categories c ON c.categoryid = i.category " . "LEFT OUTER JOIN {$opt["table_prefix"]}ranks r ON r.ranking = i.ranking " . "LEFT OUTER JOIN {$opt["table_prefix"]}allocs a ON a.itemid = i.itemid AND i.quantity = 1 " . // only join allocs for single-quantity items. "LEFT OUTER JOIN {$opt["table_prefix"]}users ub ON ub.userid = a.userid AND a.bought = 1 " . "LEFT OUTER JOIN {$opt["table_prefix"]}users ur ON ur.userid = a.userid AND a.bought = 0 " . "WHERE i.userid = ? AND i.archive = false "; if ($public_view) { $sql .= "AND public = 1 "; } $sql .= "ORDER BY " . $sortby; error_log("sql = '$sql'"); $stmt = $smarty->dbh()->prepare($sql); $stmt->bindParam(1, $shopfor, PDO::PARAM_INT); $stmt->execute(); $shoprows = array(); while ($row = $stmt->fetch()) { $row['price'] = formatPrice($row['price'], $opt); if ($row['quantity'] > 1) { // check the allocs table to see what has been allocated. $avail = $row['quantity']; $substmt = $smarty->dbh()->prepare("SELECT a.quantity, a.bought, a.userid, " . "ub.fullname AS bfullname, ub.userid AS boughtid, " . "ur.fullname AS rfullname, ur.userid AS reservedid " . "FROM {$opt["table_prefix"]}allocs a " . "LEFT OUTER JOIN {$opt["table_prefix"]}users ub ON ub.userid = a.userid AND a.bought = 1 " . "LEFT OUTER JOIN {$opt["table_prefix"]}users ur ON ur.userid = a.userid AND a.bought = 0 " . "WHERE a.itemid = ? " . "ORDER BY a.bought, a.quantity"); $substmt->bindValue(1, $row['itemid'], PDO::PARAM_INT); $substmt->execute(); $ibought = 0; $ireserved = 0; $itemallocs = array(); while ($allocrow = $substmt->fetch()) { if ($allocrow['bfullname'] != '') { if ($allocrow['boughtid'] == $userid) { $ibought += $allocrow['quantity']; $itemallocs[] = ($allocrow['quantity'] . " bought by you."); } else { if (!$opt["anonymous_purchasing"] && !$public_view) { $itemallocs[] = ($allocrow['quantity'] . " bought by " . $allocrow['bfullname'] . "."); } else { $itemallocs[] = ($allocrow['quantity'] . " bought."); } } } else { if ($allocrow['reservedid'] == $userid) { $ireserved += $allocrow['quantity']; $itemallocs[] = ($allocrow['quantity'] . " reserved by you."); } else { if (!$opt["anonymous_purchasing"] && !$public_view) { $itemallocs[] = ($allocrow['quantity'] . " reserved by " . $allocrow['rfullname'] . "."); } else { $itemallocs[] = ($allocrow['quantity'] . " reserved."); } } } $avail -= $allocrow['quantity']; } $row['allocs'] = $itemallocs; $row['avail'] = $avail; $row['ibought'] = $ibought; $row['ireserved'] = $ireserved; } $row['urlhost'] = preg_replace("/^(https?:\/\/)?(www\.)?([^\/]+)(\/.*)?$/", "$3", $row['url']); $shoprows[] = $row; } /* okay, I *would* retrieve the shoppee's fullname from the items recordset, 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, 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); $smarty->assign('public_view', $public_view); if (isset($_GET["message"])) { $message = $_GET["message"]; } if (isset($message)) { $smarty->assign('message', $message); } $smarty->display('shop.tpl'); ?>