E-commerce con Zend Framework: Clase Cart

Por zsamer en Febrero 23, 2009

En el capitulo anterior "E-commerce con Zend Framework: Factoría" hablamos sobre el componente/clase Factoría que nos resolvía el problema de obtener el objeto persistente Cart (carro de compras) desde una sesión, implementado con Zend_Sesion, y todo este proceso implementando el conocido patrón de diseño Factory.

Hoy vamos a mostrar las clases Core_Store_Cart_Abstract y Core_Store_Cart_Abstract_StandardCart.

CartAbstract es una clase abstracta que determina que comportamiento tiene que implementar las clases que las extiendan, nos dice el "que hacen nuestras sub-clases" no el como lo hacen ya que esto dependerá de cada una, además nos entrega una estructura, molde o esqueleto a seguir, es un tipo. También es correcto haber hecho esto usando una interfaz, pero en nuestro ejemplo tenemos implementado un método en común save(), por lo que lo haremos con una clase abstracta.

CartAbstract nos presenta una colección de método, que debemos implementar estos métodos serán el comportamiento de la clase Concreta Cart, son las acciones que debe de realizar en determinados momentos.

Clase Core_Store_Cart_Abstract

PHP:
  1. <?php
  2. Zend_Loader::loadClass('Core_Store_Cart_Item_Collection');
  3.  
  4. abstract class Core_Store_Cart_Abstract
  5. {
  6.     protected $_contents = null;
  7.  
  8.     protected $_total = 0;
  9.  
  10.     protected $_weight = 0;
  11.    
  12.     protected $_totalTax = 0;
  13.    
  14.     protected $_taxValue = 19;
  15.  
  16.     protected function __construct()
  17.     {
  18.         $this->reset();
  19.     }
  20.  
  21.     abstract public function reset($reset_database = false);
  22.  
  23.     abstract public function addCart(Core_Store_Cart_Item $item);
  24.  
  25.     abstract public function updateQuantity($products_id, $quantity);
  26.  
  27.     abstract public function cleanup();
  28.  
  29.     abstract public function countContents();
  30.  
  31.     abstract public function getQuantity($products_id);
  32.  
  33.     abstract public function inCart($products_id);
  34.  
  35.     abstract public function remove($products_id);
  36.  
  37.     abstract public function removeAll();
  38.  
  39.     abstract public function getProducts();
  40.  
  41.     abstract public function getContents();
  42.  
  43.     abstract public function getTotal();
  44.  
  45.     abstract public function getWeight();
  46.  
  47.     public function save()
  48.     {
  49.         try {
  50.             $sessionData = Zend_Registry::get('coreSession');
  51.  
  52.             if (isset($sessionData->cart)) {
  53.                 unset($sessionData->cart);
  54.             }
  55.  
  56.             $sessionData->cart = $this;
  57.  
  58.         } catch (Exception $e) {
  59.             print "Message: " . $e->getMessage() . "\n";
  60.         }
  61.     }
  62. }

Clase Core_Store_Cart_Abstract_StandardCart

PHP:
  1. <?php
  2. Zend_Loader::loadClass('Core_Store_Cart_Abstract');
  3.  
  4. class Core_Store_Cart_Abstract_StandardFinal extends Core_Store_Cart_Abstract
  5. {
  6.     static private $_instance = null;
  7.  
  8.     protected function __construct()
  9.     {
  10.         parent::__construct();
  11.     }
  12.  
  13.     static public function getInstance()
  14.     {
  15.         if (!self::$_instance instanceof self) {
  16.             self::$_instance = new self();
  17.         }
  18.  
  19.         return self::$_instance;
  20.     }
  21.  
  22.     public function reset($resetDatabase = false)
  23.     {
  24.         $this->_contents = new Core_Store_Cart_Item_Collection();
  25.         $this->_total = 0;
  26.         $this->_weight = 0;
  27.  
  28.         $sessionData = Zend_Registry::getInstance()->get('coreSession');
  29.  
  30.         if (isset($sessionData->cartId)) {
  31.             unset($sessionData->cartId);
  32.         }
  33.     }
  34.  
  35.     public function addCart(Core_Store_Cart_Item $item)
  36.     {
  37.         if ($this->inCart($item->getId())) {
  38.             $this->updateQuantity($item->getId(), $item->getQuantity());
  39.         } else {
  40.             $this->_contents->addItem($item->getId(), $item);
  41.             $this->cleanup();
  42.         }
  43.     }
  44.  
  45.     public function updateQuantity($productId, $quantity, $qtyFromPost = false)
  46.     {
  47.         $item = $this->findProducto($productId);
  48.  
  49.         if ($item !== null) {
  50.             $quantity = ($qtyFromPost === true)? $quantity: $item->getQuantity() + $quantity;
  51.             $item->setQuantity($quantity);
  52.                
  53.             $this->cleanup();
  54.         }
  55.     }
  56.  
  57.     public function cleanup()
  58.     {
  59.         foreach( $this->_contents->getIterator() as $key => $value ) {
  60.             if ( $this->getQuantity($key) <1 ) {
  61.                 $this->_contents->detach($key);
  62.             }
  63.         }
  64.     }
  65.  
  66.     public function countContents()
  67.     {
  68.         return (int)$this->_contents->count();
  69.     }
  70.  
  71.     public function getQuantity($productId)
  72.     {
  73.         if ( $this->inCart($productId) ) {
  74.             if(($item = $this->_contents->getItem($productId)) && ($item->getQuantity()> 0) ){
  75.                 return $item->getQuantity();
  76.             }
  77.             return 0;
  78.         } else {
  79.             return 0;
  80.         }
  81.     }
  82.  
  83.     public function inCart($productId)
  84.     {
  85.         return $this->_contents->offsetExists($productId);
  86.     }
  87.  
  88.     public function has($productId)
  89.     {
  90.         return $this->inCart($productId);
  91.     }
  92.    
  93.     private function findProducto($productoId) {
  94.         if($this->inCart($productoId)){
  95.             return $this->_contents->getItem($productoId);
  96.         }
  97.         return null;
  98.     }
  99.  
  100.     public function remove($productId)
  101.     {
  102.         $product = $this->findProducto($productId);
  103.         if ($product !== null) {
  104.             $this->_contents->detach($product);
  105.         }
  106.     }
  107.  
  108.     public function removeProductos(ArrayAccess $productIds) {
  109.         if ($productIds !== null) {
  110.  
  111.             for($iterator = $productIds->getIterator();
  112.             $iterator->valid();
  113.             $iterator->next()) {
  114.                 $this->remove((String)$iterator->current());
  115.             }
  116.         }
  117.     }
  118.  
  119.     public function removeAll()
  120.     {
  121.         $this->reset();
  122.     }
  123.  
  124.     public function getProducts()
  125.     {
  126.         $this->calculateTotals();
  127.         return $this->_contents;
  128.     }
  129.  
  130.     public function calculateTotals()
  131.     {
  132.         $this->_total = 0;
  133.         $this->_weight = 0;
  134.  
  135.         foreach ($this->_contents->getIterator() as $productsId => $item)
  136.         {
  137.  
  138.             $this->_weight += ($item->getQuantity() * $item->getWeight());
  139.             $this->_total += $item->getImporte();
  140.         }
  141.     }
  142.  
  143.     public function getContents()
  144.     {
  145.         return $this->_contents;
  146.     }
  147.  
  148.     public function getTotal()
  149.     {
  150.         return (double)$this->_total;
  151.     }
  152.  
  153.     public function getWeight()
  154.     {
  155.         return (double)$this->_weight;
  156.     }
  157. }

Nos damos cuenta que la clase concreta Core_Store_Cart_Abstract_StandardCart que extiende Core_Store_Cart_Abstract implementa cada uno de los métodos abstractos de la super-clase abstracta.

Sin entrar en detalle de la clase concreta del ejemplo observamos que obtenemos su instancia mediante el método estático getInstance(), esto es una implementación del patrón de diseño singleton, única instancia del objeto.

También observamos que el constructor de la super clase abstracta inicializa el proceso llamando el método reset(), que setea los atributo de la clase para comenzar con el sistema, crea una instancia del objeto de colección de items Core_Store_Cart_Item_Collection y setea atributos como total igual a "0" (cero).

Ahora vamos a explicar brevemente algunos de los principales métodos:

Bueno por hoy terminamos, la próxima sesión veremos el objeto de colección de items Core_Store_Cart_Item_Collection y la clase Core_Store_Cart_Item. Por ahora vayan analizando y observando los componentes que hemos expuesto en estos tres episodios.

:-)

Comentarios

One Response to “E-commerce con Zend Framework: Clase Cart”

  1. E-commerce con Zend Framework: Clase Colección de Items | Zend Framework: Estado del Arte on Abril 1st, 2009 4:12 am

    [...] el 3er capitulo “Clase Cart” de la serie “E-commerce con Zend Framework” hablamos en detalle sobre las clases que representa el [...]

Deja tu comentario




XHTML: puedes usar estas etiquetas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>