Foros del Web » Programando para Internet » PHP »

Problema listando categorias

Estas en el tema de Problema listando categorias en el foro de PHP en Foros del Web. Hola gente, esta noche me tuvo loco un problema que no pude resolver, ya mis neuronas no dan a basto y quiciera saber si alguien ...
  #1 (permalink)  
Antiguo 02/09/2009, 09:36
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años
Puntos: 16
Problema listando categorias

Hola gente, esta noche me tuvo loco un problema que no pude resolver, ya mis neuronas no dan a basto y quiciera saber si alguien tiene una idea que pueda horientar mejor mi busqueda.

El asunto es el siguiente. Dispongo de una tabla categorias con los siguientes atributos

tabla categorias
Código:
id,  categoria_id, Nombre
40, 	0, 		'Ecologia'
41, 	40,	 	'Educación ambiental'
42, 	40, 	         'Desarrollo Sustentable'
43, 	40,	 	'Generales'
49, 	0, 		'Gloables'
51, 	0,		 'Recursos'
52, 	51, 	       ' Recursos Hídricos'
53, 	0,		 'Política'
54, 	0, 		'Legislación Ambiental'
55, 	0, 		'Economía y Empresas'
56, 	55, 	       'Responsabilidad Social Ambiental'
57, 	52, 	       'Acuífero Guarani'
58, 	0, 		'Contaminación'
59, 	58, 	      ' Minería'
60, 	58,		'Pasteras y Papeleras'
61, 	55,		'Economía Ambiental'
62, 	0, 		'Modelo Agrario'
63, 	62, 	       'Transgénicos'
64, 	0, 		'Para Reflexionar'
65, 	0, 		'Cambio Climático'
66, 	0, 		'Biodiversidad y Ecosistemas'
67, 	0, 		'Energía'
Estas categorias son utilizadas en difrentes tipo de post y son asignadas en la tabla categorias_post
Código:
id,      categoria_id,       post_id
713, 40, 482
712, 40, 494
74, 41, 8
89, 41, 16
275, 41, 23
367, 41, 24
443, 41, 25
274, 41, 26
444, 41, 27
446, 41, 30
455, 41, 33
391, 41, 37
70, 42, 5
76, 42, 9
77, 42, 10
64, 42, 11
83, 42, 12
81, 42, 13
87, 42, 15
90, 42, 16
91, 42, 17
95, 42, 21
251, 42, 22
445, 42, 27
691, 42, 43
141, 42, 96
697, 42, 121
663, 42, 169
249, 42, 385
649, 42, 390
270, 42, 391
621, 42, 394
603, 42, 399
193, 42, 422
329, 42, 442
485, 42, 464
201, 42, 469
529, 43, 1
97, 43, 2
134, 43, 3
69, 43, 4
71, 43, 6
73, 43, 7
92, 43, 18
93, 43, 19
94, 43, 20
442, 43, 28
441, 43, 29
174, 43, 31
316, 43, 32
466, 43, 35
506, 43, 36
467, 43, 38
Los post pueden ser asignados con categorias de tipo padre o de alguna descendencia, lo que yo estaba haciendo era guardar en un array el nombre de la categoria, los datos del post y los hijos de la siguiente manera:

Código PHP:


function _list_by_categorias(){
          global 
$DbConn;
          
//Necesitamos buscar en la tabla categorias_post
          //los post asignados y separados por tipo de post
          
            
          
$sql 'SELECT * FROM categorias where categoria_id = 0';
          
          
$res $DbConn->query($sql);
          
$i 0;
          while(
$row $DbConn->fetchAssoc($res)){
            
$categorias_post[$i] = $row;
            
$categorias_post[$i]['post'] = $this->getPostByCategoriaId($row['id']);
            
$categorias_post[$i]['sub'] = $this->getCategoriasHijos($row['id']);
            
$i++;
          }
          
                    
        return 
$categorias_post
      }
      
      
      function 
getCategoriasHijos($idCategoria){
              global 
$DbConn;
            
$sql 'SELECT * FROM categorias WHERE  categoria_id = '.$idCategoria ;
              if(!
$res $DbConn->query($sql))echo mysql_error();
            
$i 0;    
                while(
$dat $DbConn->fetchAssoc($res)){
                    
$data[$i] = $dat;
                    
$data[$i]['post'] = $this->getPostByCategoriaId($dat['id']);
                    
$data[$i]['sub'] =$this->getCategoriasHijos($data[$i]['id']);
                    
$i++;
                }
                
                    
                 
            return 
$data;    
      }
      function 
getPostByCategoriaId($catId){
          global 
$DbConn;
          
$sql 'SELECT post_id, titulo FROM categorias_post AS tcat
                LEFT JOIN categorias AS tc ON tcat.categoria_id = tc.id
                LEFT JOIN post AS tp ON tcat.post_id = tp.id
                WHERE tcat.categoria_id ='
.$catId.' AND tipo_id = 2';
          
$res $DbConn->query($sql);
          
$i 0;
          while(
$row $DbConn->fetchAssoc($res)){
              
$data[$i]=$row;
              
$i++;
          }
          return 
$data;
      } 
que me da como resultado un array de este estilo:

Código:
(
    [0] => Array
        (
            [id] => 40
            [categoria_id] => 0
            [Nombre] => Ecologia
            [post] => 
            [sub] => Array
                (
                    [0] => Array
                        (
                            [id] => 41
                            [categoria_id] => 40
                            [Nombre] => Educación ambiental
                            [post] => Array
                                (
                                    [0] => Array
                                        (
                                            [post_id] => 8
                                            [titulo] => El desarrollo de una política ambiental
                                        )

                                    [1] => Array
                                        (
                                            [post_id] => 16
                                            [titulo] => Promoviendo una educación hacia el desarrollo sostenible
                                        )

                                    [2] => Array
                                        (
                                            [post_id] => 23
                                            [titulo] => Educación ambiental y desarrollo humano
                                        )

                                    [3] => Array
                                        (
                                            [post_id] => 24
                                            [titulo] => En búsqueda de una educación ambiental
                                        )

                                    [4] => Array
                                        (
                                            [post_id] => 25
                                            [titulo] => La educación ambiental como medio para una nueva ética
                                        )

                                    [5] => Array
                                        (
                                            [post_id] => 26
                                            [titulo] => Educación ambiental un intento de optimizar caminos
                                        )

                                    [6] => Array
                                        (
                                            [post_id] => 27
                                            [titulo] => La educación ambiental, vía hacia el desarrollo sostenible
                                        )

                                    [7] => Array
                                        (
                                            [post_id] => 30
                                            [titulo] => La educación y la gestión ambiental
                                        )

                                    [8] => Array
                                        (
                                            [post_id] => 33
                                            [titulo] => La evolución del concepto de educación ambiental
                                        )

                                    [9] => Array
                                        (
                                            [post_id] => 37
                                            [titulo] => Historia de la educación ambiental
                                        )

                                )

                            [sub] => 
                        )

                    [1] => Array
                        (
                            [id] => 42
                            [categoria_id] => 40
                            [Nombre] => Desarrollo Sustentable
                            [post] => Array
                                (
                                    [0] => Array
                                        (
                                            [post_id] => 5
                                            [titulo] => Los beneficios del desarrollo sostenible
                                        )

                                    [1] => Array
                                        (
                                            [post_id] => 9
                                            [titulo] => Desarrollo Sustentable
                                        )

                                    [2] => Array
                                        (
                                            [post_id] => 10
                                            [titulo] => Conciencia y Responsabilidad
                                        )


                                )

                            [sub] => 
                        )


                )

        )
  #2 (permalink)  
Antiguo 02/09/2009, 09:40
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años
Puntos: 16
Respuesta: Galleta cosmica

con esta funcion estaba recorriendo la lista

Código php:
Ver original
  1. function recorreLista($lista){
  2.     foreach($lista as $num => $data){
  3.             $html .='
  4.                 <ul>   
  5.                 <h1><a href="javascript:void(0)">'.$data['Nombre'].'</a></h1>';
  6.            
  7.             if(is_array($data[post])){
  8.                 $html .='
  9.                        
  10.                             <ul>';                     
  11.                 foreach($data[post] AS $num => $dataPost){
  12.                     $html .= '
  13.                                 <li><a href="'.ROOT_PATH.'/post/ver/id/'.$dataPost['post_id'].'"> '.$dataPost['titulo'].'</a></li>';
  14.                 }  
  15.                 $html .='
  16.                             </ul>';
  17.             }else{
  18.                 $html .= ' <ul></ul>';
  19.                 //$html .='</ul>';
  20.                
  21.             }
  22.            
  23.             if(is_array($data[sub])){
  24.                 $html .='
  25.                         <ul>';
  26.                 $html .= recorreLista($data['sub']);
  27.                 $html .='
  28.                         </ul>';
  29.             }
  30.             $html .= '</ul>';
  31.        
  32.     }
  33.     return $html;
  34.   }*/


pero en el caso de otros tipos de post se usan muy pocas categorias y se me esta complicando para filtrar solamente las que tengan un post asignados, o en la categoria padre o en alguna descendiente.

Si alguien puede ayudarme a horientarme para recorrer este array y tomar solo los arreglos que tengan un post o que tengan un post en uno de sus hijo, o en los hijos de sus hijos.
  #3 (permalink)  
Antiguo 02/09/2009, 09:59
Avatar de maycolalvarez
Colaborador
 
Fecha de Ingreso: julio-2008
Ubicación: Caracas
Mensajes: 12.120
Antigüedad: 15 años, 9 meses
Puntos: 1532
Respuesta: Galleta cosmica

Recursion es lo que necesitas.
  #4 (permalink)  
Antiguo 02/09/2009, 10:01
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Galleta cosmica

Por favor usa titulos de tema más descriptivos.
  #5 (permalink)  
Antiguo 02/09/2009, 10:24
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años
Puntos: 16
Respuesta: Galleta cosmica

Cita:
Iniciado por maycolalvarez Ver Mensaje
Recursion es lo que necesitas.
estoy utilizando una funcion recursiva, pero no se adapta a la necesidad puntual del listado, en esa funcion, recorre las categorias y subcategorias, pero lista tambien las categorias que no tienen asignadas ningun post, el problema que tengo es a la hora de filtarar las categorias que tienen contenido, a su vez si la categoria ecologia no tiene ningun post, pero si una de sus subcategorias, debe figurar igual el nombre ecologia

ecologia
medio ambiente
- post de medio ambiente


me estoy enredadon mucho, con este array, debe ser mas simple de lo que creo pero hasta ahora no logro recorrerlo perfectamente, en el caso de arriba lista todas las categorias, y en el caso de otros tipos de post queda un listado de categorias de los cuales se usan 3
  #6 (permalink)  
Antiguo 04/09/2009, 01:31
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años
Puntos: 16
Respuesta: Problema listando categorias

bueno gente, pude acomodar este listado complicado, paso a detallar por si alguien se ve envuelto en una situacion tan engorrosa como la que tuve:

estructura de la base
-Tabla categorias
Código:
id
categoria_id
nombre
- Tabla categorias_post
Código:
id
categoria_id
post_id
-Tabla post
Código:
id
tipo_id
titulo
contenido
estado
fecha_ini
fecha_mod
keywords
esta ultima no hace haria falta mostrar pero es para mostrar todas las tablas que se nombran en el codigo del listado

Obtencion de los datos antes de recorrer e imprimir
modelo->multimedia
Código php:
Ver original
  1. function getPostByCategoriaId($catId){
  2.         global $DbConn;
  3.         $sql = 'SELECT post_id, titulo FROM categorias_post AS tcat
  4.                 LEFT JOIN categorias AS tc ON tcat.categoria_id = tc.id
  5.                 LEFT JOIN post AS tp ON tcat.post_id = tp.id
  6.                 WHERE tcat.categoria_id ='.$catId.' AND tipo_id ='.$this->get('tipo_id',$this->model);
  7.         // $this->get(tipo,$this->model) es una funcion que devuelve el tipo de post
  8.        // del modelo actual, podria ser noticias, multimedia, articulos, etc
  9.         $res = $DbConn->query($sql);
  10.         $i = 0;
  11.         while($row = $DbConn->fetchAssoc($res)){
  12.             $data[$i]=$row;
  13.             $i++;
  14.         }
  15.         return $data;
  16.       }
  17.      
  18.     function getNumPostByCategoria($idCategoria){
  19.         global $DbConn;
  20.         $sql = 'SELECT COUNT(p.id) AS NUM FROM post p
  21.                 LEFT JOIN categorias_post cp ON p.id = cp.post_id
  22.                 WHERE cp.categoria_id = '.$idCategoria.' AND tipo_id = '.$this->get('tipo_id',$this->model);
  23.         $resul = $DbConn->fetchArray($DbConn->query($sql));
  24.         return $resul['NUM'];
  25.     }  
  26.    
  27.     function getNumHijosByCategoria($idCategoria){
  28.         global $DbConn;
  29.         $sql = 'SELECT COUNT(id) AS NUM FROM categorias WHERE categoria_id ='.$idCategoria;
  30.         $resul = $DbConn->fetchArray($DbConn->query($sql));
  31.         return $resul['NUM'];
  32.     }
  33.    
  34.     function crearArboles($parent='0',$ini){
  35.         global $DbConn;
  36.         //buscamos las categorias con el parent
  37.         $sql = 'SELECT * FROM categorias WHERE categoria_id ='.$parent;
  38.         $res = $DbConn->query($sql);
  39.         $numR = $DbConn->numRows($res);
  40.         while($arr = $DbConn->fetchArray($res)){
  41.             //comenzamos a recorrer una por una, primero vamos a comprobar si tiene post
  42.                 $arrRet[$ini]['id'] = $arr['id'];
  43.                 $arrRet[$ini]['categoria'] = $arr['Nombre'];
  44.                 if($this->getNumPostByCategoria($arr['id'])>0){
  45.                    $arrRet[$ini]['post'] = $this->getPostByCategoriaId($arr['id']);
  46.                 }
  47.                
  48.                 if($this->getNumHijosByCategoria($arr['id'])>0){
  49.                    $arrRet[$ini]['hijo'] = $this->crearArboles($arr['id'],$ini);
  50.                 }
  51.                 $ini++;            
  52.            
  53.         }                  
  54.                
  55.        
  56.        
  57.         return $arrRet;
  58.        
  59.     }

esto nos devuelve un array con una estructura similar a
Código:
{
   [0] =>Array
                  {
                       [id] => 1
                       [categoria] => Primera Categoria
                       // en el caso que exista un post asignado a esa categoria
                       [post] => Array
                                       {
                                          [0] => Array
                                                     {
                                                        [id] => 1
                                                        [titulo] => pos con categorias
                                                      }
                                       }
                       // si tuviera algun hijo (seria un padre excelente)
                       [hijo] => Array
                                     { 
                                          [0] => Array
                                                (
                                                     [id] => 2
                                                     [categoria] => Educación ambiental
                                                     //estas a su vez si tuvieran post quedaria como la de arriba y lo mismo si tuviera hijos
                                                 )
                                      }

                    }
}

ya tenemos nuestro array con los datos de la categorias

La vista se encarga de reccorer este array y hacer las comparaciones para que, si tiene algun post, o si no tiene pero alguno de sus hijos o nietos o bisnietos tiene liste la categoria y el desgrosado de la misma

vista -> index.php
Código php:
Ver original
  1. function recorrer($objet){
  2.        
  3.         foreach($objet as $num => $padre){
  4.             $mTitulo = false;
  5.             // si tiene post
  6.             if(!empty($padre['post'])){
  7.                 $mTitulo = true;
  8.             }
  9.             // si tiene hijos
  10.             if(!empty($padre['hijo'])){
  11.                 //buscamos que tengan post, en el caso de tener hijos volveria a hacer la recursiva
  12.                 //y al cumplir la condicion retornaria el dato
  13.                 foreach($padre['hijo'] as $num => $hijo){
  14.                     // si tiene un post debe mostrar el titulo del padre
  15.                     if(!empty($hijo['post'])){
  16.                         $mTitulo = true;
  17.                     }else{
  18.                         if(!empty($hijo['hijo'])){
  19.                             recorrer($hijo['hijo']);
  20.                         }
  21.                     }
  22.                 }
  23.             }
  24.             if($mTitulo){
  25.                 $html .= '<ul>';
  26.                     $html .= '<h1><a href="javascript:void(0)">'.$padre['categoria'].'</a></h1>';
  27.                     $html .= '<ul>';
  28.                     //recorremos los datos del post
  29.                         foreach($padre['post'] as $num => $post){
  30.                             $html .= '<li><a href="'.ROOT_PATH.'/post/ver/id/'.$post['post_id'].'"> '.$post['titulo'].'</a></li>';
  31.                         }
  32.                     $html .= '</ul>';
  33.                     // verificamos si tiene hijos
  34.                         if(!empty($padre['hijo'])){
  35.                             $html .= '<ul>';
  36.                             $html .= recorrer($padre['hijo']);
  37.                             $html .= '</ul>';
  38.                         }
  39.                     $html .= '</ul>';
  40.             }else{
  41.                 $html .= '<ul></ul>';
  42.             }
  43.            
  44.         }
  45.         return $html;
  46.     }
  47.  
  48.  
  49.         // $lista es el array que nos proporciona el modelo
  50.        echo recorrer($lista);
  #7 (permalink)  
Antiguo 04/09/2009, 01:51
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años
Puntos: 16
Respuesta: Problema listando categorias

por último dejo la imagen funcionando para una mayor comprension del codigo anterior y el porque de la complicación del mismo

  #8 (permalink)  
Antiguo 05/10/2009, 07:27
 
Fecha de Ingreso: mayo-2006
Mensajes: 119
Antigüedad: 17 años, 10 meses
Puntos: 0
Respuesta: Problema listando categorias

EXCELENTE la explicación, esto me viene perfecto para lo que estoy estudiando.

Gracias.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:55.