<?php
/**
	Clase SuperEscaparate
	@version 2.0
		29/06/2016 ==> El constructor admite un objeto con los parámetros
	@version 2.1
		21/11/2016 ==> Añadimos una función para cargar los hijos y hacemos que la clase las utilice
	@version 2.2
		09/02/2018 ==> Nueva carga de escaparate y subEscaparates mucho más rápida y eficiente
	@version 3.0
		09/02/2018 ==> Añadimos las variables de la super clase que contienene campos, origen y condición de manera separada para los filtros
					==> Añadimos las funciones que nos darán los campos, las tablas y la whereTabla
					==> Delegamos la carga de productos a una función común en la super clase
*/

class SuperEscaparate extends Apartado{
	public $rama_seleccionada = false;
	public $id = '';
	public $nombre_natural = '';
	public $codigo = 0;
	public $orden = 0;
	public $nivel = 0;
	public $padre = NULL;
	public $rama = '';
	public $hijos = array();
	public $objeto_vacio = 0;
	public $estilo_seleccionado = '';
	public $estilo_no_seleccionado ='';
	public $ocultar_en_buscadores = '';
	public $fecha_ultima_modif = '';
	public $fecha_alta = '';
	public $condicion = '';
	public $activo = NULL;
	public $importe_minimo_g_envio_gratis = 0;
	public $descripcion = '';

	//Datos SEO:
	public $nombre_seo = '';
	public $title_seo = '';
	public $keywords_seo = '';
	public $descripcion_seo = '';

	//Propiedades internas o de control
	public $hijosCargados = false;
	private $cargarSoloActivos = 0;
	
	//Funciones que nos van a dar los campos de la tabla y el resto de datos:
	public static function getCampos($soloPrincipal = NULL, $tablasOrigen = NULL){
		self::$nombreTabla = strtolower(get_called_class());
		self::getTablaRelacionada();
		//tablasOrigen debe ser un array de elementos con los siguientes valores:
			//0 ==> tabla de escaparates sólo
			//1 ==> tabla de traducciones + escaparates
			//2 ==> tabla de datos SEO + escaparates
		//Nos aseguramos de que 'tablasOrigen' exista y sea un array:
		$tablasOrigen = ($tablasOrigen == NULL) ? array(0,1,2) : $tablasOrigen;
		$tablasOrigen = (is_array($tablasOrigen)) ? $tablasOrigen : array(0,1,2);
		//Vamos a inicializar la variable dónde coger los camposa mostrar:
		//$campos = BaseDatos::dameCamposAlias(BaseDatos::$dictionary->{self::$nombreTabla . 'Campos'}, self::getAlias());
		$campos = BaseDatos::dameCamposAlias(self::$nombreTabla);
		//Ahora recorremos el array de campos que se añaden para garantizar que están entre los campos:
		foreach ($tablasOrigen as $claveTabla => $exportarTabla){
			$nombreTabla = '';
			if ($exportarTabla == 1){
				//Traducciones de escaparate
				$nombreTabla = 'traducesca';
			}else if ($exportarTabla == 2){
				//Datos SEO del escaparate
				$nombreTabla = 'cesca_seo';
			}
			if ($nombreTabla != ''){
				/*$campos .= ', ' . BaseDatos::dameCamposAlias(
					BaseDatos::$dictionary->{$nombreTabla . 'Campos'}, 
					BaseDatos::$dictionary->{$nombreTabla . 'Alias'}
				);*/
				$campos .= ', ' . BaseDatos::dameCamposAlias($nombreTabla);
			}
		}
		//Cogemos los campos y los guardamos
		self::$camposSelect = $campos;
		return($campos);
	}
	
	public static function getNombreTabla($soloPrincipal = NULL, $tablasOrigen = NULL){
		$idioma = WSLocale::$idioma;
		//Incluimos los globals para coger el valor del idioma:
		//include('comunes/globals.php');
		self::$nombreTabla = strtolower(get_called_class());
		self::getTablaRelacionada();
		//tablasOrigen debe ser un array de elementos con los siguientes valores:
			//0 ==> tabla de escaparates sólo
			//1 ==> tabla de traducciones + escaparates
			//2 ==> tabla de datos SEO + escaparates
		//Nos aseguramos de que 'tablasOrigen' exista y sea un array:
		$tablasOrigen = ($tablasOrigen == NULL) ? array(0,1,2) : $tablasOrigen;
		$tablasOrigen = (is_array($tablasOrigen)) ? $tablasOrigen : array(0,1,2);
		$consulta = ' ';
		$aliasPropio = self::getAlias();
		//$aliasPropioCodigo = ' `' .  $aliasPropio . '`.`codigo` ';
		if ($soloPrincipal || $soloPrincipal === NULL){
			$consulta .= self::$nombreTabla . ' as `' .  $aliasPropio . '` ';
		}
		//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 = self::$nombreTabla . ' as `' .  self::getAlias() . '` ';
		if ($soloPrincipal === false || $soloPrincipal === NULL){
			foreach ($tablasOrigen as $claveTabla => $exportarTabla){
				$nombreTabla = '';
				if ($exportarTabla == 1){
					//Traducciones de escaparate
					$nombreTabla = 'traducesca';
					$nombreCampo = 'escaparate';
				}else if ($exportarTabla == 2){
					//Datos SEO del escaparate
					$nombreTabla = 'cesca_seo';
					$nombreCampo = 'cescaparate';
				}
				if ($nombreTabla != ''){
					$consulta .= self::getJoin(get_called_class(), array('codigo', '$' . $idioma), $nombreTabla, array($nombreCampo, 'idioma'));
				}
			}
			
		}
		$consulta .= ' ';
		if ($soloPrincipal == NULL){
			self::$nombreTabla = $consulta;
		}
		//echo($consulta);
		return($consulta);
	}
	
	public static function getWhereTabla(){
		$argumentos = func_get_args();
		$codigo = isset($argumentos[0]) ? $argumentos[0] : 0;
		$condicion = isset($argumentos[1]) ? $argumentos[1] : '';
		$activo = isset($argumentos[2]) ? $argumentos[2] : NULL;
		$limitar = isset($argumentos[3]) ? $argumentos[3] : NULL;
		
		//$aliasTraduccion = BaseDatos::$dictionary->{'traducesca' . 'Alias'};
		$aliasTraduccion = BaseDatos::dameAlias('traducesca');
		//$aliasSeoEsca = BaseDatos::$dictionary->{'cesca_seo' . 'Alias'};
		$aliasSeoEsca = BaseDatos::dameAlias('cesca_seo');
		
		self::$whereSelect = '';
		if ($condicion != ''){
			self::$whereSelect .= ' `' .  self::getAlias() . '`.`condicion` = "' . $condicion . '" ';
		}else if (is_numeric($codigo)){
			self::$whereSelect .= ' `' .  self::getAlias() . '`.`codigo` = "' . $codigo . '" ';
		}else if ($codigo != NULL){
			self::$whereSelect .= ' `' .  $aliasTraduccion . '`.`nombre` LIKE "' . $codigo . '" OR `' .  $aliasSeoEsca . '`.`nombre` LIKE "' . $codigo . '" ';
		}
		
		if ($activo !== NULL){
			self::$whereSelect .= ( (self::$whereSelect != '') ? ' AND ' : '') . ' `' .  self::getAlias() . '`.`activo` = "' . $activo . '" ';
		}
		
		if ($limitar){
			self::$whereSelect .= ' LIMIT 0,1 ';
		}
		return(self::$whereSelect);
	}
	
	//Constructor y destructor
	function __construct($codigo = 0, $nivel_maximo = 99999, $condicion = NULL, $activo = 1, $nivel = 0, $padre = NULL, $filtrado_previo = ''){
		//echo('<!-- El nivel máximoa cargar es: $nivel_maximo -->\n');
		//include('comunes/globals.php');
		//Vamos a convertir esta clase en una v2
		$filaEscaparate = NULL; // ==> Aquí podemos pasar el resultado de una select de escaparate, lo que nos dará los campos directamente para insertarlos
		$filtrado_actual = '';
		if (is_a($codigo, 'OpcionesWidget')){
			//Recogemos las opciones del 'OpcionesWidget'
			$opciones = $codigo;
			$codigo = 0;
			$codigo = ($opciones->configuracion->codigo !== NULL) ? $opciones->configuracion->codigo : $codigo;
			$nivel_maximo = ($opciones->configuracion->nivel_maximo !== NULL) ? $opciones->configuracion->nivel_maximo : $nivel_maximo;
			$condicion = ($opciones->configuracion->condicion !== NULL) ? $opciones->configuracion->condicion : $condicion;
			$activo = ($opciones->configuracion->activo !== NULL) ? $opciones->configuracion->activo : $activo;
			$nivel = ($opciones->configuracion->nivel !== NULL) ? $opciones->configuracion->nivel : $nivel;
			$padre = ($opciones->configuracion->padre !== NULL) ? $opciones->configuracion->padre : $padre;
			$filtrado_previo = ($opciones->configuracion->filtrado_previo !== NULL) ? $opciones->configuracion->filtrado_previo : $filtrado_previo;
			$filaEscaparate = ($opciones->configuracion->filaEscaparate !== NULL) ? $opciones->configuracion->filaEscaparate : $filaEscaparate;
			$filtrado_actual = ($opciones->configuracion->filtrado_actual != NULL) ? $opciones->configuracion->filtrado_actual : $filtrado_actual;			
		}
		$this->cargarSoloActivos = $activo;
		
		$this->adaptarFiltrado($filtrado_previo); //TODO
		
		//Hemos recibido un padre por referencia, y lo asignamos de la misma forma para no ocupar más memoria
		$this->padre = &$padre;
		//$this->nivel = $nivel;

		$sentencia_sql = $sentencia_sql = 'SELECT ' . self::getCampos() . ' '
							. 'FROM ' . self::getNombreTabla() . ' '
							. 'WHERE ' . self::getWhereTabla($codigo, $condicion, $activo) . ';';
		
		
		//echo("$sentencia_sql\n<br />");
		
		//Puede que hayamos recibido una fila, en cuyo caso no es necesario hacer la select:
		if ($filaEscaparate == NULL){
			$bd = new BaseDatos();
			if ($bd->isConectado()){
				//echo($sentencia_sql);
				$bd->setConsultaSQL($sentencia_sql);
				if (!$fila = $bd->getFila()){
					$fila = NULL;
				}
			}
		}else{
			$fila = $filaEscaparate;
		}
		
		$aliasEscaparate = self::getAlias();
		//$aliasTraduccion = BaseDatos::$dictionary->{'traducesca' . 'Alias'};
		$aliasTraduccion = BaseDatos::dameAlias('traducesca');
		//$aliasSeoEsca = BaseDatos::$dictionary->{'cesca_seo' . 'Alias'};
		$aliasSeoEsca = BaseDatos::dameAlias('cesca_seo');
		if ($fila != NULL){
			$this->codigo = $fila[$aliasEscaparate . '_' . 'codigo'];
			$this->nombre_natural = $fila[$aliasTraduccion . '_' . 'nombre'];
			$this->descripcion = $fila[$aliasTraduccion . '_' . 'descripcion'];
			$this->nombre_seo = $fila[$aliasSeoEsca . '_' . 'nombre'];
			$this->nombre_seo = ($this->nombre_seo == '') ? $this->nombre_natural : $this->nombre_seo;
			$this->estilo_seleccionado = $fila[$aliasEscaparate . '_' . 'estilo_seleccionado'];
			$this->estilo_no_seleccionado = $fila[$aliasEscaparate . '_' . 'estilo_no_seleccionado'];
			$this->ocultar_en_buscadores = $fila[$aliasEscaparate . '_' . 'ocultar_en_buscadores'];
			$this->orden = $fila[$aliasEscaparate . '_' . 'orden'];
			$this->fecha_ultima_modif = $fila[$aliasEscaparate . '_' . 'fecha_ultima_modif'];
			$this->fecha_alta = $fila[$aliasEscaparate . '_' . 'fecha_alta'];
			$this->condicion = $fila[$aliasEscaparate . '_' . 'condicion'];
			$this->activo = $fila[$aliasEscaparate . '_' . 'activo'];
			$this->importe_minimo_g_envio_gratis = $fila[$aliasEscaparate . '_' . 'importe_minimo_g_envio_gratis'];
			$this->nivel = $fila[$aliasEscaparate . '_' . 'nivel'];
			$this->rama = $fila[$aliasEscaparate . '_' . 'rama'];
			$this->title_seo = $fila[$aliasSeoEsca . '_' . 'title'];
			$this->keywords_seo = $fila[$aliasSeoEsca . '_' . 'keywords'];
			$this->descripcion_seo = $fila[$aliasSeoEsca . '_' . 'descripcion'];

/*			//EL id era la ruta completa de este escaparate. Ahora tenemos la rama
			if ($this->padre != NULL){
				$this->id = $this->padre->id . ( ($this->padre->id != '') ? '_' : '' ) . $this->codigo;
			}
*/
		}
		//Si el escaparate actual es el que tenemos seleccionado, hay que recorrer recursivamente hacia arriba 
		$escaparate_actual = Sections::getParam('escaparate');
		//Tras hacerme un esquema veo que el escaparate que yo he cargado contiene una rama, para saber si está dentro de la "linea"
		// de escaparates seleccionados sólo tengo que comprobar la rama del seleccionado. Si la rama del seleccionado COMIENZA con la rama 
		// del escaparate actual, entonces está seleccionado tb
		if (is_object($escaparate_actual)){
			if (substr( $escaparate_actual->rama, 0, strlen($this->rama) ) === $this->rama){
				$this->rama_seleccionada = true;
			}
		}

		//si no hay código, el objeto está vacío
		if ($this->codigo == 0){
			//Indicamos que el objeto está vacío y no sirve
			$this->objeto_vacio = 1;
		}
		
		//Por último componemos la url de este escaparate
		$this->url = corregir_url(Shop::$configuracion->url . (str_replace('/', '_', $this->nombre_seo)));
		//echo("URL :" . $this->url . "<br />\n");
		
		
		//Ahora vamos a componer la select que nos dará los productos de este escaparate:
		//---------------------------------------------------------------------------------------------
		//Inicializamos la consulta que dará pie a una lista de productos asociada:
		//---------------------------------------------------------------------------------------------
		//$aliasCategoriasProductos = BaseDatos::$dictionary->{'categorias_productos' . 'Alias'};
		$aliasCategoriasProductos = BaseDatos::dameAlias('categorias_productos');
		$this->nombreTablas = ' `categorias-productos` as `' . $aliasCategoriasProductos . '`, ' . Articulo::getNombreTabla();
		$this->camposTabla = 'DISTINCT(`' . Articulo::getAlias() . '`.`codigo`) codigo_articulo, 
								`' . Articulo::getAlias() . '`.`fecha_alta` fecha_alta, ' . Articulo::getCampos();
		$this->whereTabla = ' `' . $aliasCategoriasProductos . '`.articulo = `' . Articulo::getAlias() . '`.codigo '
								. ' AND `' . $aliasCategoriasProductos . '`.`orden` >= ' . $this->nivel * 10000;
		if ($this->codigo > 0){
			$this->whereTabla .= ' AND `' . $aliasCategoriasProductos . '`.`categoria` = ' . $this->codigo . ' ';
		}
		//Creamos el orden:
		$this->crea_orden(' ORDER BY `' . $aliasCategoriasProductos . '`.orden ASC, `' . Articulo::getAlias() . '`.codigo DESC ');
		//Y la paginación
		$this->crea_paginacion();
		//Seteamos los filtrados correspondientes:
		$this->adaptarFiltrado($filtrado_actual, true); //==> Encargado de generar los filtrados de sesión o temporales del usuario
		$this->filtradoGlobal();						//==> Encargado de generar los filtrados globales de la web
	}

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

	//TODO ==> Más adelante alimentaremos esta info desde SINLIB
	public function carga_miga(){
		//Cuando se crea un escaparate, no se inserta el padre a no ser que se haya creado de forma recursiva.
		//Para esos casos, esta función carga el escaparate padre y lo inserta en el campo "escaparate padre"
		include('comunes/globals.php');
		$sentencia_sql = 'SELECT escaparate_padre FROM cescaparate WHERE codigo = ' . $this->codigo;
		if ($resultado = mysqli_query($conexionBD, $sentencia_sql)){
			if($fila = mysqli_fetch_array($resultado)){
				if ($fila['escaparate_padre'] != 0){
					$this->padre = new Escaparate($fila['escaparate_padre'], 1);
					$this->padre->carga_miga();
				}
			}
		}

	}

	public function cargar_hijos(){
		//include('comunes/globals.php');

		//Ahora vamos a ver si hay que cargar los hijos del escaparate:
		$sentencia_sql = 'SELECT ' . self::getCampos() . ' 
							FROM ' . self::getNombreTabla() . ' '
							. ' WHERE '
							. '`' . self::getAlias() . '`.`rama` LIKE "' . $this->rama . '%" ';
		if ($this->codigo > 0){
			$sentencia_sql .= ' AND `' . self::getAlias() . '`.`codigo` != ' . $this->codigo . ' ';
		}
		if ($this->cargarSoloActivos != NULL){
			$sentencia_sql .= ' AND `' . self::getAlias() . '`.`activo` = ' . $this->cargarSoloActivos . ' ';	
		}
		$sentencia_sql .= ' ORDER BY '. '`' . self::getAlias() . '`.`nivel` ASC, `' . self::getAlias() . '`.`orden` ASC';
		//Vamos a cargar los hijos
		//Vamos a hacer la select y a recorerla:
		$bd = new BaseDatos();
		if ($bd->isConectado()){
			$bd->setConsultaSQL($sentencia_sql);
			while ($fila = $bd->getFila()){
				/*echo('<pre>');
				var_dump($fila);
				echo('</pre>');*/
				$rama = $fila[self::getAlias() . '_rama'];
				//Tenemos que limpiar la rama para sacar desde este elemento en adelante:
				//echo('Tenemos la rama ' . $rama);
				$cadBuscar = '-' . strval($this->codigo);
				$pos = strpos($rama, $cadBuscar);
				//Si no se ha encontrado nada, entonces vamos desde el principio:
				if ($pos === false){
					$pos = 0;
					$cadBuscar = '';
				}
				$rama = substr($rama, $pos + (strlen($cadBuscar)));
				$this->insertarSubEscaparate($rama, $fila);
			}
		}
		if (count($this->hijos) > 0){
			$this->objeto_vacio = 0;
		}
		$this->hijosCargados = true;
	}
	
	public function muestraEstructura(){
		echo("Escaparate: " . $this->nombre_natural . " " . $this->nivel . " " . $this->rama . "\n");
		if ($this->hijosCargados){
			echo("hijos cargados\n");
		}else{
			echo("hijos NO cargados\n");
		}
		foreach ($this->hijos as $clave => $valor){
			$valor->muestraEstructura();
		}
	}
	
	public function insertarSubEscaparate($rama, $fila){
		//Rama es una cadena con los códigos de los escaparates separados por guiones: "-"
		//La convertimos en un array para ver su longitud:
		$rama = explode('-', $rama);
		if (count($rama) > 1){
			//Aún tenemos que seguir bajando de nivel, vamos a quitar extraer el primer nivel para utilizarlo:
			$primerElemento = $rama[0];
			$rama = array_slice($rama, 1);
			$rama = implode($rama, '-');
			$this->hijos[$primerElemento]->insertarSubEscaparate($rama, $fila);
			//Indicamos que los hijos de este elemento se han cargado
		}else{
			//Como es sólo uno, creamos el escaparate:
			$this->hijos[$rama[0]] = New Escaparate(new OpcionesWidget(array('filaEscaparate' => $fila)));
			//Este es el proceso de cargar hijos, hay que indicar que están todos cargados:
			$this->hijos[$rama[0]]->hijosCargados = true;
			$this->hijos[$rama[0]]->padre = &$this;
			//Este objeto ya no está vacío
			$this->objeto_vacio = 0;
		}
	}
	
	/*public function cargar_productos_escaparate($pagina_actual = 0, $lista_codigos_escaparate = NULL, $cantidad_a_cargar = NULL, $codigos_a_quitar = ""){
		include("comunes/globals.php");
		if ($cantidad_a_cargar == NULL){
			$cantidad_a_cargar = Shop::$configuracion->elementos_por_pagina;
		}
		//No hay que quitar códigos porque ya no es necesario.
		//Si hay conexión con la Bd:
		$bd = new BaseDatos();
		if ($bd->isConectado()){
			//Primero vamos a ver qué orden tiene el escaparate: ==> Esto hay que cambiarlo, por ahora lo vamos dejando igual por la retrocompatibilidad
			$orden_productos = ' ORDER BY `categorias-productos`.orden ASC, `' . Articulo::getAlias() . '`.codigo DESC ';
			$this->crea_orden($orden_productos);
			//Si tenemos un orden especial, hay que añadir los campos a la select
			$campos_add = "";
			if (strtoupper(trim($this->orden_select)) != $orden_productos){
				//echo ($this->orden_select);
				$array_campos = explode(",", str_replace("ORDER BY", "", $this->orden_select));
				foreach($array_campos as $clave => $valor){
					$valor =  explode(" ", trim($valor));
					$campos_add .= ", " . $valor[0];
				}
			}
			
			$sentencia_sql = 'SELECT DISTINCT(`' . Articulo::getAlias() . '`.codigo) codigo_articulo, 
								`' . Articulo::getAlias() . '`.`fecha_alta` fecha_alta' . $campos_add . ', ' . 
								Articulo::getCampos() . ' 
								FROM `categorias-productos`, ' . Articulo::getNombreTabla() . ' 
								WHERE 
								`categorias-productos`.articulo = `' . Articulo::getAlias() . '`.codigo
								AND `categorias-productos`.orden >= ' . $this->nivel * 10000 . ' 
								AND `' . Articulo::getAlias() . '`.no_web = 0 
								AND `' . Articulo::getAlias() . '`.ean != "" ';
			//Si no hay código de escaparate es porque se van a cargar todos los productos:
			if ($this->codigo > 0){
				$sentencia_sql .= ' AND `categorias-productos`.categoria = ' . $this->codigo . ' ';
			}
			if ($this->filtrado != ''){
				$sentencia_sql .= ' AND ' . $this->filtrado  . ' ';
			}
			//$sentencia_sql .= $this->filtrado . ' ';
			//echo("$sentencia_sql<br />\n");
			$bd->setConsultaSQL($sentencia_sql);
			//echo("$sentencia_sql<br />\n");
			//$this->total_articulos = mysqli_num_rows(mysqli_query($conexionBD, $sentencia_sql));
			$this->total_articulos = $bd->getNumeroFilas();
			//Vamos con la paginación
			$elemento_inicial = $cantidad_a_cargar * $pagina_actual;
			$this->paginacion_select = ' LIMIT ' . $elemento_inicial . ', ' . $cantidad_a_cargar;
			//la consulta la hacemos sobre la sentencia_sql generada porque contiene los filtrados. A parte hemos dejado intacta la sentencia_select original
			//Guardamos la consulta en el escaparate
			$this->sentencia_select = $sentencia_sql;
			//echo("$sentencia_sql<br />\n");
			//Y para sacar los productos le añadimos el orden y la paginación
			$sentencia_sql .= $this->orden_select . $this->paginacion_select;
			//Ahora vamos a cargar los artículos en el escaparate
			//echo("$sentencia_sql<br />\n");
			$bd->setConsultaSQL($sentencia_sql);
			$nuevaLista = array();
			//var_dump($this->lista_articulos);
			while ($fila = $bd->getFila()){
				$nuevaLista[] = new Articulo(new OpcionesWidget(array('filaArticulo' => $fila)));
			}
			$this->lista_articulos = array_merge($this->lista_articulos, $nuevaLista);
			//var_dump($this->lista_articulos);
			//Si la página es mayor que 0, tenemos que incluirla en el title
			if ($pagina_actual > 0){
				$this->title_seo .= ', ' . traducir('página') . ' ' . ($pagina_actual + 1);
			}
		}
	}*/
	
}
