From 3711717a14307d5fb978ae361075b6e24c3b0dce Mon Sep 17 00:00:00 2001 From: Martin Samson Date: Fri, 25 Mar 2011 16:57:22 -0400 Subject: [PATCH] Some more work toward a mongodb-based cart --- controllers/CheckoutsController.php | 1 + controllers/OffersController.php | 20 ++++++++++---------- extensions/action/Controller.php | 10 +++++++++- models/{Cart.php => Carts.php} | 24 ++++++++++++++++++++---- models/Inventories.php | 15 +++++---------- models/Offers.php | 5 +++-- views/offers/admin_edit.html.php | 4 ++-- 7 files changed, 50 insertions(+), 29 deletions(-) rename models/{Cart.php => Carts.php} (70%) diff --git a/controllers/CheckoutsController.php b/controllers/CheckoutsController.php index c65fd30..d3d3ea3 100644 --- a/controllers/CheckoutsController.php +++ b/controllers/CheckoutsController.php @@ -42,6 +42,7 @@ public function cancel(){ return $this->redirect(array('Offers::index')); } public function confirm(){ + if(Cart::isEmpty()){ FlashMessage::set("Your cart is currently empty."); return $this->redirect("Offers::index"); diff --git a/controllers/OffersController.php b/controllers/OffersController.php index 2c01e26..31f7ffd 100644 --- a/controllers/OffersController.php +++ b/controllers/OffersController.php @@ -14,9 +14,7 @@ class OffersController extends \chowly\extensions\action\Controller{ public function index(){ $offers = Offers::current(); - - $venues = array(); $venues_id = array(); foreach($offers as $offer){ @@ -26,7 +24,7 @@ public function index(){ if(!empty($venues_id)){ $conditions = array('_id' => array_keys($venues_id)); Venues::meta('title', 'logo'); - $venues = Venue::find('list', compact('conditions','fields')); + $venues = Venues::find('list', compact('conditions','fields')); } return compact('offers', 'venues'); } @@ -54,18 +52,20 @@ public function view(){ public function buy(){ if(!$this->request->id){ FlashMessage::set("Missing data."); - return $this->redirect(array("Offers::index")); + return $this->redirect( array("Offers::index") ); } - if(Cart::contain($this->request->id)){ - return $this->redirect(array('Checkouts::confirm')); + + if($this->Cart->containItem($this->request->id)){ + return $this->redirect( array('Checkouts::confirm') ); } - $readonly = Cart::isReadOnly(); - if($readonly){ + + if($this->Cart->isReadOnly()){ FlashMessage::set("There is currently a transaction in progress on your cart."); return $this->redirect(array('Checkouts::confirm')); } + try{ - $reserved = Offers::reserve($this->request->id, Cart::id()); + $reserved = Offers::reserve($this->request->id, $this->Cart->_id); }catch(InventoryException $e){ FlashMessage::set("Sorry, The item could not be added to your cart"); return $this->redirect($this->request->referer()); @@ -73,7 +73,7 @@ public function buy(){ FlashMessage::set("Sorry, The item could not be added to your cart for the following reason: {$e->getMessage()}"); return $this->redirect($this->request->referer()); } - Cart::add($this->request->id, $reserved); + $this->Cart->addItem($this->request->id, $reserved); return $this->redirect(array('Checkouts::confirm')); } diff --git a/extensions/action/Controller.php b/extensions/action/Controller.php index 97c9708..e9d41c8 100644 --- a/extensions/action/Controller.php +++ b/extensions/action/Controller.php @@ -4,8 +4,12 @@ use \lithium\net\http\Router; use \lithium\template\View; +use chowly\models\Carts; + class Controller extends \lithium\action\Controller{ + protected $Cart; + protected function _init(){ parent::_init(); if($this->request->is('ssl') && !in_array($this->request->controller, array('checkouts','users'))){ @@ -16,7 +20,11 @@ protected function _init(){ ) ); } - + $this->Cart = Carts::first(array('_id' => session_id())); + if(!$this->Cart){ + $this->Cart = Carts::create(); + $this->Cart->_id = new \MongoId(); + } } protected function _getEmail(array $data, $template = null, $controller = null){ diff --git a/models/Cart.php b/models/Carts.php similarity index 70% rename from models/Cart.php rename to models/Carts.php index ba088b7..abefd38 100644 --- a/models/Cart.php +++ b/models/Carts.php @@ -3,6 +3,10 @@ class Carts extends \lithium\data\Model{ + protected $_schema = array( + '_id' => array('type'=>'id'), + 'items' => array('type'=>'id', 'array' => true) + ); public function endTransaction(){ $command = $entity->_transaction('transaction', 'default'); $result = static::connection()->connection->command($command); @@ -14,6 +18,13 @@ public function startTransaction($entity){ return !isset($result['errmsg']); } + /** + * Wraps findAndModify mongodb command for transaction status handling. + * @param Model $entity + * @param var $from + * @param var $to + * @return var The mongodb command structure. + */ private function _transaction($entity, $from = 'default', $to = 'transaction'){ debug($entity);die; return array( @@ -32,10 +43,9 @@ private function _transaction($entity, $from = 'default', $to = 'transaction'){ /** * Add a cart item - * @param var $offer_id * @return bool */ - public function add($entity, $offer_id, $inventory_id){ + public function addItem($entity, $offer_id, $inventory_id){ $conditions = array('_id' => $entity->_id, 'state' => 'default'); $data = array('$addToSet' => array('items' => $offer_id)); $options = array('multiple' => false, 'safe' => true); @@ -46,17 +56,23 @@ public static function isEmpty($entity){ return empty($entity->items); } - public function clear($entity){ + public function clearItems($entity){ $conditions = array('_id' => $entity->_id, 'state' => 'default'); $data = array('$set' => array('items' => array())); $options = array('multiple' => false, 'safe' => true); return $entity->update($data, $conditions, $options); } - public function remove($entity, $offer_id){ + public function removeItem($entity, $offer_id){ $conditions = array('_id' => $entity->_id, 'state' => 'default'); $data = array('$pull' => array('items' => $offer_id)); $options = array('safe'=>true); return $entity->update($data, $conditions, $options); } + public function containItem($entity, $offer_id){ + return $entity->items->first(function($i) use ($offer_id) { return (string) $i->_id == $offer_id; }); + } + public function isReadOnly($entity){ + return ($entity->state == "default"); + } } ?> \ No newline at end of file diff --git a/models/Inventories.php b/models/Inventories.php index 60246e8..8c1a7ec 100644 --- a/models/Inventories.php +++ b/models/Inventories.php @@ -30,9 +30,8 @@ public static function releaseExpired(){ return static::update( $data , $conditions); } public static function release($customer_id, $offer_id){ - $self = static::_object(); $command = array( - 'findAndModify' => $self->_meta['source'], + 'findAndModify' => static::meta('source'), 'query' => array( 'offer_id' => new \MongoId($offer_id), 'state' => 'reserved' @@ -64,10 +63,9 @@ public static function release($customer_id, $offer_id){ * @param var $offer_id * @todo Add indexes to inventory */ - public static function reserve($customer_id, $offer_id){ - $self = static::_object(); + public static function reserve($offer_id, $customer_id){ $command = array( - 'findAndModify' => $self->_meta['source'], + 'findAndModify' => static::meta('source'), 'query' => array( 'offer_id' => new \MongoId($offer_id), 'state' => 'available' @@ -80,7 +78,6 @@ public static function reserve($customer_id, $offer_id){ ) ) ); - $result = static::connection()->connection->command($command); if(isset($result['errmsg'])){ @@ -93,9 +90,8 @@ public static function reserve($customer_id, $offer_id){ return $inventory; } public static function secure($inventory_id){ - $self = static::_object(); $command = array( - 'findAndModify' => $self->_meta['source'], + 'findAndModify' => static::meta('source'), 'query' => array( '_id' => $inventory_id, ), @@ -113,9 +109,8 @@ public static function secure($inventory_id){ return true; } public static function purchase($purchase_id, $inventory_id){ - $self = static::_object(); $command = array( - 'findAndModify' => $self->_meta['source'], + 'findAndModify' => static::meta('source'), 'query' => array( '_id' => new \MongoId($inventory_id), ), diff --git a/models/Offers.php b/models/Offers.php index 1c660dd..add91ca 100644 --- a/models/Offers.php +++ b/models/Offers.php @@ -100,7 +100,7 @@ public static function releaseInventory($offer_id){ * @param var $customer_id * @param var $offer_id */ - public static function reserve($offer_id,$customer_id){ + public static function reserve($offer_id, $cart_id){ $date = new \MongoDate(); $conditions = array( 'starts' => array('$lt' => $date), @@ -114,8 +114,9 @@ public static function reserve($offer_id,$customer_id){ throw new OfferException("Offer not found."); } + try{ - $inventory = Inventories::reserve($customer_id,$offer_id); + $inventory = Inventories::reserve($offer_id, $cart_id); $offer->availability--; if($offer->availability <= 0){ $offer->availability = 0; diff --git a/views/offers/admin_edit.html.php b/views/offers/admin_edit.html.php index 20b157a..c17c18d 100644 --- a/views/offers/admin_edit.html.php +++ b/views/offers/admin_edit.html.php @@ -1,6 +1,6 @@ starts->sec ?: time(); -$ends = $offer->starts->sec ?: time() + 60 * 60 * 24 * 30; +$starts = ($offer->_id)? $offer->starts->sec : time(); +$ends = ($offer->_id)? $offer->ends->sec : time() + 60 * 60 * 24 * 30; ?>
_id):?>