Code Design Question

Hi,

How would you implement that ?

Needs :

  • logged user can had/remove a content to it’s favorites. There is multiple types of contents (news, article, other user…)

  • user can list it’s favorites

  • user can list someone else favorites

  • user can list overall favorites


First I attached a behavior to user (so he could add/delete/list he’s own favorite). But I also have to create a model and a controller to favorite. So Things are splitted behavior + model/controler , i think that’s a bad design.

So maybe it’s better to attach a FavoriteBehavior to contents …

But maybe i should implement a module (+ a behavior ?) ?

Feeling a bit lost :unsure:

What do you think ?

I like to make securty checks in the controller rather than the models.

On the action add/delete favorites check if the user is the owner of the list, if not, throw exception.

Ok.

But to be more clear :

Will you create a behavior (2 behaviors?), a module …

I will just write this code in the action:


if ($model->userid != Yii::app()->user->id)

   throw new Exception

For simple cases I use named scope %)

I have defined named scope ‘own’ in base model, that just adds an additional condition to check ownerId of the record.

Then it goes like this:


$record = MyModel::model()->own()->findByPk($id);

if (!record) {

    // wooops, that's not your record! or it doesn't exist, but who cares?

    throw ...;

}


$record->delete();



Not very good design, but extremely simple and clean.

That’s a great idea for filter record, I usually add an afterFind for throwing exception.

I like to place all user action (update, delete create own record) in a module, in this module I use a modfied copy of each model in which I go like that:


public function afterFind()

{

  if ($model->user_id!==Yii::app()->user->id)

     throw new Exception();

}

This grant that in the entire model noone is authorized to see anything that is not owned.

This saves you if the user manually enter an url like:


/private/car/update/id/123

trying to guess an existing id of a someone else’s record.

These seem like regular controller actions to me. If you’ll be displaying them in a grid or list, create a dataprovider.




public function actionListFavorites($id)

{

    $userId = (isset($id)) ? $id : Yii::app()->user->id;


    $criteria=new CDbCriteria(array(

        'condition'=>'user_id='.$userId

        )

    );


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

        'criteria'=>$criteria,));


    // output view

}



ok, thank you guys.

In fact, i know how to user providers, controlers, etc.

I was just wondering "Should i code a behavior, a module, etc."

Finaly i think i’ll make 2 behaviors. one attached to user (so he can add/remove favorites) and one attached to content models (for afterSave & afterDelete action (so favorites are removed if content gets deleted or unpublished).

I’ll put everything (favorite model, controller, views & behaviors) in a module, that way it will be easier to activate or deactive the favorites related actions, models, etc…