[wellwell-devel] [wellwell] Add module for database cart.
Stefan Hornburg
wellwell-devel at rt.icdevgroup.org
Thu Jul 1 09:08:53 UTC 2010
commit b9453d1dadb20904635a2d0c7dcfdbc3dcbc86f9
Author: Stefan Hornburg (Racke) <racke at linuxia.de>
Date: Thu Jul 1 11:05:48 2010 +0200
Add module for database cart.
lib/WellWell/DatabaseCart.pm | 268 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 268 insertions(+), 0 deletions(-)
---
diff --git a/lib/WellWell/DatabaseCart.pm b/lib/WellWell/DatabaseCart.pm
new file mode 100644
index 0000000..2717dd7
--- /dev/null
+++ b/lib/WellWell/DatabaseCart.pm
@@ -0,0 +1,268 @@
+# WellWell::DatabaseCart - WellWell database cart routines
+#
+# Copyright (C) 2010 Stefan Hornburg (Racke) <racke at linuxia.de>.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+package WellWell::DatabaseCart;
+
+use strict;
+use warnings;
+
+use Vend::Config;
+use Vend::Data;
+use Vend::Tags;
+
+# DatabaseCart directive
+Vend::Config::parse_directive('DatabaseCart', 'DatabaseCart database_cart');
+
+Vend::Config::parse_tag('UserTag', 'database_cart_restore MapRoutine WellWell::DatabaseCart::cart_restore');
+Vend::Config::parse_tag('UserTag', 'database_cart_clear MapRoutine WellWell::DatabaseCart::cart_clear');
+Vend::Config::parse_tag('UserTag', 'database_cart_compare MapRoutine WellWell::DatabaseCart::cart_compare');
+
+# Cart hook
+sub cart_hook {
+ my ($op, $cartname, $item, $changes) = @_;
+ my ($cart);
+
+ if ($cartname eq 'main') {
+ $cartname = $Vend::Cfg->{DatabaseCart};
+ }
+
+ $cart = get_cart_by_name($cartname, 'cart', $Vend::Session->{username}, 1);
+
+ if ($op eq 'add') {
+ $cart->add_item($item);
+ }
+ elsif ($op eq 'delete') {
+ $cart->delete_item($item);
+ }
+ elsif ($op eq 'modify' || $op eq 'combine') {
+ $cart->modify_item($item, $changes);
+ }
+}
+
+# Restoring database cart into session cart
+sub cart_restore {
+ my $cart;
+
+ $cart = get_cart_by_name($Vend::Cfg->{DatabaseCart}, 'cart', $Vend::Session->{username});
+
+ if ($cart) {
+ $cart->restore();
+ }
+}
+
+# Clearing database cart
+sub cart_clear {
+ my $cart;
+
+ $cart = get_cart_by_name($Vend::Cfg->{DatabaseCart}, 'cart', $Vend::Session->{username});
+
+ if ($cart) {
+ $cart->clear();
+ }
+}
+
+# Comparing database cart with session cart
+sub cart_compare {
+ my ($cart, $cart_products, $session_products, $cart_item, $session_item, $max_count, @diff);
+
+ $cart = get_cart_by_name($Vend::Cfg->{DatabaseCart}, 'cart', $Vend::Session->{username});
+
+ $cart_products = $cart->item_list();
+ $session_products = $Vend::Items;
+
+ if (@$cart_products > @$session_products) {
+ $max_count = @$cart_products;
+ }
+ else {
+ $max_count = @$session_products;
+ }
+
+ for (my $i = 0; $i < $max_count; $i++) {
+ unless ($cart_item = $cart_products->[$i]) {
+ push (@diff, "Cart item $i missing.");
+ next;
+ }
+
+ unless ($session_item = $session_products->[$i]) {
+ push (@diff, "Session item $i missing.");
+ next;
+ }
+
+ if ($cart_item->{code} ne $session_item->{code}) {
+ push (@diff, "SKU differs for item $i: $cart_item->{code} vs $session_item->{code}.");
+ }
+
+ if ($cart_item->{quantity} ne $session_item->{quantity}) {
+ push (@diff, "Quantity differs for item $i: $cart_item->{quantity} vs $session_item->{quantity}.");
+ }
+ }
+
+ if (@diff) {
+ return \@diff;
+ }
+}
+
+# Cart object instantiation
+sub get_cart_by_name {
+ my ($name, $type, $uid, $create) = @_;
+ my ($db_carts, $set, $code);
+
+ $db_carts = database_exists_ref('carts');
+
+ $set = $db_carts->query(q{select code from carts where name = '%s' and uid = %s},
+ $name, $uid);
+
+ if (@$set) {
+ $code = $set->[0]->[0];
+ }
+ elsif ($create) {
+ $code = $db_carts->autosequence();
+
+ $code = $db_carts->set_slice($code, uid => $uid,
+ created => Vend::Tags->time({format => '%s'}),
+ type => $type,
+ name => $name);
+ }
+
+ if ($code) {
+ return new WellWell::DatabaseCart($code);
+ }
+
+ return;
+}
+
+# constructor of DatabaseCart object
+sub new {
+ my ($class, $code) = @_;
+ my ($self);
+
+ $self->{code} = $code;
+
+ bless $self;
+
+ # set up database accessors
+ $self->{db_carts} = database_exists_ref('carts');
+ $self->{db_products} = database_exists_ref('cart_products');
+
+ return $self;
+}
+
+sub add_item {
+ my ($self, $item) = @_;
+
+ $self->{db_products}->set_slice([$self->{code}, $item->{code}], quantity => $item->{quantity},
+ position => 0);
+ $self->touch();
+}
+
+sub delete_item {
+ my ($self, $item) = @_;
+
+ $self->{db_products}->delete_record([$self->{code}, $item->{code}]);
+
+ $self->touch();
+}
+
+sub modify_item {
+ my ($self, $item, $changes) = @_;
+
+ if ($changes->{quantity}) {
+ $self->{db_products}->set_slice([$self->{code}, $item->{code}], quantity => $changes->{quantity});
+ }
+
+ $self->touch();
+}
+
+# update cart timestamp
+sub touch {
+ my ($self) = @_;
+ my ($last_modified);
+
+ $last_modified = Vend::Tags->time({format => '%s'});
+
+ $self->{db_carts}->set_field($self->{code}, 'last_modified', $last_modified);
+}
+
+# clear cart (usually after order has been finished)
+sub clear {
+ my ($self) = @_;
+
+ $self->{db_products}->query(qq{delete from cart_products where cart = $self->{code}});
+
+ $self->touch();
+}
+
+# restore cart from database into session cart
+sub restore {
+ my ($self, $set, $item) = @_;
+
+ # empty session cart first
+ @$Vend::Items = ();
+
+ $set = $self->{db_carts}->query(qq{select sku,quantity from cart_products where cart = $self->{code}});
+
+ for (@$set) {
+ $item = WellWell::Cart::cart_item(@$_);
+ push (@$Vend::Items, $item);
+ }
+
+ return;
+}
+
+# return structure similar to session cart
+sub item_list {
+ my ($self, $complete) = @_;
+ my ($set, @list);
+
+ $set = $self->{db_products}->query(qq{select sku,quantity from cart_products where cart = $self->{code}});
+
+ for (@$set) {
+ my $item;
+
+ if ($complete) {
+ $item = WellWell::Cart::cart_item(@$_);
+ }
+ else {
+ $item = {code => $_->[0], quantity => $_->[1]};
+ }
+
+ push(@list, $item);
+ }
+
+ return \@list;
+}
+
+package Vend::Config;
+
+sub parse_database_cart {
+ my ($item, $settings) = @_;
+
+ # parse routine is called once per catalog, regardless of configuration
+ # directives
+ return {} unless $settings;
+
+ $C->{$item} = $settings;
+
+ # add to cart hook
+ push(@{$C->{Hook}->{cart}}, \&WellWell::DatabaseCart::cart_hook);
+
+ return $C->{$item};
+}
+
+1;
More information about the wellwell-devel
mailing list