Inserire un campo calcolato in una CGridView

Yii ver 1.1.8, PHP ver 5.3

Sto cercando di mettere in una grid un campo calcolato.

Il model si chiama FerieGiorni ed ha (oltre ad una chiave primaria e una foreign key ad un model "Dipendente") un campo da_data ed un campo a_data.

Dentro il model ho creato questa funzione:




	public function getTotale_giorni()

	{

		$date1 = new DateTime($this->da_data);

		$date2 = new DateTime($this->a_data);

		$interval = $date2->diff($date1);

		return $interval->d;

	}



e funziona correttamente.

La mia grid l’ho settata così:




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

        'id'=>'ferie_grid',

	'dataProvider'=> $this->getFerieProvider(),

	'summaryText'=>'',

	'cssFile'=>'grid.css',

	'columns'=>array(

		array(

			'name'=>'da_data',

			'value'=>'$data->da_data_ita',

			'header'=>'Da data',

		),

		array(

			'name'=>'a_data',

			'value'=>'$data->a_data_ita',

			'header'=>'A data',

		),

		array(

			'value'=>'$data->totale_giorni',

			'header'=>'Giorni',

		)

	)

));



e due volte su tre il browser mi restituisce questo messaggio:

PHP Error range() [<a href=‘function.range’>function.range</a>]: step exceeds the specified range

mentre la terza volta mi visualizza tutto correttamente.

Non vi chiedo di risolvermi l’errore, dato che dovrei postarvi tutto lo stack, ma mettere un campo calcolato in una CGridView dovrebbe essere semplice.

Mi fate vedere come si fa?

Grazie a tutti

Roberto

Il problema sembra essere la funzione del calcolo.

L’ho sostituita con la seguente:




        public function getTotale_giorni()

        {

 		$date1 = strtotime($this->da_data);

		$date2 = strtotime($this->a_data);

		$diff = $date2 - $date1;

		return floor($diff / (60*60*24));

        }



Questa non fa uso delle funzioni di PHP 5.3 sul calcolo delle date.

La cosa strana è che la versione precedente funzionava a volte sì e a volte no.

Misteri del codice

Mi manca un’ultima cosa: come faccio a rendere questa nuova colonna della grid ordinabile come le altre?

Grazie a tutti

Per ordinare setta l’attributo “sort” nel DataProvider della view




        public function getTotale_giorni()

        {

 		$date1 = strtotime($this->da_data);

		$date2 = strtotime($this->a_data);

		$diff = $date2 - $date1;

		return floor($diff / (60*60*24));

        }



yii mette a disposizione il meccanismo dei behaviors(afterFind,afterSave, beforeFind etc etc) che rende il codice molto più snello e pulito…del tipo




        public $totale

        

protected function afterFind()

        {

 		$date1 = strtotime($this->da_data);

		$date2 = strtotime($this->a_data);

		$diff = $date2 - $date1;

		$this->totale = floor($diff / (60*60*24));

                parent::afterFind();

        }



così non avrai bisogno di invocare ogni volta il metodo totale_giorni all’interno di CGridView.Ovvio che tutto sarebbe ancora più sensato se crei una proprietà “total” e setti il suo valore al risultato dell’operazione.In CGridView basterà utilizzare solo utilizzare come attributo il nome della proprietà “total” ed il gioco è fatto.

Grazie per la risposta.

Solo non capisco quando parli del creare una proprietà "total" come qualcosa di diverso da quello che hai fatto nel tuo esempio.

infatti lo avevo già fatto :)

Grazie.

Sono riuscito a farlo in questo modo:




		$sort = new CSort();

		$sort->attributes = array(

            'da_data',

            'a_data',

            'totale_giorni_assenza' => array('asc'=>'a_data - da_data', 'desc'=>'a_data - da_data desc'),

        );

		

		$this->ferie_provider = new CActiveDataProvider('FerieGiorni',array(

 			'criteria'=>array(

				'condition'=>'iddipendente = ' .$this->dipendente->oid,

			),

			'sort'=>$sort,

			'pagination'=>array(

				'pageSize'=>6,

			),

		));




per risparmiare righe puoi anche mettere l’array direttamente nella dichiarazione del dataprovider (come per pagination per intenderci)

Scusate se riprendo questa vecchia discussione :) Ma se io dovessi filtrare e ordinare un dato completamente indipendente dal database, quindi un campo calcolato, il procedimento è lo stesso? O bisogna per forza avere l’appoggio del DB? (mi riferisco alla logica del CSort)

Grazie in anticipo

Puoi fare una query che calcola quel dato ed ordinare i dati di conseguenza. Anche se il campo è calcolato, dipende dal DB.