entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

ayuda con lógica para filtrar productos en php

Hola que tal gente, estoy intentando crear un menú de filtros que permita al usuario filtrar los productos de una tienda por más de un parámetro a la vez si así lo quisiera, por ejemplo si el usuario se encuentra en la categoría de calzados y elige filtrar por el tipo de producto botas, pues mostraría todos los productos de calzado que sean botas, pero si también se le antoja filtrar por otro tipo de producto como por ejemplo tennis, pues en vez de mostrar solo los productos de calzado que sean tenis debería añadirse al filtro que existía anteriormente en este caso el de botas y mostrar botas y tenis. Pero no consigo lograr hacer esto, por eso les pido su ayuda con este código:

FORM

<form id="form-filter" name="form-filter">
    <div class="form-wrapper small">

        <div class="input-wrapper">
            <button class="navbar-button form-label" type="button" id="product-btn">TIPO DE PRODUCTO <span class="form-span"><i class="fas fa-caret-down"></span></i></button>

            <?php $tipoProductos = Utils::showTiposProductos(); ?>
            <div class="product-wrapper" id="produc-category">
                <?php while($tipo = $tipoProductos->fetch_object()): ?> 
                    <label class="label-wrapper" for="<?=$tipo->nombre?>"><?=$tipo->nombre?>
                        <input class="checkbox" type="checkbox" name="id_tipo" id="<?=$tipo->nombre?>" value="<?=$tipo->id?>">
                        <span class="checkmark"></span>   
                    </label>
                <?php endwhile; ?> 
            </div>
        </div>

    </div>
</form>   

Les explico brevemente con la función: Utils::showTiposProductos(); recojo todos los tipos de productos una categoría y luego itero con un ciclo while para generar un checkbox por cada tipo de producto que haya en una categoría. Con una función de js capturo el name y el value del/los input checkbox que estén checkeados y se los envió por GET a mi controlador.

CONTROLADOR

<?php
require_once 'models/Categoria.php';
require_once 'models/Producto.php';

class CategoriaController{

    public function filtro(){
        if (isset($_GET['id_tipo'])) {
            $id_tipo = $_GET['id_tipo'];

            $tipo = new Categoria();
            $tipo->setId($id_tipo);

            $tipo = $tipo->getOneType();

            $producto = new Producto();
            $producto->setTipo_id($id_tipo);

            $productos = $producto->getAllType();

        }

        require_once 'views/categoria/ver.php';
    }

}

De nuevo les explico brevemente, con if isset valido que lo que sea que le este llegando por GET exista, y luego le asigno ese valor a una variable que en este caso se llama $id_tipo, luego procedo a crear un objeto de la clase categoría y le asigno a setId el valor que hay en la variable $id_tipo después ejecuto el método del modelo Categoría.php:

getOneType();

public function getOneType(){
        $tipo = $this->db->query("SELECT * FROM tipo_productos WHERE id = {$this->getId()}");
        return $tipo->fetch_object();
    }

Posteriormente creo un objeto de la clase producto y le asigno a setTipo_id el valor que hay en la variable $id_tipo, luego ejecuto el método del modelo Producto.php:

getAllType()

public function getAllType(){
        $sql = "SELECT p.*, tp.nombre AS 'tiponombre' FROM productos p "
                . "INNER JOIN tipo_productos tp ON tp.id = p.tipo_id "
                . "WHERE p.tipo_id = {$this->getTipo_id()} "
                . " ORDER BY id DESC";
        $productos = $this->db->query($sql);
        return $productos;
    }

Finalmente cargo la vista ver.php la cual muestra los productos filtrados.

PD: ese no es todo el formulario completo es solo un fragmento existen mas input checkbox y tampoco es toda la lógica del controlador existen mas condicionales if isset.

2 Respuestas

3votos

magarzon Puntos26710

Varias cosas erróneas en tu código.

Para empezar, en principio, en la variable $id_tipo vas a obtener un array de valores (aunque es probable que si por alguna razón en la lista de tipos solo haya un tipo, recibas directamente el valor, ten cuidado con esto).

Pero luego, tanto en la función getOneType como en la función getAllType utilizas en la expresión WHERE una condición de igualdad, que nunca se va a dar, porque en ambos casos, el valor de $this->getId() y $this->getTipo_id() es un array de PHP.

Tendrías que substituir en el WHERE la condición de igualdas (el =) por un IN (condición de inclusión), y tranformar el array PHP en una lista separada por comas, tal que así:

'WHERE p.tipo_id IN ('. implode(',', $this->getTipo_id().')'

Ten en cuenta que además en la sintaxis de MySQL la lista tiene que estar entre paréntesis. Además, es posible que haya que forzar a que cada valor del array esté entre comillas, si son string (no lo he probado). En ese caso el implode solo no te valdría y tendrías que hacer una función propia.

Por otro lado, en el getOneType(), o bien coges el primer elemento del array que está en $this->getId(), o bien utilizas otra vez el IN y coges el primer resultado de la consulta.

0voto

elaprendiz comentado

hola magarzon he intentado reemplazando la linea de código de la función getAllType(); con la que tu has posteado y me arroja un error de sintaxis y si la escribo de la siguiente forma:

"WHERE p.genero_id IN ('. implode(',', $this->getGenero_id().') "
me arroja este error: Undefined property: Producto::$getGenero_id.

También he intentado modificar la función getOneType(); y me ha quedado así:

getOneType();

public function getOneType(){
        $tipo = $this->db->query("SELECT * FROM tipo_productos WHERE id IN (".implode(",", $this->getId()).")");
        return $tipo->fetch_object();
    }

Pero no se si me he equivocado escribiendo la función, si no es mucha molestia podrías darme un ejemplo de como quedarían ambas funciones getOneType(); y getAllType(); modificadas para que incluyan IN.

2votos

elaprendiz Puntos380

Me auto respondo al final solucione el problema lo que faltaba era un paréntesis, la función getAllType(); quedo asi:

getAllType();

public function getAllType(){
        $sql = "SELECT p.*, tp.nombre AS 'tiponombre' FROM productos p "
                . "INNER JOIN tipo_productos tp ON tp.id = p.tipo_id "
                . "WHERE p.tipo_id IN (". implode(',', $this->getTipo_id()).") "
                . " ORDER BY id DESC";
        $productos = $this->db->query($sql);
        return $productos;
    }

Ahora todo funciona como queria, muchas gracias por tu ayuda magarzon.

0voto

Peter comentado

Gracias por compartirlo. Si esta es la solución, marca esta respuesta como correcta.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta