OctoberCMS: How to dynamically filter manage.list in relation configuration file

- 1 answer

Ad

I'm extending the rainlab.user plugin to allow each user to have friends via a simple intermediate table with the following fields:

user_id
friend_id
status

I've therefor extended the Rainlab.User Controller to have Friends tab where all friends of a user are listed:

use RainLab\User\Models\User as FrontUser;
use RainLab\User\Controllers\Users as UsersController;

FrontUser::extend(function($model) {
    $model->belongsToMany['friends']=[
        'RainLab\User\Models\User',
        'table'    => 'meysam_social_friends',
        'pivot' => ['status'],
        'key'      => 'user_id',
        'otherKey' => 'friend_id'
    ];
});

UsersController::extend(function($controller) {
    if(!isset($controller->implement['Backend.Behaviors.RelationController'])) {
        $controller->implement[] = 'Backend.Behaviors.RelationController';
    }
    $controller->relationConfig  =  '$/meysam/social/controllers/user/config_relations.yaml';
});

UsersController::extendFormFields(function($form, $model, $context) {
    if(!$model instanceof FrontUser or $context != 'preview'){
        // friends tab should not be displayed in update and create contexts
        return;
    }

    $form->addTabFields([
        'friends' => [
            'label' => '',
            'tab' => 'Friends',
            'type' => 'partial',
            'path' => '$/meysam/social/controllers/user/_friends.htm',
        ]
    ]);
});

And here is the config_relations.yaml file:

friends:
    label: 'new friend'
    view:
        list: ~/plugins/meysam/social/models/friendspivot/columns.yaml
        toolbarButtons: add|remove
        showSearch: true
    manage:
        showSearch: true
        recordsPerPage: 10
        list: ~/plugins/rainlab/user/models/user/columns.yaml
    pivot:
        form: ~/plugins/meysam/social/models/friendspivot/fields.yaml

Now in the friends tab, list of are friends of the currently selected user are shown and when I click on Add new friend button, the list of all users is shown (manage.list) so that one of the users could be selected as the new friend. My problem is that in this list, all users are shown, even the currently selected user, and therefor a user can be added as his own friend. How can I filter out the current user from this list? I thought of using scope property but then this scope should be dynamic and I don't know how to pass the user_id of the current User Model to this scope.

Ad

Answer

Ad

The current model is passed to the scope methods provided in the view and manage options as the first parameter. I've updated the documentation to reflect this fact.

To give you an example, your config_relation.yaml should look like

friends:
    label: 'new friend'
    view:
        list: ~/plugins/meysam/social/models/friendspivot/columns.yaml
        toolbarButtons: add|remove
        showSearch: true
    manage:
        showSearch: true
        recordsPerPage: 10
        list: ~/plugins/rainlab/user/models/user/columns.yaml
        scope: notThis
    pivot:
        form: ~/plugins/meysam/social/models/friendspivot/fields.yaml

and then the query scope method notThis should be added dynamically to the User Model:

FrontUser::extend(function($model) {
    $model->addDynamicMethod('scopeNotThis', function ($query, $user) {
        return $query->where('id', '!=', $user->id);
    });
});
Ad
source: stackoverflow.com
Ad