Bueno este es mi primer post y espero que les sea de buena utilidad.
A continuación veremos como se crea un carrito de compras usando PHP5, POO y MYSQL.
Al final del post se encontrará el link para descargar el código completo y la BD.
Primero que nada necesitaremos crearnos un par de tablas que vamos a trabajarlas.
Ahi la estructura de las tabla.(Las tablas la encontraran en el archivo adjunto de abajo.)
EMPEZEMOS:
1.Crearemos la clase Conexion: Conexion.class.php
<?php
class Conexion{
private $hilo; //Variable para retornar el valor de la conexion.
private $resultSet; //Variable para retornar el valor de la consulta.
//Función que se ejecutará ni bien se haya instanciado en objeto Conexión.
public function __construct($server = '127.0.0.1',
$username = 'root',
$password = '',
$database = 'carrito') {
//Nos conectamos la BD
$this->hilo = mysql_pconnect($server,$username,$password);
//Si en caso haya fallado la conexión a la BD mostramos un mensaje de error.
if(!$this->hilo){
die('No se pudo conectar a la Base de Datos:' . mysql_error());
}
//Si en caso no se ha podido acceder a la BD mostramos un mensaje de rror
if(!mysql_select_db($database,$this->hilo)){
die('No se pudo conectar a la BD '.$database.':'. mysql_error());
}
}
//Esta función nos permitirá ejecutar cualquier tipo de consulta Select, Insert, Update o Delete
public function ejecutar($sql){
$this->resultSet=mysql_query($sql); //Si sale bien.
if(!$this->resultSet){ //Si hay un error.
die('No se pudo realzizar la consulta:<br />'.$sql.'<br />'. mysql_error());
}
return $this->resultSet; //Retorna el valor obtenido de la consulta.
}
//La función desctructor se ejecutará una vez terminado todo el script y cerrará la conexión
public function __destruct() {
if(!$this->hilo)mysql_close($this->hilo);
}
}
?>
2. Pasamos a crear la clase: Producto.class.php
//Se le asignara los atributos correspondientes
<?php
class Producto{
//Atributos
public $codpro;
public $nompro;
public $prepro;
public $cantidad;
//Constructor se ejecutará una vez instanciado al Objeto(recibirá 3 parámetros codpro,nompro y prepro)
public function __construct($c,$n,$p) {
$this->codpro=$c;
$this->nompro=$n;
$this->prepro=$p;
$this->cantidad=1; //Se le asignara un valor por defecto 1.
}
//Metodo que nos permitirá calcular el precio Total por cada producto insertado al carrito
public function precioTotal(){
//Se aplica un formato para números con 2 decimales.
return number_format($this->prepro*$this->cantidad, 2, '.', '');
}
}
?>
3.Pasamos a crear la clase: Carrito.class.php
<?php
class Carrito{
public $codigo; //atributo codigo de carrito
public $productos; //atributo productos, contendra todo los productos seleccionados al carrito
function __construct($id) {
$this->codigo=$id;
$this->productos=array(); //instanciamos el atributo productos l ista para ser llenado de productos
}
//Indico el codigo y recupero un producto si es que existe en el carrito
public function obtenerProducto($codigo){
foreach($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
return $producto;
}
}
return null;
}
//Actualiza la cantidad de items para un mismo producto que ya existe en el carrito
//En caso existe el mismo producto que se quiera insertar al carrito la cantidad suma +1
public function actualizarCantidad($codigo,$cantidad){
foreach ($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
$producto->cantidad +=$cantidad;
}
}
}
//Agrego o actualizo su cantidad de un producto al carrito
public function agregarProducto($producto){
//Busco el producto si ya fue insertado
$yaIncluido = $this->obtenerProducto($producto->codpro); //Buscará si existe el producto
if($yaIncluido){
$this->actualizarCantidad($producto->codpro, 1); //Busco y actualizo el producto
}else{
$this->productos[]=$producto; //Agrego un nuevo producto al carrito
}
}
//Calcular el monto total de los productos
public function calcularMonto(){
$monto = 0;
foreach($this->productos as $indice => $producto){
$monto += $producto->precioTotal();
}
return number_format($monto, 2, '.', '');
}
//Nos permitirá calcular la cantidad total de productos insertados al carrito
public function calcularCantidad(){
$cantidad = 0;
foreach($this->productos as $indice => $producto){
$cantidad += $producto->cantidad;
}
return $cantidad;
}
//Calcular descuento segun cantidad total.
public function calcularDescuento(){
$cantidad = $this->calcularCantidad();
if($cantidad > 1000){
return 20;
}else if($cantidad > 100){
return 10;
}else if($cantidad > 3){
return 2;
}else
return 0;
}
//Calcular precio total, con el montoTotal y el descuento.
public function calcularPrecioTotal(){
$total=$this->calcularMonto()*(100 - $this->calcularDescuento())/100;
return number_format($total, 2, '.', '');
}
//Eliminar producto del carrito por su codigo
//En este caso lo que hacemos es recorrer los productos, luego preguntamos si el código de producto
//es diferente al código que estamos mandando, si es así entonces llenaremos los productos en un nuevo
//arreglo $pro2, luego de eso reemplazamos el atributo productos por el valor del arreglo $pro2.
public function eliminarProducto($codigo){
$pro2 = array();
foreach ($this->productos as $indice => $producto){
if($producto->codpro!=(int)$codigo){
$pro2[]=$producto;
}
}
$this->productos=$pro2; //Reemplaza por el valor del arreglo
}
//Actualizar cantidad ingresada.
//Este metodo lo que hace simplemente es reemplazar la cantidad del producto por uno ingresada.
public function actualizarCantidadIngresada($codigo,$cantidad){
foreach ($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
$producto->cantidad =$cantidad; //Reemplaza la cantidad existente en el producto
}
}
}
}
?>
4.Pasamos a crear la clase: ProductoDAO.class.php
<?php
//Incluimos las 2 clases necesarias para realizar la consulta. a la BD.
require_once ('Producto.class.php');
require_once ('Conexion.class.php');
class ProductoDAO{
public $conexion; //Variable que contendra el resultado de la conexion
public function __construct() {
$this->conexion = new Conexion(); //Instanciamos el metodo Conexion de la clase Conexion.class.php
}
//Recupero en un array todos los productos en forma de objetos de la base de datos
public function obtenerProductos(){
$productos = array();
$result = $this->conexion->ejecutar("select codpro, nompro, prepro from producto");
while($array = mysql_fetch_array($result)){
//Creo una instanacia de producto y lo almanceo en el array
$productos[] = new Producto($array['codpro'],$array['nompro'],$array['prepro']);
}
return $productos;
}
//Recupero un producto de foma de objeto de la base de datos indicandole su código
public function obtenerProducto($codigo){
$producto = null;
$sql = "select codpro, nompro, prepro from producto where codpro=". mysql_escape_string($codigo);
$result = $this->conexion->ejecutar($sql);;
if($array = mysql_fetch_array($result)){
//Creo una sola instancia que será devuelta..
$producto = new Producto($array['codpro'],$array['nompro'],$array['prepro']);
}
return $producto;
}
//Funcion para guardar una Factura y su Detalle, recibirá como parámetros.
//$productos - que contndra todos los productos agregados al carrito
//$mon - El monto total de todo los productos
//$des - El descuento total de todos los productos
//$tot - El total de todo los productos
function guardarFactura($productos,$mon,$des,$tot){
//Autocommit = 0
mysql_query("SET AUTOCOMMIT=0;"); //Para InnoDB, sirve para mantener la transaccion abierta
//Inicio de transacción
mysql_query("BEGIN;");
//Operaciones en la Factura
//Para este usaremos el codigo de 1 cliente
$sql = "insert into factura (codcli,facfec,facmon,facdes,factot) ";
$sql .= "values (1, now(),$mon,$des,$tot)";
$rs =$this->conexion->ejecutar($sql);
if(!$rs){
echo "Error en la Transacción: ".mysql_error();
mysql_query("ROLLBACK;"); //Terminar la transaccion si hay error
exit();
}
//Recuperamos el ID generado en el insert de la tabla "factura"
$facnum = mysql_insert_id();
//Recorremos e insertamos todos los productos a la tabla facdeta, todos con el mismo Id.
foreach($productos as $producto){
$sql1 = "INSERT INTO facdeta(codpro,facnum,cantidad,precio,total)";
$sql1 .= "values ($producto->codpro,$facnum, $producto->cantidad,$producto->prepro,{$producto->precioTotal()})";
$rs = $this->conexion->ejecutar($sql1);
if(!$rs){
echo "Error en la Transacción: ".mysql_error();
mysql_query("ROLLBACK;"); //Terminar la transaccion si hay error
exit();
}
}
if ($rs) {
mysql_query("COMMIT"); //Terminar la transaccion
}
return $facnum; //Retornamos el id
}
}
?>
5. Por último tenemos en index. Acá se hará todas las transacciones..
<?php
//Incluimos los 2 archivos para realizar toda la transacción
require_once ('Carrito.class.php');
require_once ('ProductoDAO.class.php');
session_start(); //Inicamos todas las sesiones
//Creamos al objeto carrito vacio con un identificador de sesion
$carrito = new Carrito(session_id());
//Recupero el objeto carrito de la sesion en caso exista
if(isset($_SESSION['carrito'])) $carrito = $_SESSION['carrito'];
//Si el usuario realizo una acción
if(isset ($_GET['action'])){
//Si el cliente ha seleccionado un producto
switch ($_GET['action']){
case 'agregar':
//Recupero el producto de codigo indicado en la base de datos
$productoDAO = new ProductoDAO();
$producto = $productoDAO->obtenerProducto((int)$_GET['idProducto']);
//Agrego al carrito de compras el producto recuperado de la base de datos
$carrito->agregarProducto($producto);
break;
case 'vacear':
//Reemplazo el atributo carrito de la sesion con un objeto carrito sin productos
$carrito = new Carrito(session_id());
break;
case 'eliminar':
//Llamo al metodo eliminarProducto retorno todos los productos menos el del código incicado
$carrito->eliminarProducto((int)$_GET['idProducto']);
break;
case 'actualizar':
//Atrapamos el nombre y valor de todos los textbox...
//Luego vemos si tanto el codigo y la cantidad son mayores que 0.
//Y actualizamos la cantidad 1 a 1 de cada producto
foreach($_GET as $codigo => $cantidad){
if((int)$codigo > 0 && (int)$cantidad > 0){
//Actualizamos la cantidad para un mismo producto
$carrito->actualizarCantidadIngresada($codigo, $cantidad);
}
}
break;
case 'guardar':
$productoDAO = new ProductoDAO();
$facnum = $productoDAO->guardarFactura($carrito->productos,$carrito->calcularMonto(),$carrito->calcularDescuento(),$carrito->calcularPrecioTotal());
break;
}
//Guardo nuevamente el carrito de la session
$_SESSION['carrito'] = $carrito;
header('Location: index.php'); //Regresamos ala pagina Inicial
exit(); //Paramos el script
}
?>
<html>
<head>
<style>
.link_button{
background-color:#444444;
color:#FFFFFF;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
font-weight:bold;
border: 1px solid #7F7F7F;
padding: 2px 3px 2px 3px;
cursor:pointer;
}
.productos_listado{
table-layout:fixed;
width:650px;
border: 1px solid #D3D4DF;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
}
.productos_listado caption{
background-color: #333333;
font-family:Arial, Helvetica, sans-serif;
font-size:14px;
font-weight:bold;
color:#FFFFFF;
padding:8px 0px 8px 0px;
}
.productos_listado th{
background-color: #D3D4DF;
color:#333333;
}
.productos_listado td{
height:24px;
}
.productos_listado td.td_linea{
height: 2px;
background-color: #333333;
padding: 2px 0px 4px 3px;
}
</style>
</head>
<body topmargin="0" leftmargin="0">
<div align="center" class="content">
<form action="index.php" method="get">
<table border="0" class="productos_listado">
<caption>Listado de Productos</caption>
<tr>
<th width="70px">Código</th>
<th>Detalle</th>
<th width="80px">Precio</th>
<th width="50px">Add</th>
</tr>
<?php
//Recuperando datos de los productos
$productoDAO = new ProductoDAO;
$productos = $productoDAO->obtenerProductos();
//Listamos todos los productos
foreach ($productos as $producto){
?>
<tr>
<td align="center"><b><?php echo $producto->codpro ;?></b></td>
<td><?php echo $producto->nompro ;?></td>
<td align="center">S/.<?php echo $producto->prepro ;?></td>
<td align="center">
<a href="javascript:void(0);"
onclick="window.location='index.php?action=agregar&idProducto=<?php echo $producto->codpro ;?>';">
<img src="img/shopcart.png" alt="Agregar" border="0" title="Agregar"/>
</a>
</td>
</tr>
<?php
}
?>
</table>
<br />
<hr>
<?php
$total = 0;
//Si existe al menos un producto se generará todo lo demas.
if(count($carrito->productos)>0){
?>
<table border="0" class="productos_listado">
<caption>Carrito de compras</caption>
<tr>
<th width="40"> </th>
<th width="60">Cant.</th>
<th width="70">Código</th>
<th>Nombre</th>
<th width="90">Precio unit.</th>
<th width="90">Precio total</th>
</tr>
<?php
//Listamos los productos insertados al carrito
foreach($carrito->productos as $producto){
?>
<tr>
<td align="center">
<a href="javascript:void(0);"
onClick="window.location='index.php?action=eliminar&idProducto=<?php echo $producto->codpro ;?>';">
<img src="img/bin_closed.png" alt="Eliminar" border="0" title="Eliminar"/>
</a>
</td>
<td align="center">
<input type="text" name="<?php echo $producto->codpro ;?>"
value="<?php echo $producto->cantidad ;?>" maxlength="3" size="4" style="text-align: center" />
</td>
<td align="center"><?php echo $producto->codpro ;?></td>
<td align="center"><?php echo $producto->nompro ;?></td>
<td align="center">S/.<?php echo $producto->prepro ;?></td>
<td align="center">S/.<?php echo $producto->precioTotal() ;?></td>
</tr>
<?php
}
?>
<tr>
<td class="td_linea" colspan="6"></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Monto:</b>
</td>
<td align="center">S/.<?php echo $carrito->calcularMonto(); ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Cantidad:</b>
</td>
<td align="center"><?php echo $carrito->calcularCantidad(); ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Descuento:</b>
</td>
<td align="center">%<?php echo $carrito->calcularDescuento() ; ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Total:</b>
</td>
<td align="center">S/.<?php echo $carrito->calcularPrecioTotal() ; ?></td>
</tr>
</table>
<input type="button" value="Vacear Cesta" class="link_button" style="width:130px;"
onClick="parent:location='index.php?action=vacear'"/>
<input type="hidden" name="action" value="actualizar" style="width:130px;"/>
<input type="submit" value="Actualizar" class="link_button" style="width:130px;"/>
<!--<input type="submit" value="Guardar" name="guardar" class="link_button" style="width:130px;"/>-->
<input type="button" value="Grabar" class="link_button" style="width: 130px"
onclick="parent:location='index.php?action=guardar';">
<?php
//var_dump($carrito);
?>
<?php
}else
echo 'No tiene ningun producto'; //Si no hay producto en el carrito se muestra un mensaje
?>
</form>
</div>
</body>
</html>
---------------------------------------------------------------------------------------------------
Bueno esto es todo, como dije antes espero que les sirva para poder realizar trabajos más complejos en adelante usando la POO y la base de datos MYSQL.
Aca la descarga del archivo... (' ' ,)
Descargar