Auto Update After Rendering Detail View

Hi all,

I’d like to know how to automatically update a record after rendering a detailview of that record.

I have a table with the field status. This field has to be updated from 0 to 1 as soon the user views that record in detailview.

i think it has something to do with AfterRender? But I have no clue how to do it and what the code should be.

Thanks in advance!

Do you have only one user in your app?

No, eventually there will be more users.

You can do it in the actionView, if you run this action means that the user will see this record.

Thank you for your answer, but please describe it in more detail. I have allready the action view, but i want to add some functionality to it. As soon as the render is complete, a database value should be updated from 0 to 1. So the user doesn’t have to click a button to achieve this.

MAD

There is no difference in doing before or after rendering, you get the same result.

just add:


public function actionView()

{


$model= loadmodel;

$model->value=1;

$model->save();

...

Wow, and again im surprised how easy things are done with Yii.

Thanks zaccaria!

And what will happen if yet another user views the same record?

Seems like you need an extra table (userId, recordId) to store the ‘viewed’ state of the record for all the users.

Your scenario isnt ocurring. The record is like a message. It has a sender and a receiver. So in my model ill add some code that only change the state when the receiver id is equal to the current user id.

You’re first question made me think about security, something i didn’t take care of yet. Thanks :slight_smile:

I’m still not getting it right.

This is my action view at the moment:




public function actionView($id)

	{

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

			'model'=>$this->loadModel($id),

		));

		$model->read="1";

		$model->save();

	}

I tried several things. With double quotes, no quotes. With an extra line:


$model = loadmodel($id)

Does anybody has some suggestions?

Please try this:




public function actionView($id) {

	$model = $this->loadModel($id)

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

		'model'=>$model,

	));

	$model->read=1;

	$model->saveAttributes(array('read'));

}



brilliant,

It’s working!

Thanks mentel!

Happy to help!

Did you notice you were using an undeclared variable?

Try enabling E_NOTICE on your development environment and PHP will warn you. I recommend enabling E_STRICT also.

Some IDEs will also help you with that. I’m using Netbeans currently and I recommend it.

eventually this is the code.




	public function actionView($id){

	  $model = $this->loadModel($id);

		$user_id = Yii::app()->user->id;

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

			'model'=>$model,

		));

		if($user_id === $model->user_id_rec) {

		$model->read=1;

		$model->saveAttributes(array('read'));

		}

	}



Thanks for all the help!

So any user is allowed to read this message, but only when the receiver read it become read.

If you want to deny anyone to read this message, do:


if($user_id !== $model->user_id_rec) 

  throw new Exception('not authorized');

I’d like to suggest a very small improvement to zaccaria’s suggestion:


throw new CHttpException(403, 'Not authorized.');

This way the app will return a 403 (forbidden) status code to the visitor’s browser.

Docs for CHttpException here.

zaccarai,

Thanks for your initiative to help me further. I consider I have to do this for every action on this controller? If you may not read it, you may not edit or delete it either. So I have to add this code to every action? Or is there a better solution for this?

This has become my final actionview:




	public function actionView($id){

	  $model = $this->loadModel($id);

	  $user_id = Yii::app()->user->id;

		if($user_id == $model->user_id_rec or $user_id == $model->user_id_send){

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

			'model'=>$model,

		));

		if($user_id == $model->user_id_rec) {

		$model->read=1;

		$model->saveAttributes(array('read'));

		}

		}

		else {

		throw new CHttpException(403, 'You are not authorized to perform this action.');

		}

	}



All you need is here, on the guide.

Please post if you need any clarification.