diff --git a/src/archive.php b/src/archive.php new file mode 100644 index 0000000..059bc38 --- /dev/null +++ b/src/archive.php @@ -0,0 +1,398 @@ +opt(); + +session_start(); +if (!isset($_SESSION["userid"])) { + header("Location: " . getFullPath("login.php")); + exit; +} +else { + $userid = $_SESSION["userid"]; +} + +if (!empty($_GET["message"])) { + $message = filter_var(trim($_GET["message"], FILTER_SANITIZE_STRING));; + $message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); +} + +/* if we've got `page' on the query string, set the session page indicator. */ +if (isset($_GET["offset"])) { + $offset = filter_var(trim($_GET["offset"]), FILTER_SANITIZE_NUMBER_INT); + if (filter_var($offset, FILTER_SANITIZE_NUMBER_INT) === false || $offset == "" || !is_numeric($offset) || $offset < 0) { + die("Invalid page offset ({$_GET["offset"]})"); + } + $_SESSION["offset"] = $offset; +} +else if (isset($_SESSION["offset"])) { + $offset = $_SESSION["offset"]; +} +else { + $offset = 0; +} + +if (!empty($_GET["action"])) { + $action = $_GET["action"]; + if ($action == "ack") { + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}messages SET isread = 1 WHERE messageid = ?"); + $stmt->bindValue(1, (int) $messageid, PDO::PARAM_INT); + $stmt->execute(); + } + else if ($action == "approve") { + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}shoppers SET pending = 0 WHERE shopper = ? AND mayshopfor = ?"); + $stmt->bindValue(1, (int) $shopper, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + sendMessage($userid,(int) $shopper,$_SESSION["fullname"] . " has approved your request to shop for him/her.", $smarty->dbh(), $smarty->opt()); + } + else if ($action == "decline") { + $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}shoppers WHERE shopper = ? AND mayshopfor = ?"); + $stmt->bindValue(1, (int) $shopper, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + sendMessage($userid,(int) $shopper,$_SESSION["fullname"] . " has declined your request to shop for him/her.", $smarty->dbh(), $smarty->opt()); + } + else if ($action == "request") { + $stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}shoppers(shopper,mayshopfor,pending) VALUES(?, ?, ?)"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindValue(2, (int) $shopfor, PDO::PARAM_INT); + $stmt->bindValue(3, $opt["shop_requires_approval"], PDO::PARAM_BOOL); + $stmt->execute(); + if ($opt["shop_requires_approval"]) { + sendMessage($userid,(int) $shopfor,$_SESSION["fullname"] . " has requested to shop for you. Please approve or decline this request.", $smarty->dbh(), $smarty->opt()); + } + } + else if ($action == "cancel") { + // this works for either cancelling a request or "unshopping" for a user. + $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}shoppers WHERE shopper = ? AND mayshopfor = ?"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindValue(2, (int) $shopfor, PDO::PARAM_INT); + $stmt->execute(); + } + else if ($action == "subscribe") { + // ensure the current user can shop for that user first. + $stmt = $smarty->dbh()->prepare("SELECT pending FROM {$opt["table_prefix"]}shoppers WHERE shopper = ? AND mayshopfor = ?"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindValue(2, (int) $shoppee, PDO::PARAM_INT); + $stmt->execute(); + if ($row = $stmt->fetch()) { + if ($row["pending"]) { + die("You aren't allowed to shop for that user yet."); + } + } + else { + die("You aren't allowed to shop for that user."); + } + + $stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}subscriptions(publisher, subscriber) VALUES(?, ?)"); + $stmt->bindValue(1, (int) $shoppee, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + } + else if ($action == "unsubscribe") { + $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}subscriptions WHERE publisher = ? AND subscriber = ?"); + $stmt->bindValue(1, (int) $shoppee, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + } +} + +$reset_sortdir = false; +if (!empty($_GET["mysort"])) { + $mysort = filter_var(trim($_GET["mysort"]), FILTER_SANITIZE_STRING); + $mysort = htmlspecialchars($mysort, ENT_QUOTES, 'UTF-8'); + if (isset($_SESSION["mysort"]) && $_SESSION["mysort"] != $mysort) { + $reset_sortdir = true; + } + $_SESSION["mysort"] = $mysort; +} + +if (!empty($_GET["sortdir"]) && !$reset_sortdir) { + $sortdir = strtoupper(trim($_GET["sortdir"])) == "DESC" ? "DESC" : "ASC"; + $_SESSION["sortdir"] = $sortdir; +} + +if (!isset($_SESSION["sortdir"]) || $reset_sortdir) { + $sortdir = "ASC"; + $_SESSION["sortdir"] = $sortdir; +} + +if (!isset($_SESSION["mysort"])) { + $sortby = "rankorder {$_SESSION['sortdir']}, i.name"; + $_SESSION["mysort"] = "ranking"; +} +else { + switch ($_SESSION["mysort"]) { + case "name": + $sortby = "i.name {$_SESSION['sortdir']}"; + break; + case "source": + $sortby = "source {$_SESSION['sortdir']}, rankorder, i.name"; + break; + case "quantity": + $sortby = "quantity {$_SESSION['sortdir']}, rankorder, i.name"; + break; + case "price": + $sortby = "price {$_SESSION['sortdir']}, rankorder, i.name"; + break; + case "category": + $sortby = "c.category {$_SESSION['sortdir']}, rankorder, i.name"; + break; + default: + $sortby = "rankorder {$_SESSION['sortdir']}, i.name"; + } +} +$stmt = $smarty->dbh()->prepare("SELECT itemid, name, description, i.category as catid, c.category, price, price as pricenum, source, url, i.ranking as rankid, rendered, comment, quantity, image_filename, public 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 WHERE userid = ? and i.archive = true ORDER BY " . $sortby); +$stmt->bindParam(1, $userid, PDO::PARAM_INT); +$stmt->execute(); +$myitems_count = 0; +$myitems = array(); +for ($i = 0; $i < $offset; $i++, ++$myitems_count) { + $row = $stmt->fetch(); +} +$i = 0; +while ($i++ < $opt["items_per_page"] && $row = $stmt->fetch()) { + $row['price'] = formatPrice($row['price'], $opt); + $row['urlhost'] = preg_replace("/^(https?:\/\/)?(www\.)?([^\/]+)(\/.*)?$/", "$3", $row['url']); + $myitems[] = $row; + ++$myitems_count; +} +while ($stmt->fetch()) { + ++$myitems_count; +} + +$stmt = $smarty->dbh()->prepare("SELECT categoryid, category FROM {$opt["table_prefix"]}categories ORDER BY category"); +$stmt->execute(); +$categories = array(); +while ($row = $stmt->fetch()) { + $categories[] = $row; +} + +$stmt = $smarty->dbh()->prepare("SELECT ranking, title FROM {$opt["table_prefix"]}ranks ORDER BY rankorder"); +$stmt->execute(); +$ranks = array(); +while ($row = $stmt->fetch()) { + $ranks[] = $row; +} + +if (!$opt["auto_connect_family_members"]) { + # When family members are not automatic shoppers + $stmt = $smarty->dbh()->prepare("SELECT u.userid, u.fullname, u.comment, u.list_stamp, ISNULL(sub.subscriber) AS is_unsubscribed, COUNT(i.itemid) AS itemcount " . + "FROM {$opt["table_prefix"]}shoppers s " . + "INNER JOIN {$opt["table_prefix"]}users u ON u.userid = s.mayshopfor " . + "LEFT OUTER JOIN {$opt["table_prefix"]}items i ON u.userid = i.userid " . + "LEFT OUTER JOIN {$opt["table_prefix"]}subscriptions sub ON sub.publisher = u.userid AND sub.subscriber = ? " . + "WHERE s.shopper = ? " . + "AND pending = 0 " . + "GROUP BY u.userid, u.fullname, u.list_stamp " . + "ORDER BY u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + $shoppees = array(); + while ($row = $stmt->fetch()) { + if ($row['list_stamp'] == 0) { + $row['list_stamp'] = '-'; + } + else { + $listStampDate = new DateTime($row['list_stamp']); + $row['list_stamp'] = $listStampDate->format($opt["date_format"]); + } + $shoppees[] = $row; + } + + $stmt = $smarty->dbh()->prepare("SELECT DISTINCT u.userid, u.fullname, s.pending " . + "FROM {$opt["table_prefix"]}memberships mymem " . + "INNER JOIN {$opt["table_prefix"]}memberships others " . + "ON others.familyid = mymem.familyid AND others.userid <> ? " . + "INNER JOIN {$opt["table_prefix"]}users u " . + "ON u.userid = others.userid " . + "LEFT OUTER JOIN {$opt["table_prefix"]}shoppers s " . + "ON s.mayshopfor = others.userid AND s.shopper = ? " . + "WHERE mymem.userid = ? " . + "AND (s.pending IS NULL OR s.pending = 1) " . + "AND u.approved = 1 " . + "ORDER BY u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->bindParam(3, $userid, PDO::PARAM_INT); + $stmt->execute(); + $prospects = array(); + while ($row = $stmt->fetch()) { + $prospects[] = $row; + } +} else { + # When family members are automatically connected as shoppers + $stmt = $smarty->dbh()->prepare("SELECT u.userid, u.fullname, u.comment, u.list_stamp, ISNULL(sub.subscriber) AS is_unsubscribed, COUNT(i.itemid) AS itemcount " . + "FROM {$opt["table_prefix"]}users u " . + "JOIN {$opt["table_prefix"]}memberships m ON u.userid = m.userid " . + "LEFT JOIN {$opt["table_prefix"]}items i ON u.userid = i.userid " . + "LEFT JOIN {$opt["table_prefix"]}subscriptions sub ON sub.publisher = u.userid AND sub.subscriber = ? " . + "WHERE m.familyid IN ( " . + "SELECT familyid " . + "FROM {$opt["table_prefix"]}memberships " . + "WHERE userid = ? " . + ") " . + "AND u.userid != ? " . + "GROUP BY u.userid, u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->bindParam(3, $userid, PDO::PARAM_INT); + $stmt->execute(); + $shoppees = array(); + while ($row = $stmt->fetch()) { + if ($row['list_stamp'] == 0) { + $row['list_stamp'] = '-'; + } + else { + $listStampDate = new DateTime($row['list_stamp']); + $row['list_stamp'] = $listStampDate->format($opt["date_format"]); + } + $shoppees[] = $row; + } + $prospects = array(); +} + +$stmt = $smarty->dbh()->prepare("SELECT messageid, u.fullname, message, created " . + "FROM {$opt["table_prefix"]}messages m " . + "INNER JOIN {$opt["table_prefix"]}users u ON u.userid = m.sender " . + "WHERE m.recipient = ? " . + "AND m.isread = 0 " . + "ORDER BY created DESC"); +$stmt->bindParam(1, $userid, PDO::PARAM_INT); +$stmt->execute(); +$messages = array(); +while ($row = $stmt->fetch()) { + $createdDateTime = new DateTime($row['created']); + $row['created'] = $createdDateTime->format($opt["date_format"]); + $messages[] = $row; +} + +$query = "SELECT CONCAT(YEAR(CURDATE()),'-',MONTH(eventdate),'-',DAYOFMONTH(eventdate)) AS DateThisYear, " . + "TO_DAYS(CONCAT(YEAR(CURDATE()),'-',MONTH(eventdate),'-',DAYOFMONTH(eventdate))) AS ToDaysDateThisYear, " . + "CONCAT(YEAR(CURDATE()) + 1,'-',MONTH(eventdate),'-',DAYOFMONTH(eventdate)) AS DateNextYear, " . + "TO_DAYS(CONCAT(YEAR(CURDATE()) + 1,'-',MONTH(eventdate),'-',DAYOFMONTH(eventdate))) AS ToDaysDateNextYear, " . + "TO_DAYS(CURDATE()) AS ToDaysToday, " . + "TO_DAYS(eventdate) AS ToDaysEventDate, " . + "e.userid, u.fullname, description, eventdate, recurring, s.pending " . + "FROM {$opt["table_prefix"]}events e " . + "LEFT OUTER JOIN {$opt["table_prefix"]}users u ON u.userid = e.userid " . + "LEFT OUTER JOIN {$opt["table_prefix"]}shoppers s ON s.mayshopfor = e.userid AND s.shopper = ? "; +if ($opt["show_own_events"]) + $query .= "WHERE (pending = 0 OR pending IS NULL)"; +else + $query .= "WHERE (e.userid <> ? OR e.userid IS NULL) AND (pending = 0 OR pending IS NULL)"; +$query .= "ORDER BY u.fullname"; +$stmt = $smarty->dbh()->prepare($query); +$stmt->bindParam(1, $userid, PDO::PARAM_INT); +if (!$opt["show_own_events"]) + $stmt->bindParam(2, $userid, PDO::PARAM_INT); +$stmt->execute(); +$events = array(); +while ($row = $stmt->fetch()) { + $event_fullname = $row["fullname"]; + $days_left = -1; + if (!$row["recurring"] && (($row["ToDaysEventDate"] - $row["ToDaysToday"]) >= 0) && (($row["ToDaysEventDate"] - $row["ToDaysToday"]) <= $opt["event_threshold"])) { + $days_left = $row["ToDaysEventDate"] - $row["ToDaysToday"]; + $event_date = new DateTime($row["eventdate"]); + } + else if ($row["recurring"] && (($row["ToDaysDateThisYear"] - $row["ToDaysToday"]) >= 0) && (($row["ToDaysDateThisYear"] - $row["ToDaysToday"]) <= $opt["event_threshold"])) { + $days_left = $row["ToDaysDateThisYear"] - $row["ToDaysToday"]; + $event_date = new DateTime($row["DateThisYear"]); + } + else if ($row["recurring"] && (($row["ToDaysDateNextYear"] - $row["ToDaysToday"]) >= 0) && (($row["ToDaysDateNextYear"] - $row["ToDaysToday"]) <= $opt["event_threshold"])) { + $days_left = $row["ToDaysDateNextYear"] - $row["ToDaysToday"]; + $event_date = new DateTime($row["DateNextYear"]); + } + if ($days_left >= 0) { + $thisevent = array( + 'fullname' => $event_fullname, + 'eventname' => $row['description'], + 'daysleft' => $days_left, + 'date' => $event_date->format($opt["date_format"]) + ); + $events[] = $thisevent; + } +} + +function compareEvents($a, $b) { + if ($a["daysleft"] == $b["daysleft"]) + return 0; + else + return ($a["daysleft"] > $b["daysleft"]) ? 1 : -1; +} + +// i couldn't figure out another way to do this, so here goes. +// sort() wanted to sort based on the array keys, which were 0..n - 1, so that was useless. +usort($events, "compareEvents"); + +if ($opt["shop_requires_approval"]) { + $query = "SELECT u.userid, u.fullname " . + "FROM {$opt["table_prefix"]}shoppers s " . + "INNER JOIN {$opt["table_prefix"]}users u ON u.userid = s.shopper " . + "WHERE s.mayshopfor = ? " . + "AND s.pending = 1 " . + "ORDER BY u.fullname"; + $stmt = $smarty->dbh()->prepare($query); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->execute(); + $pending = array(); + while ($row = $stmt->fetch()) { + $pending[] = $row; + } +} + +if (($_SESSION["admin"] == 1) && $opt["newuser_requires_approval"]) { + $query = "SELECT userid, fullname, email, approved, initialfamilyid, familyname " . + "FROM {$opt["table_prefix"]}users u " . + "LEFT OUTER JOIN {$opt["table_prefix"]}families f ON f.familyid = u.initialfamilyid " . + "WHERE approved = 0 " . + "ORDER BY fullname"; + $stmt = $smarty->dbh()->prepare($query); + $stmt->execute(); + $approval = array(); + while ($row = $stmt->fetch()) { + $approval[] = $row; + } +} + +$smarty->assign('fullname', $_SESSION['fullname']); +if (isset($message)) { + $smarty->assign('message', $message); +} +$smarty->assign('mysort', $_SESSION['mysort']); +$smarty->assign('sortdir', $_SESSION['sortdir']); +$smarty->assign('categories', $categories); +$smarty->assign('ranks', $ranks); +$smarty->assign('myitems', $myitems); +$smarty->assign('myitems_count', $myitems_count); +$smarty->assign('offset', $offset); +$smarty->assign('shoppees', $shoppees); +$smarty->assign('prospects', $prospects); +$smarty->assign('messages', $messages); +$smarty->assign('events', $events); +if (isset($pending)) { + $smarty->assign('pending', $pending); +} +if (isset($approval)) { + $smarty->assign('approval', $approval); +} +$smarty->assign('userid', $userid); +$smarty->display('archive.tpl'); +?> diff --git a/src/help.php b/src/help.php index 338689b..74b7b6a 100644 --- a/src/help.php +++ b/src/help.php @@ -54,11 +54,12 @@ if (!empty($_POST["action"])) { } try { - $stmt = $smarty->dbh()->prepare("SELECT show_helptext FROM {$opt["table_prefix"]}users WHERE userid = ?"); + $stmt = $smarty->dbh()->prepare("SELECT email, show_helptext FROM {$opt["table_prefix"]}users WHERE userid = ?"); $stmt->bindParam(1, $userid, PDO::PARAM_INT); $stmt->execute(); if ($row = $stmt->fetch()) { + $smarty->assign('email', $row["email"]); $smarty->assign('show_helptext', $row["show_helptext"]); $_SESSION['show_helptext'] = $row["show_helptext"]; } diff --git a/src/images/archive-fill-dark.png b/src/images/archive-fill-dark.png new file mode 100644 index 0000000..c0dad79 Binary files /dev/null and b/src/images/archive-fill-dark.png differ diff --git a/src/images/archive-fill-light.png b/src/images/archive-fill-light.png new file mode 100644 index 0000000..a5fae73 Binary files /dev/null and b/src/images/archive-fill-light.png differ diff --git a/src/images/basket3-fill-dark.png b/src/images/basket3-fill-dark.png new file mode 100644 index 0000000..992b8b0 Binary files /dev/null and b/src/images/basket3-fill-dark.png differ diff --git a/src/images/basket3-fill-light.png b/src/images/basket3-fill-light.png new file mode 100644 index 0000000..75c502e Binary files /dev/null and b/src/images/basket3-fill-light.png differ diff --git a/src/includes/config.php b/src/includes/config.php index 906ca18..699a4e8 100644 --- a/src/includes/config.php +++ b/src/includes/config.php @@ -62,6 +62,12 @@ function getGlobalOptions() { */ "newuser_default_family" => 1, + /* Automatically make family members shoppers for each other + 0 = manual connections + 1 = auto connect family members + */ + "auto_connect_family_members" => 1, + /* Whether or not whom an item is reserved/bought by is hidden. */ "anonymous_purchasing" => 0, @@ -87,6 +93,13 @@ function getGlobalOptions() { */ "show_helptext" => 1, + /* Whether or not clicking the Archive Item link requires a JavaScript-based + confirmation. + 0 = don't show confirmation, + 1 = show confirmation + */ + "confirm_item_archives" => 1, + /* Whether or not clicking the Delete Item link requires a JavaScript-based confirmation. 0 = don't show confirmation, diff --git a/src/includes/config.php.dist b/src/includes/config.php.dist index c28a417..62ecd39 100644 --- a/src/includes/config.php.dist +++ b/src/includes/config.php.dist @@ -61,6 +61,13 @@ function getGlobalOptions() { */ "show_helptext" => 0, + /* Whether or not clicking the Archive Item link requires a JavaScript-based + confirmation. + 0 = don't show confirmation, + 1 = show confirmation + */ + "confirm_item_archives" => 0, + /* Whether or not clicking the Delete Item link requires a JavaScript-based confirmation. 0 = don't show confirmation, diff --git a/src/index.php b/src/index.php index 009d885..43ef737 100644 --- a/src/index.php +++ b/src/index.php @@ -190,7 +190,7 @@ else { $sortby = "rankorder {$_SESSION['sortdir']}, i.name"; } } -$stmt = $smarty->dbh()->prepare("SELECT itemid, name, description, i.category as catid, c.category, price, price as pricenum, source, url, i.ranking as rankid, rendered, comment, quantity, image_filename 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 WHERE userid = ? ORDER BY " . $sortby); +$stmt = $smarty->dbh()->prepare("SELECT itemid, name, description, i.category as catid, c.category, price, price as pricenum, source, url, i.ranking as rankid, rendered, comment, quantity, created, image_filename, public 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 WHERE userid = ? and i.archive = false ORDER BY " . $sortby); $stmt->bindParam(1, $userid, PDO::PARAM_INT); $stmt->execute(); $myitems_count = 0; @@ -223,49 +223,82 @@ while ($row = $stmt->fetch()) { $ranks[] = $row; } -$stmt = $smarty->dbh()->prepare("SELECT u.userid, u.fullname, u.comment, u.list_stamp, ISNULL(sub.subscriber) AS is_unsubscribed, COUNT(i.itemid) AS itemcount " . - "FROM {$opt["table_prefix"]}shoppers s " . - "INNER JOIN {$opt["table_prefix"]}users u ON u.userid = s.mayshopfor " . - "LEFT OUTER JOIN {$opt["table_prefix"]}items i ON u.userid = i.userid " . - "LEFT OUTER JOIN {$opt["table_prefix"]}subscriptions sub ON sub.publisher = u.userid AND sub.subscriber = ? " . - "WHERE s.shopper = ? " . - "AND pending = 0 " . - "GROUP BY u.userid, u.fullname, u.list_stamp " . - "ORDER BY u.fullname"); -$stmt->bindParam(1, $userid, PDO::PARAM_INT); -$stmt->bindParam(2, $userid, PDO::PARAM_INT); -$stmt->execute(); -$shoppees = array(); -while ($row = $stmt->fetch()) { - if ($row['list_stamp'] == 0) { - $row['list_stamp'] = '-'; +if (!$opt["auto_connect_family_members"]) { + # When family members are not automatic shoppers + $stmt = $smarty->dbh()->prepare("SELECT u.userid, u.fullname, u.comment, u.list_stamp, ISNULL(sub.subscriber) AS is_unsubscribed, COUNT(i.itemid) AS itemcount " . + "FROM {$opt["table_prefix"]}shoppers s " . + "INNER JOIN {$opt["table_prefix"]}users u ON u.userid = s.mayshopfor " . + "LEFT OUTER JOIN {$opt["table_prefix"]}items i ON u.userid = i.userid " . + "LEFT OUTER JOIN {$opt["table_prefix"]}subscriptions sub ON sub.publisher = u.userid AND sub.subscriber = ? " . + "WHERE s.shopper = ? " . + "AND pending = 0 " . + "GROUP BY u.userid, u.fullname, u.list_stamp " . + "ORDER BY u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->execute(); + $shoppees = array(); + while ($row = $stmt->fetch()) { + if ($row['list_stamp'] == 0) { + $row['list_stamp'] = '-'; + } + else { + $listStampDate = new DateTime($row['list_stamp']); + $row['list_stamp'] = $listStampDate->format($opt["date_format"]); + } + $shoppees[] = $row; } - else { - $listStampDate = new DateTime($row['list_stamp']); - $row['list_stamp'] = $listStampDate->format($opt["date_format"]); - } - $shoppees[] = $row; -} -$stmt = $smarty->dbh()->prepare("SELECT DISTINCT u.userid, u.fullname, s.pending " . - "FROM {$opt["table_prefix"]}memberships mymem " . - "INNER JOIN {$opt["table_prefix"]}memberships others " . - "ON others.familyid = mymem.familyid AND others.userid <> ? " . - "INNER JOIN {$opt["table_prefix"]}users u " . - "ON u.userid = others.userid " . - "LEFT OUTER JOIN {$opt["table_prefix"]}shoppers s " . - "ON s.mayshopfor = others.userid AND s.shopper = ? " . - "WHERE mymem.userid = ? " . - "AND (s.pending IS NULL OR s.pending = 1) " . - "AND u.approved = 1 " . - "ORDER BY u.fullname"); -$stmt->bindParam(1, $userid, PDO::PARAM_INT); -$stmt->bindParam(2, $userid, PDO::PARAM_INT); -$stmt->bindParam(3, $userid, PDO::PARAM_INT); -$stmt->execute(); -$prospects = array(); -while ($row = $stmt->fetch()) { - $prospects[] = $row; + $stmt = $smarty->dbh()->prepare("SELECT DISTINCT u.userid, u.fullname, s.pending " . + "FROM {$opt["table_prefix"]}memberships mymem " . + "INNER JOIN {$opt["table_prefix"]}memberships others " . + "ON others.familyid = mymem.familyid AND others.userid <> ? " . + "INNER JOIN {$opt["table_prefix"]}users u " . + "ON u.userid = others.userid " . + "LEFT OUTER JOIN {$opt["table_prefix"]}shoppers s " . + "ON s.mayshopfor = others.userid AND s.shopper = ? " . + "WHERE mymem.userid = ? " . + "AND (s.pending IS NULL OR s.pending = 1) " . + "AND u.approved = 1 " . + "ORDER BY u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->bindParam(3, $userid, PDO::PARAM_INT); + $stmt->execute(); + $prospects = array(); + while ($row = $stmt->fetch()) { + $prospects[] = $row; + } +} else { + # When family members are automatically connected as shoppers + $stmt = $smarty->dbh()->prepare("SELECT u.userid, u.fullname, u.comment, u.list_stamp, ISNULL(sub.subscriber) AS is_unsubscribed, COUNT(i.itemid) AS itemcount " . + "FROM {$opt["table_prefix"]}users u " . + "JOIN {$opt["table_prefix"]}memberships m ON u.userid = m.userid " . + "LEFT JOIN {$opt["table_prefix"]}items i ON u.userid = i.userid " . + "LEFT JOIN {$opt["table_prefix"]}subscriptions sub ON sub.publisher = u.userid AND sub.subscriber = ? " . + "WHERE m.familyid IN ( " . + "SELECT familyid " . + "FROM {$opt["table_prefix"]}memberships " . + "WHERE userid = ? " . + ") " . + "AND u.userid != ? " . + "GROUP BY u.userid, u.fullname"); + $stmt->bindParam(1, $userid, PDO::PARAM_INT); + $stmt->bindParam(2, $userid, PDO::PARAM_INT); + $stmt->bindParam(3, $userid, PDO::PARAM_INT); + $stmt->execute(); + $shoppees = array(); + while ($row = $stmt->fetch()) { + if ($row['list_stamp'] == 0) { + $row['list_stamp'] = '-'; + } + else { + $listStampDate = new DateTime($row['list_stamp']); + $row['list_stamp'] = $listStampDate->format($opt["date_format"]); + } + $shoppees[] = $row; + } + $prospects = array(); } $stmt = $smarty->dbh()->prepare("SELECT messageid, u.fullname, message, created " . diff --git a/src/item.php b/src/item.php index 14f3018..34e095f 100644 --- a/src/item.php +++ b/src/item.php @@ -36,6 +36,7 @@ $url = ""; $category = 1; $ranking = 3; $comment = ""; +$public = 0; $quantity = 1; $image_url = ""; $image_filename = ""; @@ -78,6 +79,7 @@ if (!empty($_REQUEST["action"])) { $category = isset($_REQUEST["category"]) ? trim($_REQUEST["category"]) : "1"; $ranking = isset($_REQUEST["ranking"]) ? $_REQUEST["ranking"] : "3"; $comment = isset($_REQUEST["comment"]) ? $_REQUEST["comment"] : ""; + $public = isset($_REQUEST["public"]) ? $_REQUEST["public"] : 0; if (isset($_REQUEST["pricesymbol"]) && $_REQUEST["pricesymbol"] != $opt["currency_symbol"]) { $price = ""; $comment = trim("$comment Price not in {$opt['currency_symbol']}, it is {$_REQUEST["pricesymbol"]}{$_REQUEST['price']}."); @@ -200,6 +202,34 @@ if (!empty($_REQUEST["action"])) { } } + if ($action == "archive") { + try { + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}items SET archive=true WHERE itemid = ?"); + $stmt->bindValue(1, (int) $_REQUEST["itemid"], PDO::PARAM_INT); + $stmt->execute(); + + header("Location: " . getFullPath("index.php?message=Item+archived.")); + exit; + } + catch (PDOException $e) { + die("sql exception: " . $e->getMessage()); + } + } + + if ($action == "unarchive") { + try { + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}items SET archive=false WHERE itemid = ?"); + $stmt->bindValue(1, (int) $_REQUEST["itemid"], PDO::PARAM_INT); + $stmt->execute(); + + header("Location: " . getFullPath("archive.php?message=Item+unarchived.")); + exit; + } + catch (PDOException $e) { + die("sql exception: " . $e->getMessage()); + } + } + if ($action == "delete") { try { /* find out if this item is bought or reserved. */ @@ -241,7 +271,7 @@ if (!empty($_REQUEST["action"])) { } } else if ($action == "edit") { - $stmt = $smarty->dbh()->prepare("SELECT name, description, price, source, category, url, ranking, comment, quantity, image_filename FROM {$opt["table_prefix"]}items WHERE itemid = ?"); + $stmt = $smarty->dbh()->prepare("SELECT name, description, price, source, category, url, ranking, comment, public, quantity, image_filename FROM {$opt["table_prefix"]}items WHERE itemid = ?"); $stmt->bindValue(1, (int) $_REQUEST["itemid"], PDO::PARAM_INT); $stmt->execute(); @@ -254,6 +284,7 @@ if (!empty($_REQUEST["action"])) { $category = $row["category"]; $ranking = $row["ranking"]; $comment = $row["comment"]; + $public = $row["public"]; $quantity = (int) $row["quantity"]; $image_filename = $row["image_filename"]; } @@ -267,13 +298,14 @@ if (!empty($_REQUEST["action"])) { $category = 1; $ranking = 3; $comment = ""; + $public = 0; $quantity = 1; $image_filename = ""; } else if ($action == "insert") { if (!$haserror) { - $stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}items(userid,name,description,price,source,category,url,ranking,comment,quantity,image_filename) " . - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}items(userid,name,description,price,source,category,url,ranking,comment,public,quantity,created,image_filename) " . + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->bindParam(1, $userid, PDO::PARAM_INT); $stmt->bindParam(2, $name, PDO::PARAM_STR); $stmt->bindParam(3, $description, PDO::PARAM_STR); @@ -283,11 +315,13 @@ if (!empty($_REQUEST["action"])) { $stmt->bindParam(7, $url, PDO::PARAM_STR); $stmt->bindParam(8, $ranking, PDO::PARAM_INT); $stmt->bindParam(9, $comment, PDO::PARAM_STR); - $stmt->bindParam(10, $quantity, PDO::PARAM_INT); + $stmt->bindParam(10, $public, PDO::PARAM_BOOL); + $stmt->bindParam(11, $quantity, PDO::PARAM_INT); + $stmt->bindParam(12, date('Y-m-d H:i:s')); if (!isset($image_base_filename) || $image_base_filename == "") { $image_base_filename = NULL; } - $stmt->bindParam(11, $image_base_filename, PDO::PARAM_STR); + $stmt->bindParam(13, $image_base_filename, PDO::PARAM_STR); $stmt->execute(); stampUser($userid, $smarty->dbh(), $smarty->opt()); @@ -309,6 +343,7 @@ if (!empty($_REQUEST["action"])) { "url = ?, " . "ranking = ?, " . "comment = ?, " . + "public = ?, " . "quantity = ? " . ($image_base_filename != "" ? ", image_filename = ? " : "") . "WHERE itemid = ?"); @@ -320,13 +355,15 @@ if (!empty($_REQUEST["action"])) { $stmt->bindParam(6, $url, PDO::PARAM_STR); $stmt->bindParam(7, $ranking, PDO::PARAM_INT); $stmt->bindParam(8, $comment, PDO::PARAM_STR); - $stmt->bindParam(9, $quantity, PDO::PARAM_INT); + $stmt->bindParam(9, $public, PDO::PARAM_BOOL); + $stmt->bindParam(10, $quantity, PDO::PARAM_INT); + error_log("public = $public"); if ($image_base_filename != "") { - $stmt->bindParam(10, $image_base_filename, PDO::PARAM_STR); - $stmt->bindValue(11, (int) $_REQUEST["itemid"], PDO::PARAM_INT); + $stmt->bindParam(11, $image_base_filename, PDO::PARAM_STR); + $stmt->bindValue(12, (int) $_REQUEST["itemid"], PDO::PARAM_INT); } else { - $stmt->bindValue(10, (int) $_REQUEST["itemid"], PDO::PARAM_INT); + $stmt->bindValue(11, (int) $_REQUEST["itemid"], PDO::PARAM_INT); } $stmt->execute(); @@ -400,6 +437,7 @@ if (isset($url_error)) { } $smarty->assign('image_filename', $image_filename); $smarty->assign('comment', $comment); +$smarty->assign('public', $public); $smarty->assign('categories', $categories); $smarty->assign('ranks', $ranks); header("Location: " . getFullPath("index.php")); diff --git a/src/receive.php b/src/receive.php index 31ad06b..56a427d 100644 --- a/src/receive.php +++ b/src/receive.php @@ -73,13 +73,16 @@ try { if ($quantity == 1) { /* just delete the alloc and the item and get out. yes, it's possible the item was RESERVED, not PURCHASED. */ - deleteImageForItem($itemid, $smarty->dbh(), $smarty->opt()); + // don't delete images for archived items + // deleteImageForItem($itemid, $smarty->dbh(), $smarty->opt()); + /* $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}allocs WHERE itemid = ?"); $stmt->bindParam(1, $itemid, PDO::PARAM_INT); $stmt->execute(); + */ - $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}items WHERE itemid = ?"); + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}items SET archive=true WHERE itemid = ?"); $stmt->bindParam(1, $itemid, PDO::PARAM_INT); $stmt->execute(); @@ -97,8 +100,9 @@ try { if ($actual == $quantity) { // now they're all gone. - deleteImageForItem($itemid, $smarty->dbh(), $smarty->opt()); - $stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}items WHERE itemid = ?"); + // don't delete images for archived items + // deleteImageForItem($itemid, $smarty->dbh(), $smarty->opt()); + $stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}items SET archive=true WHERE itemid = ?"); $stmt->bindParam(1, $itemid, PDO::PARAM_INT); $stmt->execute(); } diff --git a/src/shop.php b/src/shop.php index 2880ee4..26231b4 100644 --- a/src/shop.php +++ b/src/shop.php @@ -18,26 +18,47 @@ require_once(dirname(__FILE__) . "/includes/MySmarty.class.php"); $smarty = new MySmarty(); $opt = $smarty->opt(); -session_start(); -if (!isset($_SESSION["userid"])) { - header("Location: " . getFullPath("login.php") . "?from=shop.php"); - exit; -} -else { - $userid = $_SESSION["userid"]; -} +$public_view = 0; +if (isset($_GET["list"])) { + $list = filter_var(strtolower(trim($_GET["list"])), FILTER_SANITIZE_EMAIL);; + $list = htmlspecialchars($list, ENT_QUOTES, 'UTF-8'); -$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"]})"); + 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")); } - $shopfor = (int) $shopfor; -//} else { -// header("Location: " . getFullPath("index.php")); } if ($shopfor == $userid) { @@ -142,13 +163,17 @@ if (!empty($_GET["action"])) { } } -$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 (!$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"])) { @@ -198,18 +223,23 @@ 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, price as pricenum, source, i.category as catid, c.category, url, r.title as rank, i.ranking as rankid, image_filename, " . +$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 " . + "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 = ? " . - "ORDER BY " . $sortby); + "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(); @@ -238,7 +268,7 @@ while ($row = $stmt->fetch()) { $itemallocs[] = ($allocrow['quantity'] . " bought by you."); } else { - if (!$opt["anonymous_purchasing"]) { + if (!$opt["anonymous_purchasing"] && !$public_view) { $itemallocs[] = ($allocrow['quantity'] . " bought by " . $allocrow['bfullname'] . "."); } else { @@ -252,11 +282,11 @@ while ($row = $stmt->fetch()) { $itemallocs[] = ($allocrow['quantity'] . " reserved by you."); } else { - if (!$opt["anonymous_purchasing"]) { + if (!$opt["anonymous_purchasing"] && !$public_view) { $itemallocs[] = ($allocrow['quantity'] . " reserved by " . $allocrow['rfullname'] . "."); } else { - $itemallocs[] = ($allocrow['quanitity'] . " reserved."); + $itemallocs[] = ($allocrow['quantity'] . " reserved."); } } } @@ -292,6 +322,7 @@ $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"]; } diff --git a/src/sql/create-phpgiftregdb.sql b/src/sql/create-phpgiftregdb.sql index bcdd6e1..7f721e7 100644 --- a/src/sql/create-phpgiftregdb.sql +++ b/src/sql/create-phpgiftregdb.sql @@ -78,6 +78,10 @@ CREATE TABLE `items` ( `comment` text, `quantity` int(11) NOT NULL default '0', `image_filename` varchar(255) default NULL, + `public` tinyint(1) NOT NULL default '0', + `archive` tinyint(1) NOT NULL default '0', + `archive` tinyint(1) NOT NULL default '0', + `created` datetime default NULL, PRIMARY KEY (`itemid`) ); diff --git a/src/templates/archive.tpl b/src/templates/archive.tpl new file mode 100644 index 0000000..20bf651 --- /dev/null +++ b/src/templates/archive.tpl @@ -0,0 +1,418 @@ +{* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*} + + + + + {$opt.app_name} - Archive for {$fullname|escape:'htmlall'} + + + + + + + + + + + + + + + {include file='navbar.tpl'} +
+
+ {if isset($message)} + + {/if} + {if $opt.show_helptext} +
+
Help
+
+
    +
  • You can click the column headers to sort by that attribute.
  • +
  • List each item seperately on your list - do not combine items. (i.e. list each book of a 4-part series separately.)
  • +
  • Once you've bought or decided not to buy an item, remember to return to the recipient's gift lists and mark it accordingly.
  • +
  • If someone purchases an item on your list, click to mark it as received.
  • +
  • To unarchive an item on your list, click .
  • +
+
+
+ {/if} +
+

My Items

+
+
+ + + + + + + + + + + + + + {foreach from=$myitems item=row} + + + + + + + + + + {/foreach} + +
Name{if $mysort == "name"} {/if}Ranking{if $mysort == "ranking"} {/if}Quantity{if $mysort == "quantity"} {/if}Category{if $mysort == "category"} {/if}Store{if $mysort == "source"} {/if}Price{if $mysort == "price"} {/if}Actions
+
+ +
+ + {$row.name|truncate:50|escape:'htmlall'} + + + {if $row.public == 1}   Item is Public{/if} +
{$row.rankid}{$row.quantity}{$row.category|default:" "}{$row.source|default:" "}{$row.price} + {if $row.url != ''} + Link  + {/if} + {if $row.image_filename != '' && $opt.allow_images} + Image  + {/if} + Mark Item Received  + Edit Item  + Unarchive Item + Delete Item +
+
+ {if $myitems_count > $opt.items_per_page || $offset > 0} + + {/if} +
+ +
+
+
+ {include file='footer.tpl'} + + diff --git a/src/templates/help.tpl b/src/templates/help.tpl index 98b49cc..b92d63e 100644 --- a/src/templates/help.tpl +++ b/src/templates/help.tpl @@ -75,6 +75,24 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +
+
+
What's New
+
+
    +
  • 2024-12-31: Items can be marked "Public" and shared with others via +
    + + +
    +
  • +
  • 2024-12-31: Marking items as received archives them instead of deletes them
  • +
  • 2024-12-31: Items can be archived and the Item Archive can be viewed under the profile icon (top-right)
  • +
  • 2024-12-17: You are automatically a shopper for your family members
  • +
+
+
+
Gift Registry Help
@@ -141,5 +159,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{include file='footer.tpl'} + diff --git a/src/templates/home.tpl b/src/templates/home.tpl index 2a7a934..e09b46e 100644 --- a/src/templates/home.tpl +++ b/src/templates/home.tpl @@ -30,6 +30,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - {include file='navbar.tpl' isadmin=$isadmin} + {if !$public_view} + {include file='navbar.tpl' isadmin=$isadmin} + {else} + {include file='public_navbar.tpl'} + {/if}
{if isset($message)} @@ -52,7 +56,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  • If you return something you've purchased, come back and click the icon. It will remain reserved for you.
  • Just because an item has a URL listed doesn't mean you have to buy it from there (unless the comment says so).
  • You can click the column headers to sort by that attribute.
  • -
  • If you see something you'd like for yourself, click the icon to copy it to your own list.
  • + {if !$public_view} +
  • If you see something you'd like for yourself, click the icon to copy it to your own list.
  • + {/if}
    @@ -167,33 +173,38 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - {$row.name|truncate:50|escape:'htmlall'} + {$row.name|truncate:50|escape:'htmlall'} {$row.rankid} @@ -249,7 +260,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA {* *} {else} - {if $opt.anonymous_purchasing} + {if $opt.anonymous_purchasing || $public_view} Reserved. {else} Reserved by {$row.rfullname|escape:'htmlall'}. @@ -286,7 +297,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA {/if} {/if} {* *} - I Want This Too + {if !$public_view} + I Want This Too + {/if} {/foreach} @@ -296,25 +309,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -
    -
    -
    -

    {$ufullname|escape:'htmlall'} Info

    -
    - {if $uemail != ''} - Email Address: {$uemail|escape:'htmlall'}

    - {/if} - {if $ucomment != ''} - {$ucomment|escape:'htmlall'|nl2br} - {/if} -
    -
    -
    -
    + {if !$public_view} +
    +
    +
    +

    {$ufullname|escape:'htmlall'} Info

    +
    + {if $uemail != ''} + Email Address: {$uemail|escape:'htmlall'}

    + {/if} + {if $ucomment != ''} + {$ucomment|escape:'htmlall'|nl2br} + {/if} +
    +
    +
    +
    + {/if}
    Legend
    - Reserve = Reserve, Release = Release, Purchase = Purchase, Return = Return, I Want This Too = I Want This Too + Reserve = Reserve, Release = Release, Purchase = Purchase, Return = Return{if !$public_view}, I Want This Too = I Want This Too{/if}