site/templates/include/rssitems.tmpl
site/templates/include/rsslinks.tmpl
site/templates/include/search_results.tmpl
+site/templates/include/usermenu.tmpl
site/templates/index.tmpl
site/templates/index2.tmpl
site/templates/interest/askagain_base.tmpl
site/templates/shopitem.tmpl
site/templates/sidebar/afflink.tmpl
site/templates/sidebar/logon.tmpl
+site/templates/sidebar/wishlist.tmpl
site/templates/test/children.tmpl
site/templates/test/testrep.tmpl
site/templates/textemail/basic.tmpl
site/templates/user/base_editbooking.tmpl
site/templates/user/base_orderdetail.tmpl
site/templates/user/base_redirect.tmpl
+site/templates/user/base_userpage_wishlist.tmpl
+site/templates/user/base_wishlist.tmpl
site/templates/user/blacklistdone_base.tmpl
site/templates/user/cantunsub_base.tmpl
site/templates/user/confirmed_base.tmpl
sql_statement text not null
);
+drop table if exists bse_wishlist;
+create table bse_wishlist (
+ user_id integer not null,
+ product_id integer not null,
+ display_order integer not null,
+ primary key(user_id, product_id)
+);
user/unsuball.tmpl = user,user/unsuball_base.tmpl
user/unsubone.tmpl = user,user/unsubone_base.tmpl
user/userpage.tmpl = user,user/userpage_base.tmpl
+user/userpage_wishlist.tmpl = user,user/base_userpage_wishlist.tmpl
+user/wishlist.tmpl = user,user/base_wishlist.tmpl
user/bookseminar.tmpl = user,user/base_bookseminar.tmpl
user/bookconfirm.tmpl = user,user/base_bookconfirm.tmpl
user/bookcomplete.tmpl = user,user/base_bookcomplete.tmpl
return;
}
+sub can_user_see_wishlist {
+ my ($self, $wishlist_user, $current_user, $req) = @_;
+
+ 1;
+}
+
1;
=head1 NAME
where oi.orderId = ? and oi.productId = ar.id and ar.id = pr.articleId
SQL
deleteProduct => 'delete from product where articleId = ?',
+ 'Products.userWishlist' => <<SQL,
+select ar.*, pr.* from article ar, product pr, bse_wishlist wi
+ where wi.user_id = ? and wi.product_id = ar.id and ar.id = pr.articleId
+order by wi.display_order desc
+SQL
+ bse_userWishlistOrder => <<SQL,
+select product_id, display_order
+from bse_wishlist
+where user_id = ?
+order by display_order desc
+SQL
+ bse_userWishlistReorder => <<SQL,
+update bse_wishlist
+ set display_order = ?
+where user_id = ? and product_id = ?
+SQL
+ bse_addToWishlist => <<SQL,
+insert into bse_wishlist(user_id, product_id, display_order)
+ values(?, ?, ?)
+SQL
+ bse_removeFromWishlist => <<SQL,
+delete from bse_wishlist where user_id = ? and product_id = ?
+SQL
+
Orders => 'select * from orders',
getOrderByPkey => 'select * from orders where id = ?',
getOrderItemByOrderId => 'select * from order_item where orderId = ?',
Products->getByPkey($article->{id});
}
+sub tags {
+ my ($self, $article) = @_;
+
+ return
+ (
+ $self->SUPER::tags($article),
+ ifInWishlist => [ tag_ifInWishlist => $self, $article ],
+ );
+}
+
+sub tag_ifInWishlist {
+ my ($self, $article) = @_;
+
+ my $user = $self->{req}->siteuser
+ or return 0;
+
+ return $user->product_in_wishlist($article);
+}
+
1;
nopassword => 'nopassword',
image => 'req_image',
orderdetail => 'req_orderdetail',
+ wishlistadd => 'req_wishlistadd',
+ wishlistdel => 'req_wishlistdel',
+ wishlistup => 'req_wishlistup',
+ wishlistdown => 'req_wishlistdown',
+ wishlisttop => 'req_wishlisttop',
+ wishlistbottom => 'req_wishlistbottom',
+ wishlist => 'req_wishlist',
);
sub actions { \%actions }
my $cgi = $req->cgi;
my $session = $req->session;
+ if ($message) {
+ $message = escape_html($message);
+ }
+ else {
+ $message = $req->message;
+ }
+
my $user = $self->_get_user($req, 'userpage')
or return;
require BSE::TB::Orders;
%acts =
(
$req->dyn_user_tags(),
- message => sub { CGI::escapeHTML($message) },
+ message => $message,
BSE::Util::Tags->make_iterator(\@orders, 'order', 'orders',
\$order_index),
BSE::Util::Tags->
close IMAGE;
}
+sub _refresh_wishlist {
+ my ($self, $req, $msg) = @_;
+
+ my $url = $req->cgi->param('r');
+ unless ($url) {
+ $url = '/cgi-bin/user.pl?_t=wishlist';
+ }
+
+ if ($url eq 'ajaxwishlist') {
+ return $self->req_userpage($req, $msg);
+ }
+ else {
+ $req->flash($msg);
+ refresh_to($url);
+ }
+}
+
+sub _wishlist_product {
+ my ($self, $req) = @_;
+
+ my $product_id = $req->cgi->param('product_id');
+ defined $product_id && $product_id =~ /^\d+$/
+ or return $self->req_userpage($req, "Missing or invalid product id");
+ require Products;
+ my $product = Products->getByPkey($product_id)
+ or return $self->req_userpage($req, "Unknown product id");
+
+ return $product;
+}
+
+sub req_wishlistadd {
+ my ($self, $req) = @_;
+
+ my $user = $self->_get_user($req, 'a_wishlistadd')
+ or return;
+ my $product = $self->_wishlist_product($req)
+ or return;
+ if ($user->product_in_wishlist($product)) {
+ return $self->_refresh_wishlist($req, "Product $product->{title} is already in your wishlist");
+ }
+
+ eval {
+ local $SIG{__DIE__};
+ $user->add_to_wishlist($product);
+ };
+ $@
+ and return $self->req_userpage($req, $@);
+
+ $self->_refresh_wishlist($req, "Product $product->{title} added to your wishlist");
+}
+
+sub req_wishlistdel {
+ my ($self, $req) = @_;
+
+ my $user = $self->_get_user($req, 'a_wishlistdel')
+ or return;
+
+ my $product = $self->_wishlist_product($req)
+ or return;
+
+ unless ($user->product_in_wishlist($product)) {
+ return $self->_refresh_wishlist($req, "Product $product->{title} is not in your wishlist");
+ }
+
+ eval {
+ local $SIG{__DIE__};
+ $user->remove_from_wishlist($product);
+ };
+ $@
+ and return $self->req_userpage($req, $@);
+
+ $self->_refresh_wishlist($req, "Product $product->{title} removed from your wishlist");
+}
+
+sub _wishlist_move {
+ my ($self, $req, $method) = @_;
+
+ my $user = $self->_get_user($req, $method)
+ or return;
+
+ my $product = $self->_wishlist_product($req)
+ or return;
+
+ unless ($user->product_in_wishlist($product)) {
+ return $self->_refresh_wishlist($req, "Product $product->{title} is not in your wishlist");
+ }
+
+ eval {
+ local $SIG{__DIE__};
+ $user->$method($product);
+ };
+ $@
+ and return $self->req_userpage($req, $@);
+
+ $self->_refresh_wishlist($req);
+}
+
+sub req_wishlisttop {
+ my ($self, $req) = @_;
+
+ return $self->_wishlist_move($req, 'move_to_wishlist_top');
+}
+
+sub req_wishlistbottom {
+ my ($self, $req) = @_;
+
+ return $self->_wishlist_move($req, 'move_to_wishlist_bottom');
+}
+
+sub req_wishlistup {
+ my ($self, $req) = @_;
+
+ return $self->_wishlist_move($req, 'move_up_wishlist');
+}
+
+sub req_wishlistdown {
+ my ($self, $req) = @_;
+
+ return $self->_wishlist_move($req, 'move_down_wishlist');
+}
+
+=item req_wishlist
+
+=target a_wishlist
+
+Display a given user's wishlist.
+
+Parameters:
+
+=over
+
+=item *
+
+user - user logon of the user to display the wishlist for
+
+=back
+
+Template: user/wishlist.tmpl
+
+Tags:
+
+
+
+=cut
+
+sub req_wishlist {
+ my ($self, $req) = @_;
+
+ my $user_id = $req->cgi->param('user');
+
+ defined $user_id && length $user_id
+ or return $self->error($req, "Invalid or missing user id");
+
+ my $custom = custom_class($req->cfg);
+
+ my $user = SiteUsers->getBy(userId => $user_id);
+
+ my $curr_user = $req->siteuser;
+
+ $custom->can_user_see_wishlist($user, $curr_user, $req)
+ or return $self->error($req, "Sorry, you cannot see $user_id's wishlist");
+
+ my @wishlist = $user->wishlist;
+
+ my %acts;
+ my $it = BSE::Util::Iterate::Article->new(req => $req);
+ %acts =
+ (
+ $req->dyn_user_tags(),
+ $it->make_iterator(undef, 'uwishlistentry', 'uwishlist', \@wishlist),
+ wuser => [ \&tag_hash, $user ],
+ );
+
+ my $template = 'user/wishlist';
+ my $t = $req->cgi->param('_t');
+ if ($t && $t =~ /^\w+$/ && $t ne 'base') {
+ $template .= "_$t";
+ }
+
+ BSE::Template->show_page($template, $req->cfg, \%acts);
+}
+
sub _notify_registration {
my ($self, $req, $user) = @_;
$self->dyn_article_iterator('dynallkids_of', 'dynofallkid'),
$self->dyn_article_iterator('dynchildren_of', 'dynofchild'),
$self->dyn_iterator('dyncart', 'dyncartitem'),
+ $self->dyn_article_iterator('wishlist', 'wishlistentry', $req),
url => [ tag_url => $self ],
dyncarttotalcost => [ tag_dyncarttotal => $self, 'total_cost' ],
dyncarttotalunits => [ tag_dyncarttotal => $self, 'total_units' ],
return $cart->{$field};
}
+sub iter_wishlist {
+ my ($self, $req) = @_;
+
+ my $user = $req->siteuser
+ or return [];
+ return [ $user->wishlist ];
+}
+
sub access_filter {
my ($self, @articles) = @_;
sub new {
my ($class, %opts) = @_;
+ if ($opts{req}) {
+ $opts{cfg} = $opts{req}->cfg;
+ }
+
$opts{cfg}
or confess "cfg option mission\n";
return tag_article($item, $self->{cfg}, $args);
}
+sub next_item {
+ my ($self, $article, $name) = @_;
+
+ if ($self->{req}) {
+ $self->{req}->set_article($name => $article);
+ }
+}
+
1;
if ($fmt eq 'u') {
return escape_uri($value);
}
+ elsif ($fmt eq 'U') {
+ return escape_uri(unescape_html($value));
+ }
elsif ($fmt eq 'h') {
return escape_html($value);
}
return $_[1];
}
+sub next_item {
+}
+
sub _iter_reset_paged {
my ($self, $rdata, $rindex, $rstore) = @_;
}
sub _iter_iterate {
- my ($self, $rdata, $rindex, $rstore) = @_;
+ my ($self, $rdata, $rindex, $rstore, $single) = @_;
if (++$$rindex < @$rdata) {
$$rstore = $rdata->[$$rindex] if $rstore;
+ $self->next_item($rdata->[$$rindex], $single, $rdata, $$rindex);
return 1;
}
+ else {
+ $self->next_item(undef, $single);
+ }
return;
}
"iterate_${plural}_reset" =>
[ _iter_reset_paged=>$self, \@data, $rindex, $rstore ],
"iterate_${plural}" =>
- [ _iter_iterate=>$self, \@data, $rindex, $rstore ],
+ [ _iter_iterate=>$self, \@data, $rindex, $rstore, $single ],
$single => [ _iter_item => $self, \@data, $rindex, $single, $plural ],
"if\u$plural" => scalar(@data),
"${single}_index" => [ _iter_index=>$self, $rindex ],
"iterate_${plural}_reset" =>
[ _iter_reset=>$self, $rdata, $rindex, $code, \$loaded, $nocache, $rstore ],
"iterate_${plural}" =>
- [ _iter_iterate=>$self, $rdata, $rindex, $rstore ],
+ [ _iter_iterate=>$self, $rdata, $rindex, $rstore, $single ],
$single =>
[ _iter_item=>$self, $rdata, $rindex, $single, $plural ],
"${single}_index" => [ _iter_index=>$self, $rindex ],
BSE::DB->query(bse_siteuserSeminarBookingsDetail => $self->{id});
}
+sub wishlist {
+ my $self = shift;
+ require Products;
+ return Products->getSpecial(userWishlist => $self->{id});
+}
+
+sub wishlist_order {
+ my $self = shift;
+ return BSE::DB->query(bse_userWishlistOrder => $self->{id});
+}
+
+sub product_in_wishlist {
+ my ($self, $product) = @_;
+
+ grep $_->{product_id} == $product->{id}, $self->wishlist_order;
+}
+
+sub add_to_wishlist {
+ my ($self, $product) = @_;
+
+ return
+ eval {
+ BSE::DB->run(bse_addToWishlist => $self->{id}, $product->{id}, time());
+ 1;
+ };
+}
+
+sub remove_from_wishlist {
+ my ($self, $product) = @_;
+
+ BSE::DB->run(bse_removeFromWishlist => $self->{id}, $product->{id});
+}
+
+sub _set_wishlist_order {
+ my ($self, $product_id, $display_order) = @_;
+
+ print STDERR "_set_wishlist_order($product_id, $display_order)\n";
+
+ BSE::DB->run(bse_userWishlistReorder => $display_order, $self->{id}, $product_id);
+}
+
+sub _find_in_wishlist {
+ my ($self, $product_id) = @_;
+
+ my @order = $self->wishlist_order;
+
+ my ($index) = grep $order[$_]{product_id} == $product_id, 0 .. $#order
+ or return;
+
+ return \@order, $index;
+}
+
+sub move_to_wishlist_top {
+ my ($self, $product) = @_;
+
+ my ($order, $move_index) = $self->_find_in_wishlist($product->{id})
+ or return;
+ $move_index > 0
+ or return; # nothing to do
+
+ my $top_order = $order->[0]{display_order};
+ for my $index (0 .. $move_index-1) {
+ $self->_set_wishlist_order($order->[$index]{product_id}, $order->[$index+1]{display_order});
+ }
+ $self->_set_wishlist_order($product->{id}, $top_order);
+}
+
+sub move_to_wishlist_bottom {
+ my ($self, $product) = @_;
+
+ my ($order, $move_index) = $self->_find_in_wishlist($product->{id})
+ or return;
+ $move_index < $#$order
+ or return; # nothing to do
+
+ my $bottom_order = $order->[-1]{display_order};
+ for my $index (reverse($move_index+1 .. $#$order)) {
+ $self->_set_wishlist_order($order->[$index]{product_id}, $order->[$index-1]{display_order});
+ }
+ $self->_set_wishlist_order($product->{id}, $bottom_order);
+}
+
+sub move_down_wishlist {
+ my ($self, $product) = @_;
+
+ my ($order, $index) = $self->_find_in_wishlist($product->{id})
+ or return;
+ $index < $#$order
+ or return; # nothing to do
+
+ $self->_set_wishlist_order($product->{id}, $order->[$index+1]{display_order});
+ $self->_set_wishlist_order($order->[$index+1]{product_id}, $order->[$index]{display_order});
+}
+
+sub move_up_wishlist {
+ my ($self, $product) = @_;
+
+ my ($order, $index) = $self->_find_in_wishlist($product->{id})
+ or return;
+ $index > 0
+ or return; # nothing to do
+
+ $self->_set_wishlist_order($product->{id}, $order->[$index-1]{display_order});
+ $self->_set_wishlist_order($order->[$index-1]{product_id}, $order->[$index]{display_order});
+}
+
1;
return $value;
}
+use vars '$AUTOLOAD';
+
sub AUTOLOAD {
- use vars '$AUTOLOAD';
(my $calledName = $AUTOLOAD) =~ s/^.*:://;
for ($calledName) {
/^set(.+)$/ && exists($_[0]->{lcfirst $1})
if ($@) {
my $msg = $@;
- $msg =~ /^ENOIMPL\b/
+ $msg =~ /\bENOIMPL\b/
and return $orig;
print STDERR "Eval error in perform: $msg\n";
$msg =~ s/([<>&])/"&#".ord($1).";"/ge;
-body { text-decoration: none}
+body { text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; }
a { text-decoration: none}
a:hover { text-decoration: underline; color: #FF7F00}
select { font-family: "MS Sans Serif", Verdana, sans-serif; font-size: 12px}
.cartunits { text-align: right }
.cartprice { text-align: right }
.searchresultimage { float: right }
+.sidewishlist { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; }
+.sidewishlisthead{ font-size: 13px; font-weight: bold; white-space: nowrap; text-align: left }
+.sidewishlistitem { font-size: 11px; padding-left: 10px; }
+.message { font-weight: bold; }
+.usermenu { background-color: #FF7F00; font-weight: bold; color: white; font-size: 12px; text-align: center; padding-bottom: 3px; padding-top: 3px; }
+.usermenu a { color: white; }
+.usermenu a:hover { color: #000000; text-decoration: none; }
+.usermenu a:before { content: " <" }
+.usermenu a:after { content: "> " }
+
--- /dev/null
+<div class="usermenu"><a href="<:script:>">Your Page</a> <a href="<:script:>?show_opts=1">Your Profile</a> <a href="<:script:>?_t=wishlist">Your Wishlist</a></div>
</tr>
</table>
</form>
+<:if Dynamic:><:if User:><:if InWishlist:>
+<p><a href="/cgi-bin/user.pl?a_wishlistdel=1&product_id=<:product id:>&r=<:url article |U:>">Remove from my wishlist</a></p>
+<:or InWishlist:>
+<p><a href="/cgi-bin/user.pl?a_wishlistadd=1&product_id=<:product id:>&r=<:url product |U:>">Add to my wishlist</a></p>
+<:eif InWishlist:>
+<:or User:><:eif User:><:or Dynamic:>
+<p><a href="/cgi-bin/user.pl?a_wishlistadd=1&product_id=<:product id:>&r=<:url product |U:>">Add to my wishlist</a></p>
+<:eif Dynamic:>
<:or Or:><br>
<br>
<table border="0" cellspacing="0" cellpadding="1" bgcolor="#CCCCCC">
--- /dev/null
+<:if Dynamic:><:if User:>
+<:if Wishlist:>
+<div class="sidewishlist">
+<div class="sidewishlisthead"><a href="/cgi-bin/user.pl?_t=wishlist">Your Wishlist</a></div>
+<:iterator begin wishlist:>
+<div class="sidewishlistitem"><a href="<:url wishlistentry:>"><:wishlistentry title:></a></div>
+<:iterator end wishlist:>
+</div>
+<:or Wishlist:><:eif Wishlist:>
+<:or User:><:eif User:><:or Dynamic:><:eif Dynamic:>
\ No newline at end of file
--- /dev/null
+<:wrap base.tmpl:>
+<:include include/usermenu.tmpl:>
+<p><:ifUser
+ name1:><:user name1:><:or:><:user userId:><:eif:>'s Wishlist</p>
+<:if Wishlist:>
+<table>
+<:iterator begin wishlist:>
+<tr>
+ <td><:dthumbimage wishlistentry search search,1:></td>
+ <td><a href="<:url wishlistentry:>"><:wishlistentry title:></a></td>
+ <td><a href="<:script:>?a_wishlistdel=1&product_id=<:wishlistentry id:>">Remove</a>
+ <:ifFirstWishlistentry:><:or:><a href="<:script:>?a_wishlistup=1&product_id=<:wishlistentry id:>">Up</a> <a href="<:script:>?a_wishlisttop=1&product_id=<:wishlistentry id:>">Top</a><:eif:>
+ <:ifLastWishlistentry:><:or:><a href="<:script:>?a_wishlistdown=1&product_id=<:wishlistentry id:>">Down</a> <a href="<:script:>?a_wishlistbottom=1&product_id=<:wishlistentry id:>">Bottom</a><:eif:>
+ </td>
+</tr>
+<:iterator end wishlist:>
+</table>
+<:or Wishlist:>
+<p>Your wishlist is empty.</p>
+<:eif Wishlist:>
\ No newline at end of file
--- /dev/null
+<:wrap base.tmpl:>
+<p><:ifWuser
+ name1:><:wuser name1:><:or:><:wuser userId:><:eif:>'s Wishlist</p>
+<:if Uwishlist:>
+<table>
+<:iterator begin uwishlist:>
+<tr>
+ <td><:dthumbimage uwishlistentry search search,1:></td>
+ <td><a href="<:url uwishlistentry:>"><:uwishlistentry title:></a></td>
+</tr>
+<:iterator end uwishlist:>
+</table>
+<:or Uwishlist:>
+<p><:ifWuser
+ name1:><:wuser name1:><:or:><:wuser userId:><:eif:>'s wishlist is empty.</p>
+<:eif Uwishlist:>
<:wrap base.tmpl:>
+<:include include/usermenu.tmpl:>
<p><font face="Verdana, Arial, Helvetica, sans-serif" size="2">Hello <:ifUser
name1:><:user name1:><:or:><:user userId:><:eif:>, this section contains your
personal account details. From here you can <:ifCfg subscriptions enabled:> manage
</table>
<br>
+<:if Message:><p class="message"><:message:></p> <:or Message:><:eif Message:>
<table width="100%" cellpadding="0" cellspacing="1">
- <:if Message:>
- <tr>
- <th align="center"><b><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><:message:></font></b></th>
- </tr>
- <:or Message:><:eif Message:>
<tr>
<th align="center" height="20"><font face="Verdana, Arial, Helvetica, sans-serif" size="3">Your
Account</font></th>
Column ends_at;date;NO;;
Column max_lapsed;int(11);NO;;
Index PRIMARY;1;[subscription_id;siteuser_id]
+Table bse_wishlist
+Column user_id;int(11);NO;;
+Column product_id;int(11);NO;;
+Column display_order;int(11);NO;;
+Index PRIMARY;1;[user_id;product_id]
Table email_blacklist
Column id;int(11);NO;NULL;auto_increment
Column email;varchar(127);NO;;