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)}
+
+ {$message|escape:'htmlall'}
+
+ {/if}
+ {if $opt.show_helptext}
+
+
+
+
+ - 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}
+
+
+
+
+ {if $myitems_count > $opt.items_per_page || $offset > 0}
+
+ {/if}
+
+
+
+
Add a new item
+
+
+
+
+ {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
+
@@ -141,5 +159,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
{include file='footer.tpl'}
+