<?php
/**
*  Clase Apartado que contiene los datos de una sección con datos SEO y esas cosas
*  @version 1.0
 **/
 
 //En esta clase hay que tener en cuenta que los productos tienen una nueva forma de cargarse
 
class SuperApartado extends Objeto{
	public static $campos_tabla = array();
	public static $alias = '';
	public static $nombreTabla = '';
	public static $camposSelect = '';
	public static $whereSelect = '';
	public static $publicFieldList = array();

    public $nombre_seo = '';
    public $title_seo = '';
    public $keywords_seo = '';
    public $descripcion_seo = '';
    public $url = '';
    public $lista_articulos = array();
    public $total_articulos = 0;
	public $array_filtro = array();

	//Aquí almacenamos todo lo referente con la select que vamos a hacer para cargar productos
	public $nombreTablas;
	public $camposTabla;
	public $countCamposTabla;
	public $whereTabla;
	public $orden_select;
	public $sentencia_sql;
	public $sentencia_sql_count;
	public $filtrado_especifico = '';
	public $filtrado_global = '';
	public $paginacion_select;

	function __construct(){
		parent::__construct();
	}
	
	//Adaptar filtrado lo que hace es generar una cadena de filtrado cogiendo el filtrado que haya aplicado en la web
    public function adaptarFiltrado($nuevo_filtrado, $filtradoBusqueda = false) {
		$this->filtrado_especifico = array();
		if (is_array($nuevo_filtrado)){
			if (count($nuevo_filtrado) > 0){
				$this->array_filtro = $nuevo_filtrado;
				foreach($nuevo_filtrado as $campo => $valores){
					//$campo es el campo que queremos filtrar y $valores es un array con los valores:
					switch($campo){
						case 'editorial':
						case 'fabricante':
							$campo = 'editorial';
						case 'autor':
						case 'distribuidor':
							//Este filtrado lo podemos aplicar sacándolo desde la misma ficha del producto:
							$cadena = '';
							$or = '';
							foreach($valores as $indice => $valor){
								$valor = urldecode($valor);
								//echo('Valor ' . $indice . ' - ' . $valor . '<br />');
								$cadena .= $or . ' `' . Articulo::getAlias() . '`.`' . $campo . '` LIKE \'' . $valor . '\' ';
								$or = ' OR ';
							}
							$this->filtrado_especifico[] = ' ( ' . $cadena . ' ) ';
						break;
						case 'categoria':
							//Para este filtrado necesitamos una select y puede hacer más lentos los resultados
							$cadena = '';
							$or = '';
							//$aliasTraduccion = BaseDatos::$dictionary->{'traducesca' . 'Alias'};
							$aliasTraduccion = BaseDatos::dameAlias('traducesca');
							//$aliasCategoriasProductos = BaseDatos::$dictionary->{'categorias_productos' . 'Alias'};
							$aliasCategoriasProductos = BaseDatos::dameAlias('categorias_productos');
							foreach($valores as $indice => $valor){
								$valor = urldecode($valor);
								//echo('Valor ' . $indice . ' - ' . $valor . '<br />');
								//Vamos a crear una select que me de los códigos de artículos que estén dentro de la lista especificada:
								$select_productos = 'SELECT `' . $aliasCategoriasProductos . '`.`articulo` '
										. ' FROM `categorias_productos` as `' . $aliasCategoriasProductos  . '`, '
										. ' `traducesca` as `' . $aliasTraduccion . '` '
										. ' WHERE `' . $aliasTraduccion . '`.`nombre` LIKE \'' . $valor . '\' '
										. ' AND `' . $aliasTraduccion . '`.`escaparate` = `' . $aliasCategoriasProductos  . '`.`categoria` ';
								//echo("<br />$select_productos<br />");
								$cadena .= $or . ' `' . Articulo::getAlias() . '`.`codigo` IN (' . $select_productos . ') ';
								$or = ' OR ';
							}
							$this->filtrado_especifico[] = ' ( ' . $cadena . ' ) ';
						break;
						case 'disponibilidad':
						case 'stock':
							//Para este filtrado necesitamos componer una select que muestre los articulos con stock mayor que cero
							$valores[0] = strtolower($valores[0]);
							if( $valores[0] == 'disponible' || $valores[0] == 'disponibles'){
								$this->filtrado_especifico[] = ' ( `' . Articulo::getAlias() . '`.`stock` > 0 ) ';
							}
						break;
						case 'precio':
							//Para este filtrado necesitamos componer una select que muestre un rango de precio
							// $valores[0] = strtolower($valores[0]);
							// if( $valores[0] == 'disponible' || $valores[0] == 'disponibles'){
							// 	$this->filtrado_especifico[] = ' ( `' . Articulo::getAlias() . '`.`stock` > 0 ) ';
							// }
						break;
					}
				}
			}
		}
        //$this->filtrado_especifico = ( ($this->filtrado_especifico != '') ? ' AND ' : '' ) . $this->filtrado_especifico;
		if (count($this->filtrado_especifico) > 0){
			$this->filtrado_especifico = implode(' AND ', $this->filtrado_especifico);
		}else{
			$this->filtrado_especifico = '';
		}
    }

	public function getStringFiltrado(){
		$retorno = '';
		//Esta función saca el array de filtrado y lo pasa a string:
		if (is_array($this->array_filtro)){
			if (count($this->array_filtro) > 0){
				foreach($this->array_filtro as $campo => $valores){
					if (count($valores) > 0){
						foreach($valores as $indice => $valor){
							$retorno .= '/filtrar_' . $campo . '=' . $valor;
						}
					}
				}
			}
		}
		return($retorno);
	}
	
	//Filtrado global asignará el filtrado global de la web definido en configuración o mediante diferentes parámetros
	public function filtradoGlobal(){
		$this->filtrado_global = array();
		//Desde este punto se colocan los filtrados según la configuración
        //Ahora vamos a tener en cuenta que haya que tener en cuenta el stock
        //Cargamos Filtrados
        if (Shop::$configuracion->ocultar_stock_0) {
            $this->filtrado_global[] = '`' . Articulo::getAlias() . '`.stock > 0 ';
        }
		//Aquí vamos a tener en cuenta las búsquedas de papelería
		if (Shop::$configuracion->busquedas_papeleria == 0){
			$this->filtrado_global[] = ' (tipo != \'P\') ';
		}
        //Añadimos un filtrado general que se añadira siempre
        if (Shop::$configuracion->filtroGlobal != '') {
			$cadenaFiltradoConfiguracion = Shop::$configuracion->filtroGlobal;
			//Necesitamos traducir el filtro global pues puede tener entre corchetes nombres de tablas:
			preg_match_all('~\[class\](.*?)\[\/class\]~', $cadenaFiltradoConfiguracion, $listaClases);
			$listaClases = $listaClases[1];

			//Vamos a recorrer la lista de clases que hemos obtenido puesto que hay que cambiarlas por el alias:
			if (count($listaClases) > 0){
				foreach($listaClases as $indiceClase => $clase){
					//Si la clase indicada existe, vamos a ver si tiene el método de get alias definido
					if (class_exists($clase)){
						if (method_exists($clase, 'getAlias')){
							$newTableName = '`' . $clase::getAlias() . '`';
							$cadenaFiltradoConfiguracion = str_replace('[class]' . $clase . '[/class]', $newTableName, $cadenaFiltradoConfiguracion);
							//echo($cadenaFiltradoConfiguracion . "<br>\n");
						}
					}
				}
			}
			$this->filtrado_global[] = $cadenaFiltradoConfiguracion;
        }

        //echo("El filtrado es: " . $this->filtrado_especifico . "<br />\n");
        //filtrado por artículo padre
        //Filtrado por configuración
        //var_dump(Shop::$configuracion->segundaMano);
        if (Shop::$configuracion->segundaMano) {
            $this->filtrado_global[] = ' `' . Articulo::getAlias() . '`.articulo_padre = 0 ';
        }
		//Ahora tenemos un array con el filtrado global, vamos a componer una cadena:
		if (count($this->filtrado_global) > 0){
			$this->filtrado_global = implode(' AND ', $this->filtrado_global);
			//echo($this->filtrado_global . "<br/>\n");
		}else{
			$this->filtrado_global = '';
		}
	}
	
    public function extraerCodigo($enArray = false, $codigo_inicial = NULL) {
        $lista_codigos = '';
        if (($codigo_inicial != NULL) && ($codigo_inicial != '')) {
            $lista_codigos = $codigo_inicial;
        }
        foreach ($this->lista_articulos as $clave => $valor) {
            $lista_codigos .= ", '" . $valor->codigo . "'";
        }

        if ($enArray) {
            $lista_codigos = explode(',', $lista_codigos);
        }
        return($lista_codigos);
    }

    public function crea_orden($cadena_inicial, $overSession = false) {
        $this->orden_select = " $cadena_inicial ";
        //Miramos si hay orden en la sesión. Si lo hubiese, hay que asignarlo
		if ( ($cadena_inicial == '') || (!$overSession) ){
			$orderOfProducts = Sesion::get('orderOfProducts');
			if ($orderOfProducts !== NULL) {
				if (strtoupper($orderOfProducts) != 'DEFAULT') {
					$this->orden_select = " $orderOfProducts ";
				}
			}
		}
    }
	
	public function crea_paginacion($pagina_actual = 0, $limite = 0){
		//Inicializamos el límite de elementos a cargar
		//Pedro 23/Septiembre/2019 ==> Si tenemos elementos por página en la sesión definidos, los usamos:
		if ($limite == 0){
			$elementosPaginaActual = Sesion::get('elementosPaginaActual');
			if ($elementosPaginaActual != NULL){
				$limite = $elementosPaginaActual;
			}else{
				$limite = Shop::$configuracion->elementos_por_pagina;
			}
		}
		//Establecemos el elemento inicial
		$elemento_inicial = $limite * $pagina_actual;
		$this->paginacion_select = ' LIMIT ' . $elemento_inicial . ', ' . $limite;
	}
	
	function carga_articulos($pagina_actual = 0, $limite = NULL){
		//Si no recibimos página actual, vamos a mirar si hay página en la sesión:
		if ($pagina_actual === 0){ // ==> Nos aseguramos de que sea un 0 a huevo, nos pueden pasar un NULL
			$pagina_actual = Sections::getParam('pagina');
		}
		//Ojito que tenemos que controlar la paginación si nos han pasado límite:
		if ($limite !== NULL){
			$this->crea_paginacion($pagina_actual, $limite);
		}
		//Vamos a asegurarnos de que tenemos la select bien montada:
		//16/Octubre/2019 ==> Montamos dos sentencias en paralelo, una que me dará el "count" y otra que me dará los campos:
		$this->sentencia_sql_count = $this->sentencia_sql = ' FROM ' . $this->nombreTablas . '
							WHERE ' . $this->whereTabla;
		$this->sentencia_sql ='SELECT ' . $this->camposTabla . $this->sentencia_sql; 
		$this->sentencia_sql_count ='SELECT ' . $this->countCamposTabla . $this->sentencia_sql_count;

		$filtrados =  ( ($this->filtrado_global != '') ? ' AND ' . $this->filtrado_global : '' ) . "\n"
			. ( ($this->filtrado_especifico != '') ? ' AND ' . $this->filtrado_especifico : '');
		$this->sentencia_sql .= "\n" . $filtrados;
		$this->sentencia_sql_count .= "\n" . $filtrados;
		/*echo('<!--');
		echo($this->sentencia_sql . "\n");
		echo('-->');*/
		//echo($this->sentencia_sql);
		//Ejecutamos la select para contar cuantos elementos hay
		if ($this->sentencia_sql != ''){
			$bd = new BaseDatos();
			if ($bd->isConectado()){
				//echo("$this->sentencia_sql_count<br />\n");
				//echo("$this->sentencia_sql<br />\n");
				//Vamos a ejecutar la select que me dice cuantos elementos hay (la del count)
				$bd->setConsultaSQL($this->sentencia_sql_count);
				$fila = $bd->getFila(PDO::FETCH_NUM);
				if ( (is_array($fila)) && (count($fila) > 0) ){
					$this->total_articulos = $fila[0];
				}

				//Ahora es el momento de añadir el orden junto con la paginación
				$consulta = $this->sentencia_sql . $this->orden_select . $this->paginacion_select;

				//Ahora vamos a cargar los artículos en el escaparate
				//$tiempo_ini = microtime(true);
				if ($bd->setConsultaSQL($consulta)){
					while ($fila = $bd->getFila()){
						$this->lista_articulos[] = new Articulo(new OpcionesWidget(array('filaArticulo' => $fila)));
					}
				}
				//$tiempo_ini = microtime(true) - $tiempo_ini;
				//echo("<br />la consulta tardó $tiempo_ini milisegundos. Hay " . $this->total_articulos . " resultados<br />");
				if ($pagina_actual > 0){
					$this->title_seo .= ", " . traducir('página') . ' ' . ($pagina_actual + 1);
				}

			}
		}
	}

	public function getTotalSinFiltrado(){
		$total = $this->total_articulos;
		if( $this->filtrado_especifico != '' ){
			$bd = new BaseDatos();
			if ($bd->isConectado()){
				$sentencia_sql_count = $this->sentencia_sql = ' FROM ' . $this->nombreTablas . '
									WHERE ' . $this->whereTabla;
				$sentencia_sql_count ='SELECT ' . $this->countCamposTabla . $sentencia_sql_count;
				$filtrados =  ( ($this->filtrado_global != '') ? ' AND ' . $this->filtrado_global : '' );
				$sentencia_sql_count .= "\n" . $filtrados;

				$bd->setConsultaSQL($sentencia_sql_count);
				$fila = $bd->getFila(PDO::FETCH_NUM);
				if ( (is_array($fila)) && (count($fila) > 0) ){
					$total = $fila[0];
				}
			}
		}
		return ($total);

	}
	
	public function cleanListaArticulos(){
		foreach ($this->lista_articulos as $clave => $valor){
			unset($this->lista_articulos[$clave]);
		}
		$this->lista_articulos = array();
	}
}
