Display only records which are associated with the logged in user

Hi!

How do I show only the records of the current logged in user?

Following situation as an example:

I have the model Project, Issue and User. Project and User are in an many-to-many-relation. I have a table "user_project_assignment" which saves the id of a user and the id of the associated project.

In the models Project I have this relation defined: ‘users’ => array(self::MANY_MANY, ‘User’, ‘user_project_assignment(project_id, user_id)’) and in the model User I have defined this relation: ‘projects’ => array(self::MANY_MANY, ‘Project’, ‘user_project_assignment(user_id, project_id)’).

Now currently all created projects are displayed. I want that the logged in user can only see the projects which he created, so all projects which are associated to his user id.

I think I have to add a criteria to the Dataprovider in the actionIndex() method in the ProjectController. But I don’t know how to do it? How can I get only the records of the project table which are in the user_project_assignment table associated to the current logged in user?

Also I want that the logged in user is allowed to view and delete only the projects which he created. So I think I have to put this logic into the actionView and actionDelete methods when I know how to implement this for the actionIndex, but maybe there is a simple solution so that all actions for the projects and issues are only allowed, if the projects are associated to the logged in user.

Would really appreciate your help because I searched for several hours a solution but wasn’t able to find what I need. Maybe I searched not correctly… Hopefully somebody can help me. If you need more information please ask.

Thx.

Waldemar

PS: I’m new to Yii and I’m also not perfect at PHP. I’m studying informatics and still learning.

ID of the current logged in user is available through Yii::app()->user->id

If you are absolutely new to Yii I would suggest going through some of the Authorization tutorials and others.

Thx for your reply. I know how to get the id of the current user. Also already went through the Authorization tutorial and some others and worked with the book “Agile Web Application Development with Yii”. I’m working with Yii for several months now, so I did already accomplish some functionality and I’m not an absolutely newbie. But I still think I’m a newbie. Maybe a little bit more than a newbie. :slight_smile: Sorry for misleading.

I tried further and now was able to filter the results. The actionIndex of my ProjectController now looks this way:


public function actionIndex()

	{

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

			'criteria'=>array(

				'with'=>array('users'=>array(

					'on'=>'users.id=' . Yii::app()->user->getId(),

   					'together'=>true,

   					'joinType'=>'INNER JOIN',

				)),

			),

		));

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

			'dataProvider'=>$dataProvider,

		));

	}

This works great and I see only the projects of the current users. But I still could view a project which is not associated with this user by directly typing in the url of the project into the browser. So I inserted an if-statement into actionView of the ProjectController. Now it looks this way:


public function actionView($id)

	{

		if(Project::model()->with(array(

			'users'=>array(

        		// don't want to select users

        		'select'=>false,

        		// get only users where the id is equal with the id of the current logged in user

        		'joinType'=>'INNER JOIN',

        		'condition'=>'users.id='.Yii::app()->user->getId(),

    		),

		))->findByPk($id)) {


		    $issueDataProvider=new CActiveDataProvider('Issue', array(

		        'criteria'=>array(

		            'condition'=>'issue_id=:issueId',

	                'params'=>array(':issueId'=>$this->loadModel($id)->id),

	            ),

	            'pagination'=>array(

	                'pageSize'=>100,

	            ), 

	        ));

	        

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

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

				'issueDataProvider'=>$issueDataProvider,

			));


		} else {

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

		}

	}

This is working too. Now I can’t view a project which is not associated with the current user. If I want to do it I get the error message.

But I still can view all issues which are created and saved in the database when I type in the correct url. So if somebody would know the correct url he could view the data from other users, which I don’t want. Now I would probably insert another if-statement into the actionView of the IssueController to check against the user id, and would do this with all the actions and all controllers.

But is there a way to do this more elegant and more simple?

  • Waldemar

Did you found the solution? I am looking to do same thing in my app. can you please post the solution?

The solution I currently use I posted in my last post. I just did this with every action in the controller where it is necessary. Till now I didn’t found a better solution.

Found on another thread that you can use the defaultScope() function in the Model.

For example, by adding this code to the model, whenever there is a query for that object, it will add the "where user_id=xx" to it.

Therefore you dont need to modify each action.




public function defaultScope()

{         

	    return array(

	        'condition'=>'user_id='.Yii::app()->user->id,         

	    );     

}