¿cómo Agrego Datos A Un Array De Una Consulta?

Tengo un método que devuelve un array con las alarmas que se han producido en base a unos datos almacenados en una tabla de MySQL, existen dos tipos de alarmas:

  1. Unas se disparan cuando se supera el caudal mínimo en un valor.

  2. Otro tipo de alarma que se dispara cuando en un día concreto no se han registrado datos en dicha tabla.

Bien esas alarmas se muestran en un CGridView, el problema es que no consigo añadir al array los valores de las alarmas de cuando no existen datos.

Exopongo el código a continuación para que se entienda mejor. A ver si me podeis echar una mano. Muchas gracias!!

La vista:




<?php

ob_start();


$this->beginWidget('zii.widgets.jui.CJuiDialog', array(

    'id'=>'alarmas',

    //'themeUrl' => Yii::app()->theme->baseUrl.'/css/',

    'options'=>array(

        'title'=>'Alarmas',

        'autoOpen'=>true,

        'modal'=>true,

        'resizable'=>false,

        'top' => '50px',

        'width'=>'700',

        'height'=>'auto',

        'close'=>'js:function(event, ui){ location.href = "'. Yii::app()->createUrl('zonas/cerrarPopup',array('id'=>Yii::app()->user->id)) .'" }'

    ),

));

if (isset($dataProvider)) {

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

                'id'=>'alarmas-grid',

                //'cssFile'=>'css/screen.css',

                'dataProvider'=>$dataProvider,

                //'filter'=>$model,

                'columns'=>array(

                    array(

                        'header'=>'Zona',

                        'name' => 'idImeter.idEnsal.idZona.nombre',

                    ),

                    array(

                        'header'=>'Sector',

                        'name' => 'idImeter.idEnsal.nombre',

                    ),

                    array(

                        'header'=>'Fecha',

                        'name' => 'fecha',

                    ),

                    array(

                        'header'=>'Caudal',

                        'name' => 'caudal',

                    ),

                    array(

                        'header'=>'% excedido',

                        'name' => 'prcjSuperado',

                    ),    

                    array(

                        'header'=>'tipo',

                        'name'=>'tipo',

                    ),


                    array(

                        'class'=>'CButtonColumn',

                        'template'=>'{view}',

                        'buttons'=>array(

                            'view'=>array(

                                'url' => 'Yii::app()->createUrl("/zonas/view",array("id"=>$data->idImeter->idEnsal->idZona->id))'

                            ),

                        ),

                    ), 

                ),

            )); 

}

$this->endWidget('zii.widgets.jui.CJuiDialog'); 

?>




El controlador:




public function actionIndex()

	{


            $model = new Zonas;

            // Lo que ve el administrador

            if (Yii::app()->getModule('user')->isAdmin()) {

                // Si hay alarmas recientes las mostramos

                $datos = Alarmas::model()->ultimasAlarmas(Yii::app()->user->id);

                if($datos) {

                    $dataProvider = new CArrayDataProvider($datos);

                        $this->render('/alarmas/popup',array('model'=>$model,'dataProvider'=>$dataProvider));

                }

                // En caso contrario mostramos las zonas

                else {

                    $dataProvider=new CActiveDataProvider('Zonas');

                    $this->render('/zonas/index',array('dataProvider'=>$dataProvider,));

                }


            }

            else {        

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

                    'criteria'=>array(

                        'join'=>"INNER JOIN zona_usr ON (t.id = zona_usr.id_zona)",

                        'condition'=>"zona_usr.id_usuario = ". (int)Yii::app()->user->id,

                    ),

                ));


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

                        'dataProvider'=>$dataProvider,

		));

            }

	}



La vista:




...

...

public function obtenerTipo($tipo) {

            switch ($tipo) {

                case 0:

                    return "Minimum theoretical alarm";

                    break;

                case 1:

                    return "Custom alarm";

                    break;

                case 2:

                    return "No data";

                    break;

                default:

                    return false;

                    break;

            }

        }




 public function ultimasAlarmas($id) {

            

            // Obtenemos la ultima vez que el usuario ha leido las alarmas

            $criteria = new CDbCriteria();

            $criteria->compare('id_usuario',(int)$id);

            $fecha = UsuariosAlarmas::model()->find($criteria);

            

            // Obtenemos las entradas/salidas con alarma configurara y los parámetros de la alarma

            $criteria = new CDbCriteria;

            $criteria->select = array('t.id','t.id_ensal','(t.valor + ((t.porcentaje*t.valor)/100)) AS valor', 't.tipo');

            $alarms = Alarmas::model()->findAll($criteria);

            

            // Recorremos los resultados

            foreach ($alarms as $alarm) {

                $idEnsal = $alarm->id_ensal;

                $consumoAlarma = $alarm->valor;

                $tipoAlarma = $alarm->tipo;

                $HInicio = $alarm->HInicio;

                $HFin = $alarm->HFin;

                

                // Comprobamos si hay formula, para calcular la alarma haciendo los calculos oportunos

                $criteria = new CDbCriteria();

                $criteria->select = array('t.formula');

                $criteria->compare('id', (int)$idEnsal);

                $formula = Ensal::model()->find($criteria);

                $formula = $formula->formula;

               

                

                $criteria = new CDbCriteria();

  

                $criteria->select = array('t.id','MIN(t.caudal) as caudal','t.fecha','t.HLectura');


                $criteria->together = true;

                $criteria->group = 't.fecha';

                $criteria->with=array(

                'idImeter'=>array(

                    'joinType' => 'INNER JOIN',

                    'with' => array(

                        'idEnsal' => array(

                            'joinType' => 'INNER JOIN',

                            'select' => array('id','nombre'),

                            'with' => array(

                                'idZona' => array(

                                    'joinType' => 'INNER JOIN',  

                                    'select' => array('nombre', 'id')

                                )

                            )

                        )

                    )

                )); 

                

                if (!empty($formula)) {

                    Yii::import('application.controllers.EnsalController');

                    $criteria->compare('t.id_formula', (string)implode(EnsalController::extraerIdsFormula($formula))); 

                }    

                else {

                    $criteria->compare('idImeter.id_ensal', (int)$idEnsal);

                }

                // Entrada salida que estamos recorriendo

                // Consumos que superen alarma

                $criteria->having = "caudal >= ".(double)$consumoAlarma;

                if (isset($fecha->fecha)) {

                    //$fecha = $fecha->fecha;

                    $criteria->compare('t.fecha', ' > '. (string)$fecha->fecha);

                }

                    

                    $criteria->addBetweenCondition('t.HLectura', (string)$HInicio, (string)$HFin);

                   

                $datos = Datos::model()->findAll($criteria);


                foreach ($datos as $dato) {

                    // Redondeamos el porcentaje ??

                    // Controlamos división por cero

                    if ($consumoAlarma > 0) 

                        $prcjSuperado = round(($dato->caudal * 100) / $consumoAlarma) - 100;

                    else 

                        $prcjSuperado = '';

                    $dato->prcjSuperado = $prcjSuperado;

                    $id = $dato->idImeter->idEnsal->idZona->id;

                    $dato->id_zona = $id;

                    $dato->tipo = Yii::t('default',$this->obtenerTipo($alarm->tipo));

                    $dato->id = $alarm->id;                   

                    $res[] = $dato;

                }            

            }

            // Generamos alarmas para los imeters sin datos

            

            $imeters = Imeters::model()->findAll();

            if (!$imeters === false) {

                foreach ($imeters as $imeter) {

                    $criteria = new CDbCriteria();

                    $criteria->select = array('id');

                    if (isset($fecha->fecha)) {

                        $criteria->compare('t.fecha', ' > '. (string)$fecha->fecha);

                    }

                    $criteria->compare('id_imeter',(int)$imeter->id);

                    $errorDatos = Datos::model()->find($criteria);

                    if ($errorDatos === null) {

                        $errorDatos->tipo = Yii::t('default',  $this->obtenerTipo(2));

                        $res[] = $errorDatos; 

                 

                    }

                }

            }

            return (isset($res)) ? $res : false ;

        }



El problema esta aquí, que no se como añadir al array esos datos para cuando un imeter no tiene datos y aparezca en el CGridview junto al resto de alarmas.




// Generamos alarmas para los imeters sin datos

            

            $imeters = Imeters::model()->findAll();

            if (!$imeters === false) {

                foreach ($imeters as $imeter) {

                    $criteria = new CDbCriteria();

                    $criteria->select = array('id');

                    if (isset($fecha->fecha)) {

                        $criteria->compare('t.fecha', ' > '. (string)$fecha->fecha);

                    }

                    $criteria->compare('id_imeter',(int)$imeter->id);

                    $errorDatos = Datos::model()->find($criteria);

                    if ($errorDatos === null) {

                        $errorDatos->tipo = Yii::t('default',  $this->obtenerTipo(2));

                        $res[] = $errorDatos; 

                 

                    }



Tratare de explicarme un poco mejor, a ver si alguien me puede ayudar porque no logro hacerlo :S

Tengo una tabla en una base de datos de MySQL donde se almacenan datos (caudal, fecha, hora, identificado del contador) y otra tabla donde almaceno alarmas que crean los usuarios para los datos (contador, valor de disparo, etc). Las alarmas que se han disparado las muestro en un CGridView; muestro el tipo de alarma (alarma personalizada, sin datos, alarma automática), valor con el que saltó la alarma, etc. Ahora mismo este CGridView muestra solo las alarmas disparadas que definió el usuario, ahora quiero que en este mismo CGridView se muestre una alarma que sea sin datos, que se corresponda a cuando para un día no se han registrado datos en la tabla datos para un contador en concreto, hasta aquí todo bien el problema es que no se como unir unos datos con otros para que se muestren en el CGridView y en me deje todos los campos del CGridView en blanco para este tipo de alarmas, excepto el campo tipo de alarma que debe mostrar "Sin datos". Gracias y un saludo.

Hola,

Disculpa si mi respuesta es algo corta, estoy desde el celular. Estoy casi seguro que tu problema se resuelve aplicando un LEFT JOIN en tu consulta para traerte los datos que están vacíos, por favor lee la documentación sql de tu base de datos sobre los LEFT JOIN.

Saludos.