14 de julio de 2010
Navegando por la web de Symfony en busca de un plugin que implementase las operaciones de un "Carrito de la compra" y que fuese compatible con la versión 1.4 y el ORM Doctrine, no encontré nada interesante. Sin embargo, vi el plugin sfShoppingCartPlugin creado por Fabien Potencier para la versión 1.0 de Symfony y Propel.
Tras echarle un ojo, vi que implementa basicamente lo que necesito para mi carro de la compra y que solo requería de algunas modificaciones para hacerlo compatible con Doctrine, por lo que decidí hacer uso de él.
El plugin en si consta solamente con dos clases:
Básicamente, el uso es el siguiente:
<?php
// Se crea el objeto de la cesta
$carrito = new sfShoppingCart(sfConfig::get('app_tax'));
// Se añade un nuevo Articulo al carrito
$article = ArticlesTable::getInstance()->find($request->getParameter('id'));
$articleItem = new sfShoppingCartItem(get_class($article), $article->getId());
$articleItem->setPrice($article->getPrice());
$articleItem->setQuantity($request->getParameter('quantity'));
$carrito->addItem($articleItem);
// Recorrer el carrito y ver el precio total
foreach ($carrito->getItems() as $item) {
echo sprintf(
'%d: %f x %d = %f',
$item->getId(),
$item->getPrice(),
$item->getQuantity(),
($item->getPrice() * $item->getQuantity())
);
}
echo 'Total: ' . $carrito->getTotal();
Además de estas operaciones la clase sfShoppingCart incluye dos operaciones que devuelven el objeto Item del modelo:
sfShoppingCart::getObjects()
sfShoppingCart::getObject($class, $id)
Estos métodos hacen uso de Propel para obtener el objeto de la clase $class y con id $id.
Como lo que necesito es hacer uso de Doctrine, nada mejor que extender sfShoppingCart a sfDoctrineShoppingCart y sobreescribir ambos métodos:
public function getObject($class, $id)
{
// We must first make sure that the requested object does exist in the shopping cart
$ind = $this->getItemIndice($class, $id);
return (($ind !== null) ? call_user_func(array($class.'Table', 'find'), $id) : null);
}
public function getObjects()
{
$object_ids = array();
foreach ($this->getItems() as $item)
{
if (!array_key_exists($item->getClass(), $object_ids))
{
$object_ids[$item->getClass()] = array();
}
$object_ids[$item->getClass()][] = $item->getId();
}
$objects = array();
foreach ($object_ids as $class => $ids)
{
$objects = array_merge(
$objects,
Doctrine::getTable($class)->createQuery('c')->whereIn('c.id', $ids)->execute()->getData()
);
}
return $objects;
}
Con ésto ya se puede hacer uso de la clase sfDoctrineShoppingCart con todas las funcionalidades que ofrece sfShoppingCart pero adaptado a Doctrine.
Además he implementado algunos métodos extra para hacerlo más cómodo al uso. Por ejemplo sfDoctrineShoppingCart::getInstance() o sfDoctrineShoppingCart::save() para obtener y almacenar el carrito
Plugin sfShoppingCart de Fabien Potencier.
Tags: Programación | PHP | Symfony