Listado con CGridView con 4 tablas

Hola, llevo poco usando Yii, básicamente estoy haciendo mi primera aplicación y después de irme peleando con problemas que me he ido encontrando la tengo casi lista, pero me he encontrado con un problema con el que no encuentro solución. He estado buscando en foros en ingles (mi ingles no es muy bueno, la verdad sea dicha), videotutoriales, etc y no encuentro nada que se ajuste a lo que quiero y me gustaría que alguien pudiera orientarme a como hacerlo.

Mi problema es que tengo una base de datos con 5 tablas relacionadas y necesito hacer un listado con campos de 4 de ellas y que se puedan filtrar y había pensado hacerlo como el listado de la vista admin de un crud normal, pero sin los botones de edición.

La consulta en MySQL es fácil, no tengo problemas con ella, las tablas son oficinas, empleados, clientes y pedidos (están relacionadas en ese orden) y el listado seria saber de todos los pedidos la referencia, la fecha, el cliente, el vendedor y la oficina donde se hizo la venta.

Por muchas vueltas que le doy no consigo solucionarlo y ya que estoy usando un framework me gustaría hacerlo con las herramientas que tiene.

Un saludo y gracias por la atención.

Para imprimir el resultado de la consulta puede usar GridView, que es el widget para listados en forma de tabla (si necesita algo más elaborado, puede utilizar ListView)

La documentación la encuentra en:

http://www.yiiframework.com/doc-2.0/yii-grid-gridview.html

Si nos diera algunos detalles de la consutla o de la respuesta deseada, podría enviarle algunos tips o sugerencias.

Saludos.

Gracias robregonm, tu sugerencia a usar CListView (por cierto estoy usando la versión 1 y no la 2 de Yii, no se si he hecho bien o debería usar la versión 2 en mi siguiente proyecto) me ha hecho investigar sobre esa clase y buscando he encontrado una solución (al final he usado CGridView, aunque con CListView también me funcionaba), pero solo me queda una pega y es que lo tengo todo menos el filtrado del listado.

Como la consulta es de varias tablas solo he hecho un controlador y una vista

El controlador sería:


public function actionIndex()

	{


		$sql = "SELECT o.Ciudad, o.Region, e.Nombre AS Empleado, c.Nombre AS Cliente, p.Codigo AS id, p.NumPedido, p.FechaPedido ";

		$sql.= "FROM ((oficinas o RIGHT JOIN empleados e ON o.Oficina = e.Oficina) JOIN pedidos p ON e.NumEmp = p.Representante) JOIN clientes c on p.cliente = c.NumClie ";

		

		$consulta = Yii::app()->db->createCommand($sql)->queryAll();

		$total = count($consulta);


		$dataProvider = new CSqlDataProvider($sql, array(

			'totalItemCount'=>$total,

            'sort'=>array(

                'attributes'=>array(

                    'Ciudad', 

                    'Region', 

                    'Empleado', 

                    'Cliente', 

                    'Codigo', 

                    'NumPedido', 

                    'FechaPedido',

                )

            )

        ));


		$this->render('index',array(

				'dataProvider'=>$dataProvider,

			));

	}

Y la vista:


<?php


$this->breadcrumbs=array(

	Yii::t('app','Reports'),

);

?>

<h1><?php print Yii::t('app','Reports'); ?></h1>


<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'informe-grid',

    'itemsCssClass'=>'table table-striped',

    'pager'=>array('htmlOptions'=>array('class'=>'pagination')),

	'dataProvider'=>$dataProvider,

	//'filter'=>$model,

	'columns'=>array(

		array(

			'name'=>'Ciudad',

			'header'=>Yii::t('app','City'),

		),

		array(

			'name'=>'Region', 

			'header'=>Yii::t('app','Region'),

		),

		array(

			'name'=>'Empleado', 

			'header'=>Yii::t('app','Salesman'),

		),

		array(

			'name'=>'Cliente', 

			'header'=>Yii::t('app','Client'),

		),

		array(

			'name'=>'NumPedido', 

			'header'=>Yii::t('app','Order Number'),

		),

		array(

			'name'=>'FechaPedido',

			'header'=>Yii::t('app','Order Date'),

		),

	),

)); ?>

Y lo que no se ahora es como hacerlo para que filtre, me imagino que debe ser con CDbCriteria, pero no se como hacerlo.

Y una ultima cosa, como veréis en la consulta he puesto un campo que no uso (p.Codigo AS id) porque me daba un error que me decía que indice id no estaba definido, y no he usado id en ningún sitio, ¿a que se debe eso?

Buenas:

1- Estás utilizando un CSqlDataProvider, por lo que necesitas indicarle cuál es el campo clave que identifica a cada fila. Eso se hace añadiendo keyField a la creación del mismo.




$dataProvider = new CSqlDataProvider($sql, array(

             'totalItemCount'=>$total,

            'keyField' =>'el_campo_que_tu_quieras',

            'sort'=>array(

                'attributes'=>array(

                    'Ciudad', 

                    'Region', 

                    'Empleado', 

                    'Cliente', 

                    'Codigo', 

                    'NumPedido', 

                    'FechaPedido',

                )

            )

        ));




2- Para el filtrado de un CSqlDataprovider yo utilizo una variable que contendrá la cláusula WHERE de la consulta. Cuando escribes un criterio en el CGridview, se envía por $_GET. Entonces en tu actionIndex recuperas ese $_GET y se la añades a tu consulta.

Un saludo.

Gracias lagogz, he añadido


'keyField' =>'Codigo',

que es la pk y he elimiando el "AS id" de la consulta y me funciona correcto.

Con respecto a lo que me comentabas en el punto 2, no tengo problemas con la ordenación, eso me va fenomenal, el problema es el filtrado, que he probado varias maneras y no doy con la tecla, lo que quiero hacer es por ejemplo si tengo 30 registros en total que pueda filtrar por cualquiera de los campos (ejemplo clientes que se llamen Juan) y que me salgan por ejemplo los 15 que cumpla con esa condición.

No me refería a la ordenación, sino al filtrado. Disculpa.

En el punto 2 me refiero al filtrado.

En tu search harías algo como esto:




................

$where = "";


// si es tu modelo, asignas el GET a los atributos en lugar de

// recoger directamente el campo y listo.

if(isset($_GET['nombre del dato por el que filtras']))

{

     $where .= " AND UPPER(nombreTabla.campo) LIKE '%" . strtoupper($_GET['nombre del dato por el que filtras']) . "%'";

}

.................



Después añades la cláusula WHERE a tu SQl y listo.

También lo puedes hacer con CDbCriteria si lo deseas.

Un saludo.