Leo Lapworth <[EMAIL PROTECTED]> writes:
> Hi,
>
> I was just about to write YASB (Yet Another Shopping Basket)
> and I thought, hang on, there's this CPAN thing and maybe
> I could get one from there.
>
> But to my dismay I couldn't find anything!
>
> - So before I start writing a module I thought
> I'd see what everyone want's out of a shopping basket.
>
> I think it will be heavily based on using Apache::Session,
> any other ideas / comments are very welcome.
>
> Thanks
>
> Leo
>
> ----------------------------------------------------------
> Shopping::Basket Proposal Version 0.000000001
> ----------------------------------------------------------
> Aim:
> To create a module which can be used to easily implement
> shopping baskets with lots of flexibility.
>
> Requirements of this module:
> - Generate UID
> - Store item X in Basket Y for user UID
> - Store user details
> (what happens if this is across multiple sites ?)
> - Password option
> - Option to validate basket item on retrieval (don't think
> this needs to be in the module)
>
> Functions which need to be able to be overridden (eventually)
> - Function to generate UID (might need to integrate to current system)
> - How to store the basket
> - DBI
> - File
> - anything else ?
> - Password encryption
> - standard 'salt' and 'pepper'
> - other
> - Validate of item (see requirements above)
I think that you should try and separate the shopping basket and how
it is made persistent. The system I'm using here has:
Basket -- contains rows, provides methods for manipulating said
rows. Also contains a reference to a vendor specific
catalogue class.
Basket::Row -- Contained by Basket. Contains a StockItem and has a
quantity. Provides the same interface as StockItem by
forwarding any unknown methods to the contained item. (Note
that, because we're vendor neutral here I can't be sure what
methods the StockItem will have. I may end up making this a
base class along with a factory for making vendor specific
Basket rows, but it's unlikely)
Item & StockItem -- The vendor I'm working with at the moment sells
clothes, so I need some way to draw a distinction between
the invariant parts of an Item (501s, say) and the actual
thing that is stocked (Blue, stonewashed 501s, with a 48"
waist and a 32" inside leg), hence Item and StockItem. If I
were selling DVDs and Video Tapes, say, then Item would be
details about the film, and StockItem would carry details
about the stuff specific to the format.
Note that StockItem and Basket::Row have the same interface,
with StockItem returning 'undef' for the quantity method.
StockItem also has the same interface as Item. I'm unsure as
to whether to make Item respond to StockItem methods by
returning 'undef' on a query and throwing an exception when
a 'set' is attempted
About the only methods nailed down here are 'id', 'base_id',
'stock_code' and 'name'.
I need to write an Item/StockItem template class which can
take a list of base attributes and a list of 'variant'
attributes and create an appropriate pair of Item/StockItem
classes. The same list, could in theory be used to create a
basic Catalogue class as well.
Catalogue -- Used by the basket and other parts of the website to find
Items and StockItems. This is really just an abstract base
class since each vendor's catalogue will need to know stuff
about the specific catalogue.
At the moment, I have a vendor specific PerlFixupHandler that handles
(re)creating the current session's basket and all that other session
stuff.
The Basket/Catalogue/Item/StockItem set knows *nothing* about
persistence of the basket (they have to know about the persistence of
the Item/StockItem objects, but Item and StockItem in their turn don't
know that they are persistent, nor how they are persistent, the
Catalogue is the thing that knows that). Nothing here knows about
Apache either. All of which makes unit testing relatively easy to do.
Which is a good thing.
I'm currently using this lot via the Template Toolkit. Each individual
template is passed the current basket and an Apache::Request (though I
may be about to replace Apache::Request with a 'params' hash as a
cunning ploy to prevent my page designers from screwing stuff up
completely.) Any clever programmatic stuff gets handled in template
specific plugins.
Hmm... You know, I write this stuff down to explain it to you lot and
all of a sudden I realise a bunch of stuff about what I need to do to
improve the design. Thanks all.
--
Piers