Rare error with CGridView

I’m trying to define CGridView colums but ‘value’ attribute is not working. I can’t define it at all without

getting rare error message. This structure was working with my other applications.

Here is the code:

admin.php(generated with Gii, then modificated)




<?php

$this->breadcrumbs=array(

	'Invoices'=>array('index'),

	'Manage',

);


$this->menu=array(

	array('label'=>'List Invoice', 'url'=>array('index')),

	array('label'=>'Create Invoice', 'url'=>array('create')),

);


Yii::app()->clientScript->registerScript('search', "

$('.search-button').click(function(){

	$('.search-form').toggle();

	return false;

});

$('.search-form form').submit(function(){

	$.fn.yiiGridView.update('invoice-grid', {

		data: $(this).serialize()

	});

	return false;

});

");

?>


<h1>Manage Invoices</h1>


<p>

You may optionally enter a comparison operator (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>

or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done.

</p>


<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>

<div class="search-form" style="display:none">

<?php $this->renderPartial('_search',array(

	'model'=>$model,

)); ?>

</div><!-- search-form -->


<?php 

	//$commandString = 'echo \'<a href="\'.Yii::app()->storage->getFilePath($data->pdfUrl).\'">Näytä PDF</a>';

	$commandString = 'echo "aa"';//$data->pdfUrl'; 


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

	'id'=>'invoice-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'idInvoice',

		'idPerson',

		array(    //if this array is removed, everything works.

				'header' => 'pdf',

				'value' => '$data->pdfUrl'           //THIS IS WHAT DOESN'T WORK

		),


		'state',

		'reason',

		'paid',

		'uploadDate',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Invoice.php (model)




<?php


/**

 * This is the model class for table "invoice".

 */

class Invoice extends CActiveRecord

{

	/**

	 * The followings are the available columns in table 'invoice':

	 * @var integer $idInvoice

	 * @var integer $idPerson

	 * @var string $pdfUrl

	 * @var string $state

	 * @var string $reason

	 * @var string $paid

	 * @var string $uploadDate

	 */


	/**

	 * Returns the static model of the specified AR class.

	 * @return Invoice the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'invoice';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('idPerson', 'required'),

			array('idPerson', 'numerical', 'integerOnly'=>true),

			array('pdfUrl', 'length', 'max'=>64),

			array('state', 'length', 'max'=>32),

			array('reason', 'length', 'max'=>128),

			array('paid, uploadDate', 'safe'),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('idInvoice, idPerson, pdfUrl, state, reason, paid, uploadDate', 'safe', 'on'=>'search'),

		);

	}


	/**

	 * @return array relational rules.

	 */

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'idPerson0' => array(self::BELONGS_TO, 'Person', 'idPerson'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'idInvoice' => 'Id Invoice',

			'idPerson' => 'Id Person',

			'pdfUrl' => 'Pdf Url',

			'state' => 'State',

			'reason' => 'Reason',

			'paid' => 'Paid',

			'uploadDate' => 'Upload Date',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->compare('idInvoice',$this->idInvoice);


		$criteria->compare('idPerson',$this->idPerson);


		$criteria->compare('pdfUrl',$this->pdfUrl,true);


		$criteria->compare('state',$this->state,true);


		$criteria->compare('reason',$this->reason,true);


		$criteria->compare('paid',$this->paid,true);


		$criteria->compare('uploadDate',$this->uploadDate,true);


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}

}



This is error message:





CException

Description


Property "Invoice." is not defined.

Source File


C:\xampp\htdocs\laskut\framework\db\ar\CActiveRecord.php(107)


00095:      */

00096:     public function __get($name)

00097:     {

00098:         if(isset($this->_attributes[$name]))

00099:             return $this->_attributes[$name];

00100:         else if(isset($this->getMetaData()->columns[$name]))

00101:             return null;

00102:         else if(isset($this->_related[$name]))

00103:             return $this->_related[$name];

00104:         else if(isset($this->getMetaData()->relations[$name]))

00105:             return $this->getRelated($name);

00106:         else

00107: return parent::__get($name);

00108:     }

00109: 

00110:     /**

00111:      * PHP setter magic method.

00112:      * This method is overridden so that AR attributes can be accessed like properties.

00113:      * @param string property name

00114:      * @param mixed property value

00115:      */

00116:     public function __set($name,$value)

00117:     {

00118:         if($this->setAttribute($name,$value)===false)

00119:         {


Stack Trace


#0 C:\xampp\htdocs\laskut\framework\db\ar\CActiveRecord.php(107): CComponent->__get('')

#1 C:\xampp\htdocs\laskut\framework\web\helpers\CHtml.php(1692): CActiveRecord->__get('')

#2 C:\xampp\htdocs\laskut\framework\web\helpers\CHtml.php(1166): CHtml::activeInputField('text', Object(Invoice), false, Array)

#3 C:\xampp\htdocs\laskut\framework\zii\widgets\grid\CDataColumn.php(96): CHtml::activeTextField(Object(Invoice), NULL, Array)

#4 C:\xampp\htdocs\laskut\framework\zii\widgets\grid\CGridColumn.php(103): CDataColumn->renderFilterCellContent()

#5 C:\xampp\htdocs\laskut\framework\zii\widgets\grid\CGridView.php(380): CGridColumn->renderFilterCell()

#6 C:\xampp\htdocs\laskut\framework\zii\widgets\grid\CGridView.php(358): CGridView->renderFilter()

#7 C:\xampp\htdocs\laskut\framework\zii\widgets\grid\CGridView.php(331): CGridView->renderTableHeader()

#8 C:\xampp\htdocs\laskut\framework\zii\widgets\CBaseListView.php(152): CGridView->renderItems()

#9 [internal function]: CBaseListView->renderSection(Array)

#10 C:\xampp\htdocs\laskut\framework\zii\widgets\CBaseListView.php(135): preg_replace_callback('/{(\w+)}/', Array, '{summary}?{item...')

#11 C:\xampp\htdocs\laskut\framework\zii\widgets\CBaseListView.php(121): CBaseListView->renderContent()

#12 C:\xampp\htdocs\laskut\framework\web\CBaseController.php(174): CBaseListView->run()

#13 C:\xampp\htdocs\laskut\protected\views\invoice\admin.php(65): CBaseController->widget('zii.widgets.gri...', Array)

#14 C:\xampp\htdocs\laskut\framework\web\CBaseController.php(119): require('C:\xampp\htdocs...')

#15 C:\xampp\htdocs\laskut\framework\web\CBaseController.php(88): CBaseController->renderInternal('C:\xampp\htdocs...', Array, true)

#16 C:\xampp\htdocs\laskut\framework\web\CController.php(748): CBaseController->renderFile('C:\xampp\htdocs...', Array, true)

#17 C:\xampp\htdocs\laskut\framework\web\CController.php(687): CController->renderPartial('admin', Array, true)

#18 C:\xampp\htdocs\laskut\protected\controllers\InvoiceController.php(149): CController->render('admin', Array)

#19 C:\xampp\htdocs\laskut\framework\web\actions\CInlineAction.php(32): InvoiceController->actionAdmin()

#20 C:\xampp\htdocs\laskut\framework\web\CController.php(300): CInlineAction->run()

#21 C:\xampp\htdocs\laskut\framework\web\filters\CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#22 C:\xampp\htdocs\laskut\framework\web\filters\CFilter.php(41): CFilterChain->run()

#23 C:\xampp\htdocs\laskut\framework\web\CController.php(999): CFilter->filter(Object(CFilterChain))

#24 C:\xampp\htdocs\laskut\framework\web\filters\CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#25 C:\xampp\htdocs\laskut\framework\web\filters\CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#26 C:\xampp\htdocs\laskut\framework\web\CController.php(283): CFilterChain->run()

#27 C:\xampp\htdocs\laskut\framework\web\CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#28 C:\xampp\htdocs\laskut\framework\web\CWebApplication.php(320): CController->run('admin')

#29 C:\xampp\htdocs\laskut\framework\web\CWebApplication.php(120): CWebApplication->runController('invoice/admin')

#30 C:\xampp\htdocs\laskut\framework\base\CApplication.php(135): CWebApplication->processRequest()

#31 C:\xampp\htdocs\laskut\index.php(12): CApplication->run()




If someone get any idea, I would greatly appreciate for help.

You could try:




 'name' => 'pdfUrl', // instead of  'value' => '$data->pdfUrl'



If it wouldn’t help you, then pls post search action too.

Actually, that one works but I put the $data->pdfUrl becouse I was trying to make it as simple as possible to read for others. So, in fact in need something else in value, like Yii->app()->myStorage->doMethod($data->pdfUrl).

I’m sorry I wasn’t able to understand what exactly you mean by search action?

Thanks for help, I highly appreciate it!

Today I’m going to try to solve it by testing everything I can think, maybe I will face the problem.

you need to remove the quotes from the $data->pdfUrl.

Neitheir this one works, if I understand correctly, they should be inside quotes becouse $data variable is used later when list is generated.

But still thanks for paying attention to my problem!

According to the stack trace, since you are not using filter, you’ll need to specify name.

API reference:

Seems to be a bug in renderFilterCellContent().

(I’m not sure about what PHP promises/specifies regarding initialization of instance data - in this case acquired by a call to new in Yii::createComponent() - but a default value might be needed for filter and possibly also for name.)

/Tommy

Thank you a lot!

You were right, I had to add ‘filter’=>false attribute and it works. Everything was just becouse I don’t know enought about how GridView works. I just wonder how I was able to pass this problem in my other applications or do I have just so bad memory that can’t get any image about this problem.

Thanks a lot, you saved me from many hours or maybe even days of debugging.

Ticket created

http://code.google.com/p/yii/issues/detail?id=3008

/Tommy

Ticked invalidated… as I cannot reproduce this error…

Did set only header and value, the column is rendered with no filer input… grid filter is set as other columns does have the filter field…

docc What Yii version are you using?

Ticket created because filter member of CDataColumn is used in a conditional statement without prior initialization. See my thoughts above whether the state of instance data may be defined or not in PHP. (I guess emalloc will be used under the hood for a PHP new allocation, hardly ecalloc.)

/Tommy

I’m not following you on this… I did not get any error like the posted did…

You mentioned above the renderFilterCellContent()… check it’s current code… it checks for $this->name !== null so if the name is not given the filter is not rendered…

According to the stack trace, we reach the CHtml::activeTextField() statement. But it seems I overlooked the "$this->filter===null" condition. So this should happen only if false!=null.




  if(is_string($this->filter))

    ...

  else if($this->filter!==false && ...)

  {

    if(is_array($this->filter))

      ...

    else if($this->filter===null)

      echo CHtml::activeTextField($this->grid->filter, $this->name, ...);

  }

  ...



So now I have two questions:

  1. Does PHP promise initialized member data?

  2. Does PHP promise that false!=null?

/Tommy

docc still did not answer which Yii version is using… so could happen that you are looking at the stack trace (posibly generated with old code) but looking at current code…

As there is the check for name!==null… I don’t see how the code would get to the activeTextField in the first place…

And as I wrote… I tried that example and I did not get any error… did you try it on your side ?

No, I didn’t try it. Also name isn’t explicitly initialized so whether it will satisfy the condition or not depends on the answer to my first question.

But according to the stack trace the second parameter to activeTextField() actually is NULL, so this is kinda strange…

/Tommy