<?php
/**
  Clase SuperUsuario
 */
 
class SuperUsuario extends Objeto{
	//Primero voy a declarar variables estáticas que vamos a utilizar
	public static $loggedUser = NULL;

    public $codigo = '';
    public $codigo_sinlib = 0;
    public $nombre_comercial = '';
    public $nombre_legal = '';
    public $email = '';
    public $direcciones = array();
    public $direccion_principal = 0; //Este es el índice del array de direcciones que apunta a la predeterminada
    public $direccion = '';
    public $cod_postal = '';
    public $localidad = '';
    public $provincia = '';
    public $pais = '';
    public $telefono = '';
    public $telefono2 = '';
    public $cif = '';
    public $tarifa = 0;
    public $no_precio_especial = 0;
    public $precios_escalados = 0;
    public $resta_iva = 0;
    public $tarifa_dto_pap = 0;
    public $descuento_papeleria = 0;
    public $descuento_libros = 0;
    public $descuento_texto = 0;
    public $limpiar_cesta = 0;
    public $cod_descuento = 0;
    public $direc_predeterminada = 0; //Este es el código de la dirección predeterminada
    public $escalados_tafifas = 0;
    public $vender_costo = 0;
    public $fecha_nacimiento = '';
    public $version_sinli = 0;
    public $administrador = false;
    public $factura_sin_detalle = false;
    public $favoritos = array();
    public $tipo_cliente = 0;
    public $tipo_envio = 0;
	public $ruta_importe_minimo = 0;
    public $ruta_gastos_envio = 0;
	//30/Enero/2019 ==> Añadimos el password:
	public $password = 0;
	
	private $flag_utf8 = false;

	//La funcion de get nombre tabla la dejo así por ahora porque del usuario solo vamos a sacar los datos del mismo.
	//más adelante sacaremos las tablas asociadas
	public static function getNombreTabla($soloPrincipal = NULL){
		//Incluimos los globals para coger el valor del idioma:
		self::$nombreTabla = strtolower(get_called_class());
		self::getTablaRelacionada();
		//Ahora vamos a componer el nombre de la tabla teniendo en cuenta si es sólo principal, si no o si es todo (NULL)
		$consulta = ' ';
		if ($soloPrincipal || $soloPrincipal === NULL){
			$consulta .= self::$nombreTabla . ' as `' .  self::getAlias() . '` ';
		}
		//Sólo asignamos el nombre de la tabla si no nos piden más parámetros
		if ($soloPrincipal == NULL){
			self::$nombreTabla = $consulta;
		}
		return($consulta);
	}
	
	public static function getWhereTabla(){
		$argumentos = func_get_args();
		$codigo = isset($argumentos[0]) ? $argumentos[0] : NULL;
		$email = isset($argumentos[1]) ? $argumentos[1] : NULL;
		$limitar = isset($argumentos[2]) ? $argumentos[2] : true;
		include('comunes/globals.php');
		if ($codigo != NULL){
			self::$whereSelect = ' `' . self::getAlias() . '`.`codigo` = \'' . $codigo . '\'';
		}
		if ($email != NULL){
			self::$whereSelect = ' `' . self::getAlias() . '`.`email` = \'' . $email . '\'';
		}
		if ($limitar){
			self::$whereSelect .= ' LIMIT 0,1 ';
		}
		return(self::$whereSelect);
	}
	
    function __construct($codigo) {
        include('comunes/globals.php');
		//Vamos a controlar que no se nos haya pasado un opciones widget
		$filaUsuario = NULL; // ==> Aquí podemos pasar el resultado de una select ya hecha, lo que nos dará los campos directamente para insertarlos
		if (is_a($codigo, 'OpcionesWidget')){
			//Recogemos las opciones del 'OpcionesWidget'
			$opciones = $codigo;
			$codigo = 0;
			$codigo = ($opciones->configuracion->codigo !== NULL) ? $opciones->configuracion->codigo : $codigo;
			$filaUsuario = ($opciones->configuracion->filaUsuario !== NULL) ? $opciones->configuracion->filaUsuario : $filaUsuario;
		}
		$fila = NULL;
		//Si no hemos recibido fila usuario, vamos a hacer la select:
		if ($filaUsuario == NULL){
			//echo("Vamos a cargar el usuario");
			/*
			$sentencia_sql = 'SELECT `codigo`, `codigo_sinlib`, `nombre_comercial`, `nombre_legal`, `email`, `direccion`, `cod_postal`, `localidad`, `provincia`, `telefono`, `telefono2`, `cif`, `pais`, `no_precio_especial`, `tarifa`, `precios_escalados`, `resta_iva`, `tarifa_dto_pap`, `descuento_papeleria`, `descuento_libros`, `descuento_texto`, `limpiar_cesta`, `cod_descuento`, `tarifas_multiples`, `direc_predeterminada`, `escalados-tarifa`, `vender-costo`, `fecha_nacimiento`, `version_sinli`, `factura_sin_detalle`,`tipo_cliente`, `tipo_envio` 
			 FROM cliente WHERE codigo = ' . $codigo;
			 */
			$sentencia_sql = 'SELECT ' . self::getCampos() . ' 
								FROM ' . self::getNombreTabla() . ' 
								WHERE ' . self::getWhereTabla($codigo);
			$bd = new BaseDatos();
			if ($bd->isConectado()){
				$bd->setConsultaSQL($sentencia_sql);
				$fila = $bd->getFila();
			}
			//echo("-----------$sentencia_sql<br />\n");
		}else{
			$fila = $filaUsuario;
		}
		if ($fila != NULL) {
			$this->extractData($fila);
		}
	}

	public function extractData($fila){
		$this->codigo = $fila[self::getAlias() . '_codigo'];
		$this->codigo_sinlib = $fila[self::getAlias() . '_codigo_sinlib'];
		$this->nombre_comercial = $fila[self::getAlias() . '_nombre_comercial'];
		$this->nombre_legal = $fila[self::getAlias() . '_nombre_legal'];
		$this->email = $fila[self::getAlias() . '_email'];
		//Vamos a crear un objeto direcciones para añadir la dirección del cliente
		$this->direccion = $fila[self::getAlias() . '_direccion'];
		$this->cod_postal = $fila[self::getAlias() . '_cod_postal'];
		$this->localidad = $fila[self::getAlias() . '_localidad'];
		$this->provincia = $fila[self::getAlias() . '_provincia'];
		$this->telefono = $fila[self::getAlias() . '_telefono'];
		$this->pais = $fila[self::getAlias() . '_pais'];
		$this->direcciones[0] = new Direcciones($this->codigo, 0, $this->direccion, $this->cod_postal, $this->localidad, $this->provincia, $this->telefono, $this->nombre_legal, $this->pais);
		$this->telefono2 = $fila[self::getAlias() . '_telefono2'];
		$this->cif = $fila[self::getAlias() . '_cif'];
		$this->tarifa = $fila[self::getAlias() . '_tarifa'];
		$this->no_precio_especial = $fila[self::getAlias() . '_no_precio_especial'];
		$this->precios_escalados = $fila[self::getAlias() . '_precios_escalados'];
		$this->resta_iva = $fila[self::getAlias() . '_resta_iva'];
		$this->tarifa_dto_pap = $fila[self::getAlias() . '_tarifa_dto_pap'];
		$this->descuento_papeleria = $fila[self::getAlias() . '_descuento_papeleria'];
		$this->descuento_libros = $fila[self::getAlias() . '_descuento_libros'];
		$this->descuento_texto = $fila[self::getAlias() . '_descuento_texto'];
		$this->limpiar_cesta = $fila[self::getAlias() . '_limpiar_cesta'];
		$this->cod_descuento = $fila[self::getAlias() . '_cod_descuento'];
		$this->direc_predeterminada = $fila[self::getAlias() . '_direc_predeterminada'];
		$this->escalados_tafifas = $fila[self::getAlias() . '_escalados-tarifa'];
		$this->vender_costo = $fila[self::getAlias() . '_vender-costo'];
		$this->fecha_nacimiento = $fila[self::getAlias() . '_fecha_nacimiento'];
		$this->version_sinli = $fila[self::getAlias() . '_version_sinli'];
		$this->factura_sin_detalle = ( $fila[self::getAlias() . '_factura_sin_detalle'] == 0) ? false : true;
		$this->tipo_cliente = $fila[self::getAlias() . '_tipo_cliente'];
		$this->tipo_envio = $fila[self::getAlias() . '_tipo_envio'];
		$this->ruta_importe_minimo = $fila[self::getAlias() . '_ruta_importe_minimo'];
		$this->ruta_gastos_envio = $fila[self::getAlias() . '_ruta_gastos_envio'];
		$this->password = $this->getProp($fila, 'password');
		

		//Vamos a comprobar rápidamente si el usuario es administrador ==> Esto lo podemos optimizar en la consulta inicial
		$sentencia_sql = "SELECT codigo FROM administrador WHERE email = '$this->email'";
		$bd = new BaseDatos();
		if ($bd->isConectado()){
			$bd->setConsultaSQL($sentencia_sql);
			$fila = $bd->getFila();
			if ($fila["codigo"] > 0) {
				$this->administrador = true;
			}
		}
		
		//Vamos a cargar las direcciones asociadas a este usuario
		$sentencia_sql = 'SELECT `codigo`, `direccion`, `cod_postal`, `localidad`, `provincia`, `nombre`, `telefono`, `pais` FROM `direccion_envio` WHERE `cliente` = \'' . $this->codigo . '\';';
		if ($bd->isConectado()){
			$bd->setConsultaSQL($sentencia_sql);
			while ($fila = $bd->getFila()){
				$this->direcciones[] = new Direcciones($this->codigo, $fila['codigo'], $fila["direccion"], $fila["cod_postal"], $fila["localidad"], $fila["provincia"], $fila["telefono"], $fila["nombre"], $fila["pais"]);
				if ($fila["codigo"] == $this->direc_predeterminada) {
					$this->direccion_principal = $fila["codigo"];
				}	
			}
		}
		
		//Ahora hay que ordenar las direcciones de envío
		if ($this->direc_predeterminada != 0) {
			$encontrado = 0;
			for ($i = 1; $i < count($this->direcciones) && ($encontrado == 0); $i++) {
				if ($this->direcciones[$i]->codigo == $this->direc_predeterminada) {
					$encontrado = $i;
				}
			}
			$copia_dir = $this->direcciones[0];
			$this->direcciones[0] = $this->direcciones[$encontrado];
			$this->direcciones[$encontrado] = $copia_dir;
		}
		//Cargamos los favoritos. No se inicializan los objetos artículos por optimizar la velocidad
		$sentencia_sql = 'SELECT articulo.codigo FROM articulo, favoritos WHERE favoritos.articulo = articulo.codigo AND favoritos.cliente = \'' . $this->codigo . '\' ORDER BY favoritos.fecha_alta ASC';
		if ($bd->isConectado()){
			$bd->setConsultaSQL($sentencia_sql);
			while ($fila = $bd->getFila()){
				$this->favoritos[] = $fila["codigo"];
			}
		}

	}
	
    function __destruct() {
        //Limpiamos los hijos que tenga asociados el escaparate
        for ($i = 0; $i < count($this->direcciones); $i++) {
            unset($this->direcciones[$i]);
        }
    }

	public function isRegistered(){
		return( ($this->codigo > 0) ? true : false);
	}
	
	public function getCurrentDirection(){
		$retorno = NULL;
		//Lo primero es ver cual es la dirección por defecto:
		$direccion_envio = Sesion::get('direccion_envio', 0);
		//Si el usuario no tiene código es un usuario sin login:
		if ($this->codigo != ''){
			$retorno = $this->direcciones[$direccion_envio];
		}else{
			$retorno = new Direcciones(
				0, 
				0, 
				$this->direccion, 
				$this->cod_postal, 
				$this->localidad, 
				$this->provincia, 
				$this->telefono, 
				$this->nombre_legal, 
				$this->pais
			);
		}
		return($retorno);
	}
	
	public function shippingCosts(){
		//Esta función recibirá datos sobre los productos que se piden y utilizando la conf. del cliente calculará los gastos de envío
			//por ahora son 0, pero para las pruebas vamos a poner 50 euros
		$retorno = 50;
		
		return($retorno);
	}
	
	public function limpiarCesta(){
		return(self::setLimpiarCesta($this->codigo));
	}
	
	public static function setLimpiarCesta($cod_usuario){
		//Vamos a dar el pedido por finalizado.
		$retorno = false;
		$sentencia_sql = 'UPDATE `cliente` SET `limpiar_cesta` = 1 WHERE `codigo` = \'' . $cod_usuario . '\'; ';
		$bd = new BaseDatos();
		$bd->setConsultaSQL($sentencia_sql);
		if ($bd->getNumeroFilas() > 0){
			$retorno = true;
		}
		return($retorno);
	}
	
    public function getJSON() {
        $prop = get_object_vars($this);
        $resp = '{ ';
        foreach ($prop as $key => $value) {
            if (!is_object($value)) {
                $value = (string) $value;
                if ($this->flag_utf8) {
                    $resp .= '"' . $key . '":' . json_encode(htmlspecialchars_decode($value)) . ',';
                } else {
                    $resp .= '"' . $key . '":' . json_encode(htmlspecialchars_decode(utf8_encode($value))) . ',';
                }
            } else {
                $ejecutarJson = true;
                if (method_exists(get_class($value), 'getJSON')) {
                    $ejecutarJson = false;
                }
                if (!$ejecutarJson) {
                    $resp .= '"' . $key . '":' . $value->getJSON() . ',';
                } else {
                    $resp .= '"' . $key . '":' . json_encode($value) . ',';
                }
            }
        }
        $resp = substr($resp, 0, -1) . "}";
        return $resp;
    }

	public static function logueado(){
		$retorno = NULL;
		//Esta función nos devolverá el objeto usuario si este está logueado
		//Lo primero es ver si tenemos el objeto "loggedUser" en esta clase (es estático)
		if (static::$loggedUser != NULL){
			$retorno = static::$loggedUser;
		}else{
			//Vamos a cogerlo de la sesión:
			$codigoUsuario = Sesion::get('cod_cliente_web', 0);
			if ($codigoUsuario > 0){
				$usuario = new Usuario(new OpcionesWidget(array('codigo' => $codigoUsuario)));
				if ($usuario->isRegistered()){
					$retorno = static::$loggedUser = $usuario;
				}
			}else{
				//Vamos a ver si tenemos un usuario sin registro en la sesión:
				$usuarioSinRegistro = Sesion::get('usuarioSinRegistro', NULL);
				if ($usuarioSinRegistro != NULL){
					$retorno = static::$loggedUser = $usuarioSinRegistro;
				}
			}
		}
		return($retorno);
	}
	//Creado por Pedro el 28/Enero/2019 ==> Comprobamos si el cliente existe por su email
	public static function exists($email){
		$retorno = false;
		if (isset($email)){
			if (trim($email) != ''){
				$sentencia_sql = 'SELECT ' . self::getCampos() . ' 
								FROM ' . self::getNombreTabla() . ' 
								WHERE ' . self::getWhereTabla(NULL, $email);
				//echo($sentencia_sql);
				$bd = new BaseDatos();
				if ($bd->isConectado()){
					$bd->setConsultaSQL($sentencia_sql);
					if ($bd->getFila()){
						$retorno = true;
					}
				}
			}
		}
		return($retorno);
	}
	//Creado por Pedro el 28/Enero/2019 ==> Función que recibe el array de datos del cliente e intenta registrarlo
	public static function register($data = NULL){
		$retorno = 0;
		//Data contendrá un array de datos con los nombres de los campos de la BD y sus respectivos valores
		if (is_array($data)){
			if (count($data) > 0){
				//Si hemos recibido un password vamos a controlar si tiene que ir encriptado con el sistema antiguo o el nuevo:
				if (isset($data['password'])){
					if (trim($data['password']) == ''){
						unset($data['password']); //Si el password es una cadena vacía o espacios, lo quitamos para crearlo así
					}else{
						$password = $data['password'];
						//Según la configuración, el password va guardado con un formato u otro:
						if (Shop::$configuracion->sha1_password){
							$passwordJustificado = str_pad($password, 10, '.');
							$data['password'] = sha1($passwordJustificado);
						}else{
							$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
						}
					}
				}
				$lista_campos = array_keys($data);
				$lista_valores = $data;
				$lista_campos = ' ( `' . implode('`, `', $lista_campos) . '`) ';
				$lista_valores = ' ( \'' . implode('\', \'', $lista_valores) . '\') ';
				$sentencia_sql = 'INSERT INTO ' . self::getNombreTablaSinAlias() . '
					' . $lista_campos . '
					VALUES 
					' . $lista_valores . ';';
				//Insertamos en la BD
				echo($sentencia_sql);
				$bd = new BaseDatos();
				if ($bd->isConectado()){
					if ($bd->setConsultaSQL($sentencia_sql)){
						$retorno = $bd->getAutonumerico();
					}
				}
			}
		}
		return($retorno);
	}
	
	public static function login($email = NULL, $password = NULL){
		$retorno = NULL;
		if ( ($email != NULL) && ($password != NULL) ){
			if ( (trim($email) != '') && (trim($password) != '') ){
				//Vamos a cargar los datos de cliente por el email
				$sentencia_sql = 'SELECT ' . self::getCampos() . ' 
									FROM ' . self::getNombreTabla() . ' 
									WHERE ' . self::getWhereTabla(NULL, $email);
				//echo($sentencia_sql);
				$bd = new BaseDatos();
				if ($bd->isConectado()){
					$bd->setConsultaSQL($sentencia_sql);
					if ($fila = $bd->getFila()){
						$cliente = new Usuario(new OpcionesWidget(array('filaUsuario' => $fila)));
						//Vamos a comprobar que el password es correcto:
						//Vamos a comprobar si el login es correcto, para ello tenemos en cuenta la retrocompatibilidad
						if (Shop::$configuracion->sha1_password){
							$passwordJustificado = str_pad($password, 10, '.');
							$passwordModificado = sha1($passwordJustificado);
							if ($cliente->password == $passwordModificado){
								$retorno = $cliente;
							}
						}else{
							if (password_verify($password, $cliente->password)) {
								$retorno = $cliente;
							}
						}
					}
				}
			}
		}
		if ($retorno != NULL){
			//Asignamos tanto al objeto estático como a la sesión el cliente con el que estamos
			static::$loggedUser = $retorno;
			echo("Asignamos el valor del cliente a la sesión: " . $retorno->codigo . "<br />\n");
			Sesion::set('cod_cliente_web', $retorno->codigo);
		}
		return($retorno);
	}
}

?>