<?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
*/
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;
	
	//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
		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;
			
		}
		$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;
		
		//Redefinimos los alias porque los necesitamos
		$aliasEscaparate = 'a';
		$aliasTraduccion = 'b';
		$aliasSeoEsca = 'c';

		$sentencia_sql = $this->selectEscaparate();		
		
		//Orden de preferencia es: Condición, escaparate con código numérico, escaparate por nombre
		$where_select = '';
		if ($condicion != ''){
			$where_select .= ' `' .  $aliasEscaparate . '`.`condicion` = "' . $condicion . '" ';
		}else if (is_numeric($codigo)){
			$where_select .= ' `' .  $aliasEscaparate . '`.`codigo` = "' . $codigo . '" ';
		}else if ($codigo != NULL){
			$where_select .= ' `' .  $aliasTraduccion . '`.`nombre` LIKE "' . $codigo . '" OR `' .  $aliasSeoEsca . '`.`nombre` LIKE "' . $codigo . '" ';
		}
		
		if ($activo != NULL){
			$where_select .= ( ($where_select != '') ? ' AND ' : '') . ' `' .  $aliasEscaparate . '`.`activo` = "' . $activo . '" ';
		}
		
		if ($where_select != ''){
			$sentencia_sql .= ' WHERE ' . $where_select;
		}

		//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;
		}
		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 
		if (is_object($escaparate_actual)){
			//echo("Estamos en el escaparate actual<br />\n");
			if ($this->codigo == $escaparate_actual->codigo){
				//Ejecutamos la función que recorre los padres indicando que estamos en la rama seleccionada
				$this->rama_seleccionada();
			}
		}

		//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)));
	}

	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]);
		}
	}

	private function selectEscaparate(){
		include('comunes/globals.php');
		//Si nos mandan un código 0, entonces intentamos cargar el escaparate por su condición
		//Cargamos este escaparate para asignar sus datos
		//Vamos a probar u nanueva forma de cargar el escaparate
		$aliasEscaparate = 'a';
		$aliasTraduccion = 'b';
		$aliasSeoEsca = 'c';
		$cadenaCamposEscaparate = BaseDatos::dameCamposAlias(
			['codigo', 'orden', 'estilo_seleccionado', 'estilo_no_seleccionado', 'ocultar_en_buscadores', 'orden', 'fecha_ultima_modif', 'fecha_alta',
			'condicion', 'activo', 'importe_minimo_g_envio_gratis', 'nivel', 'rama'],
			$aliasEscaparate
		);
		$cadenaCamposTraduccion = BaseDatos::dameCamposAlias(
			['nombre', 'descripcion'],
			$aliasTraduccion
		);	//escaparate
		$cadenaCamposSeoEsca = BaseDatos::dameCamposAlias(
			['nombre', 'title', 'descripcion', 'keywords'],
			$aliasSeoEsca
		);	//Campo enlazado cescaparate
		
		$campos_escaparate = '
							' . $cadenaCamposEscaparate . ',
							' . $cadenaCamposTraduccion . ',
							' . $cadenaCamposSeoEsca . '  ' ;
		//Preparamos el FROM con las uniones correspondientes
		$sentencia_sql = 'SELECT ' . $campos_escaparate . ' 
							FROM cescaparate `' .  $aliasEscaparate . '` 
							LEFT JOIN traducesca `' . $aliasTraduccion . '` on (`' . $aliasEscaparate . '`.`codigo` = `' . $aliasTraduccion . '`.`escaparate` AND `' . $aliasTraduccion . '`.`idioma` = "' . $idioma . '")
							LEFT JOIN cesca_seo `' . $aliasSeoEsca . '` on(`' . $aliasSeoEsca . '`.`cescaparate` = `' . $aliasEscaparate . '`.`codigo` AND `' . $aliasSeoEsca . '`.`idioma` = "' . $idioma . '" ) 
							';
		return($sentencia_sql);
	}
	
	public function rama_seleccionada(){
		$this->rama_seleccionada = true;
		if ($this->padre != NULL){
			$this->padre->rama_seleccionada();
		}
	}

	//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_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
			$this->crea_orden(' ORDER BY `categorias-productos`.orden ASC, articulo.codigo DESC ');
			//Si tenemos un orden especial, hay que añadir los campos a la select
			$campos_add = "";
			if (strtoupper(trim($this->orden_select)) != ' ORDER BY `categorias-productos`.orden ASC, articulo.codigo DESC '){
				//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.codigo) codigo_articulo, articulo.fecha_alta fecha_alta' . $campos_add . ' FROM `categorias-productos`, `articulo` WHERE 
								`categorias-productos`.articulo = `articulo`.codigo
								AND `categorias-productos`.orden >= ' . $this->nivel * 10000 . ' 
								AND `articulo`.no_web = 0 
								AND `articulo`.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 . ' ';
			}
			$sentencia_sql .= $this->filtrado . ' ';
			$bd->setConsultaSQL($sentencia_sql);
			//echo("<!-- $sentencia_sql -->");
			//$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;
			//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 -->");
			$bd->setConsultaSQL($sentencia_sql);
			while ($fila = $bd->getFila()){
				array_push($this->lista_articulos, new Articulo($fila['codigo_articulo']));
			}
			//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);
			}
		}
	}

	public function cargar_hijos(){
		include('comunes/globals.php');
		
		$aliasEscaparate = 'a';
		$aliasTraduccion = 'b';
		$aliasSeoEsca = 'c';
		
		//Ahora vamos a ver si hay que cargar los hijos del escaparate:
		$sentencia_sql = $this->selectEscaparate() . '	
							WHERE 
							`' . $aliasEscaparate . '`.`rama` LIKE "' . $this->rama . '%"
							';
		if ($this->codigo > 0){
			$sentencia_sql .= ' AND `' . $aliasEscaparate . '`.`codigo` != ' . $this->codigo . ' ';
		}
		if ($this->cargarSoloActivos != NULL){
			$sentencia_sql .= ' AND `' . $aliasEscaparate . '`.`activo` = ' . $this->cargarSoloActivos . ' ';	
		}
		$sentencia_sql .= ' ORDER BY '. '`' . $aliasEscaparate . '`.`nivel` ASC, `' . $aliasEscaparate . '`.`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[$aliasEscaparate . '_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;
		}
	}
}
?>