yii2-save-relations-behavior icon indicating copy to clipboard operation
yii2-save-relations-behavior copied to clipboard

Enh: Аdjust access to save the relation

Open sokollondon opened this issue 4 years ago • 4 comments

Is there such a functional? For example, I need adjust access. So that only the admin could save relation tags

public function scenarios()
{
    $s = parent::scenarios();
    if(Yii::$app->user->can('admin')){
        $s[self::SCENARIO_DEFAULT][] = 'tags';
    }
    return $s;
}
var_dump($project->isAttributeSafe('tags')); //false

But relation tags save anyway when $project->save();

sokollondon avatar Feb 10 '21 05:02 sokollondon

I did it as optional feature, see pull request. Config

public function behaviors()
{
    return [
        'saveRelations' => [
            'class' => SaveRelationsBehavior::class,
            //...
            'checkRelationsSafe' => true,// <--
        ],
    ];
}

That's all. Now only safe relation will be saved.

Аdjust

public function rules()
{
    return [
        //...
        [['company','users','projectLinks'], 'safe'],//other safe relations
    ];
}

public function scenarios()
{
    $s = parent::scenarios();
    if(Yii::$app->user->can('admin')){//your access condition
        $s[self::SCENARIO_DEFAULT][] = 'tags';
    }
    return $s;
}

sokollondon avatar Feb 10 '21 10:02 sokollondon

Hi @sokollondon

Thank you for your Pull Request.

I'm wondering why you could not configure relations like this:

public function behaviors()
    {
        $relations = [
            'company',
            'users',
            'contacts',
            'images',
            'links'        => ['scenario' => Link::SCENARIO_FIRST],
            'projectLinks' => ['cascadeDelete' => true]
        ];
        if (Yii::$app->user->can('admin')) {
            $relations['tags'] = [
                'extraColumns' => function ($model) {
                    /** @var $model Tag */
                    return [
                        'order' => $model->order
                    ];
                }
            ];
        }
        return [
            'saveRelations' => [
                'class'     => SaveRelationsBehavior::className(),
                'relations' => $relations
            ],
        ];
    }

Isn't this would be the same as what you're trying to do in the first place?

juban avatar Feb 14 '21 15:02 juban

@sokollondon OK, I misunderstood what you where trying to do, sorry. I will probably publish a new major version which will honor the safe validation rule as it is a breaking change (as also suggested by @artemryzhov in its previous PR) I'm not a big fan of adding another property to activate the check, ever for backward compatibility sake, as it should probably be the case by default (my bad).

juban avatar Feb 14 '21 16:02 juban

Thanks for the answer @juban =)

  1. Why I can't use behaviors() Above, I made a simplified example. Actually I need to use AR fields in the condition
if(Yii::$app->user->can('admin') && $this->type_id == 1){
    //...
}

But in behaviors() all AR fields is NULL. Because not set yet.

  1. Disadvantages of default validation. The programmer will have to add each relation in 2 places. In behaviors() and rules(). This makes installation more difficult. I think most people don't need this validation feature. Therefore, should not do it by default.

sokollondon avatar Feb 15 '21 05:02 sokollondon