<?php

// *********************************************************************
// 
//  Clase Pedido
//
//  Taller de Programación Orientada a Objetos
//  para programadores de PHP
//
//  http://www.linuxcabal.org
//
//  Autor: Jerónimo Sánchez <jsanchez@consecutio.com>
// 

class Pedido {

    // atributos = variables miembro
    
    public $cliente = null;         // cliente: objeto Cliente
    public $productos = array();    // productos: array de objetos Producto

    // ---------------------------------------------------------------------
    
    // constructor(es)
    
    // en esta ocasión no creamos un constructor por defecto; 
    // al crear un pedido necesitamos, al menos, un cliente al que
    // asociarlo. opcionalmente, le añadiremos productos con
    // el método anyadirProducto().
    
    // importante: al contrario que en otros lenguajes, en php5 no
    // es posible sobrecargar el constructor, es decir, sólo podemos
    // tener un constructor para cada clase.
    
    public function __construct (Cliente $cliente) {
        
        // mediante la sugerencia de tipo (Cliente), forzamos al motor
        // de PHP a que compruebe el tipo del parámetro $cliente. 
        // de otro modo tendríamos que añadir más código para asegurarnos
        // de que lo que realmente estamos recibiendo es un objeto
        // de la clase Cliente (por ejemplo, con el operador instanceof).
        
        $this->cliente = $cliente;
        
    }

    // ---------------------------------------------------------------------

    // métodos "getter" y "setter"
 
    // no tenemos. el cliente se inicializa al crear el objeto y 
    // ya no se puede cambiar. por otro lado, los productos
    // se van añadiendo a la lista de productos mediante el método
    // especial anyadirProducto()
    
    // ---------------------------------------------------------------------

    // otros métodos...
    
    public function anyadirProducto (Producto $p) {
        
        // añadimos el producto al final del array
        // que contiene los demaś productos del pedido.
        
        $this->productos[] = $p;
        
    }

    protected function calcularTotal () {
        
        // esta función está protegida porque sólo se usará internamente
        // a la hora de imprimir el pedido.
        
        // recorremos el array de productos, preguntando a cada
        // producto por su precio, y sumándolo al total.
        
        $total = 0;
        foreach ($this->productos as $p) {
            $total += $p->obtenerPrecio();
        }
        
        // observa que el objeto de la clase Pedido no tiene 
        // necesidad de saber cómo calcular precios de productos;
        // simplemente se limita a preguntarle a cada producto.
        // esto se llama encapsulamiento de funcionalidad.
        
        // lo bueno de la encapsulación es que si cambia la forma
        // de calcular el precio de los productos, el código de
        // Pedido sigue funcionando sin tener que tocarlo. esto será
        // de vital importancia cuando estudiemos el polimorfismo.
        
        return $total;  // devolvemos el resultado
        
    }
    
    public function imprimir () {
        
        echo 'CLIENTE: '.$this->cliente->obtenerNombre()."<br />\n";
        echo "-------------------------------------<br />\n";
        
        foreach ($this->productos as $p) {
            echo 'Cód.: '.$p->obtenerCodigo().' - Desc.: '.
            $p->obtenerDescripcion().' - Importe: $'.
                $p->obtenerPrecio()."<br />\n"; 
        }
        
        echo "-------------------------------------<br />\n";
        echo "  TOTAL = $".$this->calcularTotal()."<br /><br />\n";
        
    }
    
}

?>
