Customizar Dataprovider para CListView

Olá pessoal, estou tentando customizar o dataprovider com criteria mas não sei porque esta acontecendo algo de errado, vejam só:

Eu precisava do resultado desta consulta no dataprovider:




select p.* from pagina as p, categoria_has_pagina as cp where p.idpagina = cp.pagina_idpagina and cp.categoria_idcategoria = $id and p.publicar = 1



Fiz o seguinte:




$dataProvider=new CActiveDataProvider('Pagina', array(

	'criteria'=>array(

    	'condition' => 'p.idpagina=p.idpagina',

    	'alias' => 'p',

    	'with' => array('categorias'=>array(

    	'joinType' => 'LEFT JOIN',

    	'condition' => "p.idpagina=p.idpagina and p.idpagina=categorias_categorias.pagina_idpagina and categorias_categorias.categoria_idcategoria=$id and p.publicar=1",

    	)),

	),

));



Notei que esta minha consulta esta retornando três querys na hroa de incluir no CListVIew:

Esta primeira acretido que esta ok, pois ela deve ter cido gerada para ver a quantidade de itens para paginação:




SELECT COUNT(DISTINCT `p`.`idpagina`) FROM `pagina` `p`  LEFT JOIN `categoria_has_pagina` `categorias_categorias` ON (`p`.`idpagina`=`categorias_categorias`.`pagina_idpagina`) LEFT JOIN `categoria` `categorias` ON (`categorias`.`idcategoria`=`categorias_categorias`.`categoria_idcategoria`)  WHERE (p.idpagina=p.idpagina) AND (p.idpagina=p.idpagina and p.idpagina=categorias_categorias.pagina_idpagina and categorias_categorias.categoria_idcategoria=14 and p.publicar=1)



Esta segunda eu não sei porque ela foi criada, mas notei que o Limit dela muda quando eu defino que a quantidade de itens por página.




SELECT `p`.`idpagina` AS `t0_c0`, `p`.`tipopagina_idtipopagina` AS `t0_c1`, `p`.`titulo` AS `t0_c2`, `p`.`conteudo` AS `t0_c3`, `p`.`url` AS `t0_c4`, `p`.`imagemgrande` AS `t0_c5`, `p`.`imagempequena` AS `t0_c6`, `p`.`video` AS `t0_c7`, `p`.`arquivo` AS `t0_c8`, `p`.`resumo` AS `t0_c9`, `p`.`tags` AS `t0_c10`, `p`.`palavrachave` AS `t0_c11`, `p`.`acessos` AS `t0_c12`, `p`.`liberarcomentarios` AS `t0_c13`, `p`.`datacadastro` AS `t0_c14`, `p`.`dataalteracao` AS `t0_c15`, `p`.`publicar` AS `t0_c16` FROM `pagina` `p`  WHERE (p.idpagina=p.idpagina) LIMIT 10

Esta terceira que esta pegando:




SELECT `p`.`idpagina` AS `t0_c0`, `categorias`.`idcategoria` AS `t1_c0`, `categorias`.`tipocategoria_idtipocategoria` AS `t1_c1`, `categorias`.`titulo` AS `t1_c2`, `categorias`.`descricao` AS `t1_c3`, `categorias`.`url` AS `t1_c4`, `categorias`.`resumo` AS `t1_c5`, `categorias`.`tags` AS `t1_c6`, `categorias`.`datacadastro` AS `t1_c7`, `categorias`.`dataalteracao` AS `t1_c8`, `categorias`.`palavrachave` AS `t1_c9`, `categorias`.`publicar` AS `t1_c10`, `categorias`.`acessos` AS `t1_c11` FROM `pagina` `p` LEFT JOIN `categoria_has_pagina` `categorias_categorias` ON (`p`.`idpagina`=`categorias_categorias`.`pagina_idpagina`) LEFT JOIN `categoria` `categorias` ON (`categorias`.`idcategoria`=`categorias_categorias`.`categoria_idcategoria`)  WHERE (`p`.`idpagina` IN (2, 3, 5, 7, 10, 11, 12, 13, 14, 15)) AND (p.idpagina=p.idpagina and p.idpagina=categorias_categorias.pagina_idpagina and categorias_categorias.categoria_idcategoria=14 and p.publicar=1)

Não sei porque ele inseriu este trexo:


(`p`.`idpagina` IN (2, 3, 5, 7, 10, 11, 12, 13, 14, 15))

Mas notei que na segunda query quando o limite esta 3 só aparecem os 3 primeiros IDs desta de cima.

Acho que o problema esta em

‘condition’ => ‘p.idpagina=p.idpagina’,

que deveria ser

‘condition’ => ‘p.idpagina=:P.idpagina’,

com os dois pontos depois do ‘=’

Mas quando faço isso ele dá o seguinte erro na primeira query:


CDbCommand falhou ao executar o comando SQL: SQLSTATE[HY093]: Invalid  parameter number: no parameters were bound. The SQL statement executed  was: SELECT COUNT(DISTINCT `p`.`idpagina`) FROM `pagina` `p`  LEFT JOIN  `categoria_has_pagina` `categorias_categorias` ON  (`p`.`idpagina`=`categorias_categorias`.`pagina_idpagina`) LEFT JOIN  `categoria` `categorias` ON  (`categorias`.`idcategoria`=`categorias_categorias`.`categoria_idcategoria`)   WHERE (p.idpagina=<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/tongue.gif' class='bbc_emoticon' alt=':P' />.idpagina) AND (p.idpagina=p.idpagina and  p.idpagina=categorias_categorias.pagina_idpagina and  categorias_categorias.categoria_idcategoria=14 and p.publicar=1)	

Alguém já passou por isso e pode me ajudar?

Breno,

Veja que consulta retorna assim:


$dataProvider=new CActiveDataProvider('Pagina', array(

	'criteria'=>array(

		'with' => array('categorias'),

		'alias' => 'p',

		'condition' => 'p.idpagina = cp.pagina_idpagina AND cp.categoria_idcategoria = :categoria_idcategoria AND p.publicar = :publicar',

		'params' => array(

			':categoria_idcategoria' => $id,

			':publicar' => 1

		)

		),

	),

));

Olá Newerton, valeu pela dica, mas esta dando um erro que também não consegui resolver:


CDbCommand falhou ao executar o comando SQL: SQLSTATE[42S22]: Column not  found: 1054 Unknown column 'cp.pagina_idpagina' in 'where clause'. The  SQL statement executed was: SELECT COUNT(DISTINCT `p`.`idpagina`) FROM  `pagina` `p`  LEFT OUTER JOIN `categoria_has_pagina`  `categorias_categorias` ON  (`p`.`idpagina`=`categorias_categorias`.`pagina_idpagina`) LEFT OUTER  JOIN `categoria` `categorias` ON  (`categorias`.`idcategoria`=`categorias_categorias`.`categoria_idcategoria`)   WHERE (p.idpagina = cp.pagina_idpagina AND cp.categoria_idcategoria =  :categoria_idcategoria AND p.publicar = :publicar). Bound with  :categoria_idcategoria='14', :publicar=1

Tentei definir um alias dentro do with para categorias assim:




...

'with' => array('categorias'=>array('alias' => 'cp',)),

...



Mas retornou o mesmo erro.

Também tentei colocar assim no lugar de cp.categoria_idcategoria coloquei categorias_categorias.categoria_idcategoria mas retornou o mesmo erro dizendo que a coluna não existe, mas a coluna existe na tabela que estamos referenciando dentro do with.

Acho que se conseguirmos remover este trecho do código funcionária

(p.idpagina IN (2, 3, 5, 7, 10, 11, 12, 13, 14, 15))pq testei a query no sql-front, e sem este pedaço retornou a query correta.

Pessoal, consegui resolver, nossa, nem fazia ideia.

Em meu model a minha relação estava assim;


'categorias' => array(self::MANY_MANY, 'Categoria', 'categoria_has_pagina(pagina_idpagina, categoria_idcategoria)'),

E então eu coloquei assim:


'categorias' => array(self::MANY_MANY, 'Categoria', 'categoria_has_pagina(pagina_idpagina, categoria_idcategoria)', 'together'=>true),

O together juntou as querys 2 e 3 e além de remover o in resolveu o problema.