| Handel documentation | Contained in the Handel distribution. |
Catalyst::Helper::Controller::Handel::Cart - Helper for Handel::Cart Controllers
script/create.pl controller <newclass> Handel::Cart [<modelclass> <checkoutcontroller>]
script/create.pl controller Cart Handel::Cart Cart Checkout
A Helper for creating controllers based on Handel::Cart objects. If no modelclass is specified, ::M::Cart is assumed.
Both the modelclass and checkoutcontroller arguments try to do the right thing with the names given to them.
For example, you can pass the shortened class name without the MyApp::M/C, or pass the fully qualified package name:
MyApp::M::CartModel
MyApp::Model::CartModel
CartModel
In all three cases everything before M{odel)|C(ontroller) will be stripped and the class CartModel will be used.
The code generated by this helper requires FormValidator::Simple and YAML to be installed to operate.
Makes a Handel::Cart Controller class and template files for you.
Makes a Handel::Cart Controller test for you.
Christopher H. Laco
CPAN ID: CLACO
claco@chrislaco.com
http://today.icantfocus.com/blog/
| Handel documentation | Contained in the Handel distribution. |
# $Id$ ## no critic (ProhibitCaptureWithoutTest) package Catalyst::Helper::Controller::Handel::Cart; use strict; use warnings; BEGIN { use Catalyst 5.7001; use Catalyst::Utils; use Path::Class; };
sub mk_compclass { my ($self, $helper, $model, $checkout) = @_; my $file = $helper->{'file'}; my $dir = dir($helper->{'base'}, 'root', $helper->{'uri'}); $model ||= 'Cart'; $checkout ||= 'Checkout'; $model =~ /^(.*::M(odel)?::)?(.*)$/i; $model = $3 ? $3 : 'Cart'; $helper->{'model'} = $model; $checkout =~ /^(.*::C(ontroller)?::)?(.*)$/i; my $couri = $3 ? lc($3) : 'checkout'; $couri =~ s/::/\//g; $helper->{'couri'} = $couri; $helper->{'action'} = Catalyst::Utils::class2prefix($helper->{'class'}); $helper->mk_dir($dir); $helper->render_file('controller', $file); $helper->render_file('default', file($dir, 'default')); $helper->render_file('list', file($dir, 'list')); $helper->render_file('errors', file($dir, 'errors')); $helper->render_file('profiles', file($dir, 'profiles.yml')); $helper->render_file('messages', file($dir, 'messages.yml')); $helper->render_file('products', file($helper->{'base'}, 'root', 'static', 'products.htm')); return 1; };
sub mk_comptest { my ($self, $helper) = @_; my $test = $helper->{'test'}; $helper->render_file('test', $test); return 1; };
1; __DATA__
sub COMPONENT { my $self = shift->NEXT::COMPONENT(@_); $self->{'validator'} = FormValidator::Simple->new; $self->{'validator'}->set_messages( $_[0]->path_to('root', '[% action %]', 'messages.yml') ); $self->{'profiles'} = YAML::LoadFile($_[0]->path_to('root', '[% action %]', 'profiles.yml')); return $self; };
sub default : Private { my ($self, $c) = @_; $c->stash->{'template'} = '[% action %]/default'; if ($c->sessionid && $c->session->{'shopper'}) { if (my $cart = $c->forward('load')) { $c->stash->{'cart'} = $cart; $c->stash->{'items'} = $cart->items; }; }; return; };
sub add : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { my $cart = $c->forward('create'); $cart->add($c->req->params); }; $c->res->redirect($c->uri_for('[% uri %]/')); };
sub clear : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if (my $cart = $c->forward('load')) { $cart->clear; }; }; $c->res->redirect($c->uri_for('[% uri %]/')); };
sub create : Private { my ($self, $c) = @_; if (!$c->session->{'shopper'}) { $c->session->{'shopper'} = $c->model('[% model %]')->storage->new_uuid; }; if (my $cart = $c->forward('load')) { return $cart; } else { return $c->model('[% model %]')->create({ shopper => $c->session->{'shopper'}, type => CART_TYPE_TEMP }); }; return; };
sub delete : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if ($c->forward('validate')) { if (my $cart = $c->forward('load')) { $cart->delete({ id => $c->req->params->{'id'} }); $c->res->redirect($c->uri_for('[% uri %]/')); }; } else { $c->forward('default'); }; } else { $c->res->redirect($c->uri_for('[% uri %]/')); }; return; };
sub destroy : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if ($c->forward('validate')) { my $cart = $c->model('[% model %]')->search({ id => $c->req->params->{'id'}, shopper => $c->session->{'shopper'}, type => CART_TYPE_SAVED })->first; if ($cart) { $cart->destroy; } else { warn "not cart"; }; $c->res->redirect($c->uri_for('[% uri %]/list/')); } else { $c->forward('list'); }; } else { $c->res->redirect($c->uri_for('[% uri %]/')); }; return; };
sub list : Local { my ($self, $c) = @_; $c->stash->{'template'} = '[% action %]/list'; if ($c->sessionid && $c->session->{'shopper'}) { my $carts = $c->model('[% model %]')->search({ shopper => $c->session->{'shopper'}, type => CART_TYPE_SAVED }); $c->stash->{'carts'} = $carts; }; return; };
sub load : Private { my ($self, $c) = @_; if ($c->sessionid && $c->session->{'shopper'}) { return $c->model('[% model %]')->search({ shopper => $c->session->{'shopper'}, type => CART_TYPE_TEMP })->first; }; return; };
sub restore : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if ($c->forward('validate')) { if (my $cart = $c->forward('create')) { $cart->restore({ id => $c->req->param('id'), shopper => $c->session->{'shopper'}, type => CART_TYPE_SAVED }, $c->req->param('mode') || CART_MODE_APPEND); $c->res->redirect($c->uri_for('[% uri %]/')); }; } else { $c->forward('list'); }; } else { $c->res->redirect($c->uri_for('[% uri %]/')); }; return; };
sub save : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if ($c->forward('validate')) { if (my $cart = $c->forward('load')) { $cart->name($c->req->param('name') || 'My Cart'); $cart->save; $c->res->redirect($c->uri_for('[% uri %]/list/')); }; } else { $c->forward('default'); }; } else { $c->res->redirect($c->uri_for('[% uri %]/')); }; return; };
sub update : Local { my ($self, $c) = @_; if ($c->req->method eq 'POST') { if ($c->forward('validate')) { if (my $cart = $c->forward('load')) { my $item = $cart->items({ id => $c->req->param('id') })->first; if ($item) { $item->quantity($c->req->param('quantity')); }; $c->res->redirect($c->uri_for('[% uri %]/')); }; } else { $c->forward('default'); }; } else { $c->res->redirect($c->uri_for('[% uri %]/')); }; return; };
sub validate : Private { my ($self, $c) = @_; $self->{'validator'}->results->clear; my $results = $self->{'validator'}->check( $c->req, $self->{'profiles'}->{$c->action} ); if ($results->success) { return $results; } else { $c->stash->{'errors'} = $results->messages($c->action); }; return; };
1; __test__ use Test::More tests => 3; use strict; use warnings; use_ok('Catalyst::Test', '[% app %]'); use_ok('[% class %]'); ok(request('[% uri %]')->is_success, 'Request should succeed'); __default__ [% TAGS [- -] -%] [% USE HTML %] <h1>Your Shopping Cart</h1> [% INCLUDE [- action -]/errors %] [% IF items.count %] <table border="0" cellpadding="3" cellspacing="5"> <tr> <th align="left">SKU</th> <th align="left">Description</th> <th align="right">Price</th> <th align="center">Quantity</th> <th align="right">Total</th> <th colspan="2"></th> </tr> [% WHILE (item = items.next) %] <tr> <form action="[% c.uri_for('[- uri -]/update/') %]" method="post"> <input type="hidden" name="id" value="[% HTML.escape(item.id) %]"> <td align="left">[% HTML.escape(item.sku) %]</td> <td align="left">[% HTML.escape(item.description) %]</td> <td align="right">[% HTML.escape(item.price.as_string('FMT_SYMBOL')) %]</td> <td align="center"><input style="text-align: center;" type="text" size="3" name="quantity" value="[% HTML.escape(item.quantity) %]"></td> <td align="right">[% HTML.escape(item.total.as_string('FMT_SYMBOL')) %]</td> <td><input type="submit" value="Update"></td> </form> <form action="[% c.uri_for('[- uri -]/delete/') %]" method="POST"> <input type="hidden" name="id" value="[% HTML.escape(item.id) %]"> <td> <input type="submit" value="Delete"> </td> </form> </tr> [% END %] <tr> <td colspan="7" height="20"></td> </tr> <tr> <th colspan="4" align="right">Subtotal:</th> <td align="right">[% HTML.escape(cart.subtotal.as_string('FMT_SYMBOL')) %]</td> <td colspan="2"></td> </tr> <tr> <td colspan="7" align="right"> <form action="[% c.uri_for('[- uri -]/clear/') %]" method="POST"> <input type="submit" value="Empty Cart"> </form> <form action="[% c.uri_for('/[- couri -]/') %]" method="POST"> <input type="submit" value="Checkout"> </form> </td> </tr> </table> <form action="[% c.uri_for('[- uri -]/save/') %]" method="POST"> <input type="text" name="name"> <input type="submit" value="Save Cart"> </form> [% ELSE %] <p>Your shopping cart is empty.</p> [% END %] __list__ [% TAGS [- -] -%] [% USE HTML %] <h1>Your Saved Shopping Carts</h1> [% INCLUDE [- action -]/errors %] [% IF carts.count %] <table border="0" cellpadding="3" cellspacing="5"> <tr> <th align="left">Name</th> <th align="right">Restore Mode</th> <th></th> </tr> [% WHILE (cart = carts.next) %] <tr> <td align="left" valign="top">[% HTML.escape(cart.name) %]</td> <td> <form action="[% c.uri_for('[- uri -]/restore/') %]" method="POST"> <input type="hidden" name="id" value="[% HTML.escape(cart.id) %]"> <select name="mode"> [% USE hc = Handel.Constants %] <option value="[% HTML.escape(hc.CART_MODE_APPEND) %]">Append</option> <option value="[% HTML.escape(hc.CART_MODE_MERGE) %]">Merge</option> <option value="[% HTML.escape(hc.CART_MODE_REPLACE) %]">Replace</option> </select> <input type="submit" value="Restore Cart"> </form> </td> <td> <form action="[% c.uri_for('[- uri -]/destroy/') %]" method="POST"> <input type="hidden" name="id" value="[% HTML.escape(cart.id) %]"> <input type="submit" value="Delete"> </form> </td> </tr> [% END %] </table> [% ELSE %] <p>You have no saved shopping carts.</p> [% END %] __errors__ [% TAGS [- -] -%] [% IF errors %] <ul class="errors"> [% FOREACH error IN errors %] <li>[% HTML.escape(error) %]</li> [% END %] </ul> [% END %] __messages__ [% action %]/save: name: NOT_BLANK: The name field cannot be empty. LENGTH: The name field must be between 1 and 50 characters. [% action %]/update: id: REGEX: The id field is in the wrong format. quantity: NOT_BLANK: The quantity field cannot be empty. UINT: The quantity field must be a positive number. [% action %]/delete: id: REGEX: The id field is in the wrong format. [% action %]/destroy: id: REGEX: The id field is in the wrong format. [% action %]/restore: id: REGEX: The id field is in the wrong format. mode: BETWEEN: The mode field must be between 1 and 3. __profiles__ [% action %]/save: - name - [ [NOT_BLANK], [LENGTH, 1, 50] ] [% action %]/delete: - id - - - REGEX - !!perl/regexp (?i-xsm:^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$) [% action %]/destroy: - id - - - REGEX - !!perl/regexp (?i-xsm:^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$) [% action %]/update: - id - - - REGEX - !!perl/regexp (?i-xsm:^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$) - quantity - [ [NOT_BLANK], [UINT] ] [% action %]/restore: - id - - - REGEX - !!perl/regexp (?i-xsm:^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$) - mode - [ [BETWEEN, 1, 3] ] __products__ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Nifty New Products</title> <base href="http://localhost:3000/" /> </head> <body> <h1>Nifty New Products</h1> <p> <a href="[% uri %]/">View Cart</a> | </p> <h2>Mendlefarg 3000</h2> <p> It slices. It dices. It MVCs! </p> <form action="[% uri %]/add/" method="POST"> <p> <input type="hidden" name="sku" value="MFG3000" /> <input type="hidden" name="description" value="Mendlefarg 3000" /> <input type="hidden" name="price" value="19.95" /> <input type="text" name="quantity" value="1" size="3" /> <input type="submit" value="Add To Cart" /> </p> </form> <h2>Flimblebot 98</h2> <p> The most advanced flimble-based bot response software ever! </p> <form action="[% uri %]/add/" method="POST"> <p> <input type="hidden" name="sku" value="FB98" /> <input type="hidden" name="description" value="Flimblebot 98 Single-User" /> <input type="hidden" name="price" value="12.34" /> <input type="text" name="quantity" value="1" size="3" /> <input type="submit" value="Add To Cart" /> </p> </form> </body> </html> __END__