2

I like to build a Plugin where Frontend User belongsTo BackendUser ( One to Many Relation ). For the backend User i want to display an partial with Relation Manager to add many Frontend Users to BackendUser. If i try dynamically define a property on Plugin.php like:

use Backend\Models\User as BackendUser;
use Backend\Controllers\Users as BackendUsersController;


public function boot(){    
    BackendUsersController::extend(function($controller) {  
        $controller->implement[] = 'Backend.Behaviors.RelationController';  
        $controller->relationConfig = '$/plg-user/plg/controllers/plg-ctr/config_relation.yaml'  
    });
});

i get an Error : Class Backend\Controllers\Users must define property $relationConfig used by Backend\Behaviors\RelationController behavior

If i try to put manually :

public $relationConfig = '$/plg-user/plg/controllers/plg-ctr/config_relation.yaml'

to the Backend\Controllers\Users Controller everything woks.

any Idea ?

JBee
  • 23
  • 2

2 Answers2

3

The problem arises because any object that implements the October\Rain\Extension\ExtendableTrait trait (like the Users controller does, which is how you can call ::extend() on it) prevents undeclared properties from being auto-declared on first assignment.

Instead, you must use the addDynamicProperty($property, $value) method to add undeclared properties to the object. This was previously undocumented and was documented in octobercms/docs@9d454c.

An example of working code for your case would now be

/**
 * Extend the BackendUsers controller to include the RelationController behavior
 */
BackendUsersController::extend(function($controller) {

    // Implement the list controller behavior dynamically
    $controller->implement[] = 'Backend.Behaviors.RelationController';

    // Declare the relationConfig property dynamically for the RelationController behavior to use
    $controller->addDynamicProperty('relationConfig', '$/plg-user/plg/controllers/plg-ctr/config_relation.yaml');
});
LukeTowers
  • 1,262
  • 7
  • 14
0

I've extended the front-end user controller in the exact same way and it works:

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

I think the difference is that relationConfig has already been defined in the front-end user controller class:

class Users extends Controller
{
    public $implement = [
        'Backend.Behaviors.FormController',
        'Backend.Behaviors.ListController'
    ];

    public $formConfig = 'config_form.yaml';
    public $listConfig = 'config_list.yaml';
    public $relationConfig;

And public $relationConfig; does not exist in the backend user controller. A workaround might be to create your own backend user controller class which inherits from Backend\Controllers\Users and add a public $relationConfig; property to it. This may not be the best solution though.

B Faley
  • 17,120
  • 43
  • 133
  • 223
  • Hi Meysam.... Thank you ... I also think that creating my own Backend User Controller class is not the best solution ;) ... Is it not possible to add the public $relationConfig; property to the Backend\Controllers\Users class dynamically ? – JBee Apr 07 '17 at 12:42
  • @JBee That could be possible, I don't know how to do that and am interested to know. – B Faley Apr 07 '17 at 17:57
  • 1
    Meysam see my answer above – LukeTowers Apr 12 '17 at 21:48