This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
Hello Guys,
Could you please help me how can I extend a model of an existing plugin?
I've add a new (subgroup) field to groups controller of shahiemseymor's roles plugin but I would like to extend its UserGroup model as well.
So I tried to put this code into my Plugin.php file:
UserGroup::extend(function($model)
{
$model->hasOne['subgroup'] = ['Company\Project\Models\Group'];
});
My Group model has the the following scheme:
Schema::create('company_project_groups', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('user_group_id');
$table->string('subgroup');
$table->timestamps();
});
...and as I see shahiemseymor's UserGroup model has the following scheme:
Schema::create('shahiemseymor_roles', function($table)
{
$table->increments('id')->unsigned();
$table->string('name')->unique();
$table->timestamps();
});
So as I mentioned I've already put subgroup field into groups controller of the roles plugin but when I save the form it does not create record in my database table...
I've already tried to define foreign keys and local keys, table names and everything else I just found in the documentation but it still doesn't work.
I don't know what could be wrong. Please help me!
Thank you!
ps.: sorry for my poor english... :/
Okay. Here is my pages:
Plugin.php
<?php namespace Codebugs\Ldap;
use System\Classes\PluginBase;
use Event;
use ShahiemSeymor\Roles\Models\UserGroup;
/**
* Ldap Plugin Information File
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Ldap',
'description' => 'No description provided yet...',
'author' => 'Codebugs',
'icon' => 'icon-leaf'
];
}
public function boot()
{
UserGroup::extend(function($model)
{
$model->hasOne['subgroup_name'] = ['Codebugs\Ldap\Models\Subgroup'];
});
Event::listen('backend.form.extendFields', function($widget){
//Extend groups controller
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
$widget->addFields([
'subgroup_name' => [
'label' => 'Sub-group name',
'comment' => 'Select the sub-group name',
'type' => 'text',
'span' => 'auto'
]
]);
});
}
}
Subgroup model (Subgroup.php)
<?php namespace Codebugs\Ldap\Models;
use Model;
/**
* Subgroup Model
*/
class Subgroup extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'codebugs_ldap_subgroups';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [
'group' => ['UserGroup', 'foreignKey' => 'user_group_id']
];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
}
Subgroup table scheme
<?php namespace Codebugs\Ldap\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class CreateSubgroupsTable extends Migration
{
public function up()
{
Schema::create('codebugs_ldap_subgroups', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('user_group_id');
$table->string('subgroup_name');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('codebugs_ldap_subgroups');
}
}
Thank you for your help!
Last updated
I think in your model belongsTo()
need to be the fully qualified namespace of UserGroup
.
So try:
public $belongsTo = [
'group' => ['\ShahiemSeymor\Roles\Models\UserGroup', 'foreignKey' => 'user_group_id']
];
I tried in this way but it still does not work... :(
Do you have other idea what could be the problem?
Thank you!
Last updated
Well I think you'll probably still need to keep that in your model. One other idea is taken from the way they do it with the forum plugin with extending the fields. So you've named your field subgroup_name
and your relationship is named group
. You may want to just change the field name to name
in the db and extend the fields buy using the array syntax.
$widget->addFields([
'group[name]' => [
'label' => 'Sub-group name',
'comment' => 'Select the sub-group name',
'type' => 'text',
'span' => 'auto'
]
]);
It says the following error:
Unexpected type of array, should attribute "group" be jsonable?
What could be wrong?
Post your code. But it sounds like you made the key an actual array instead of an array-like string.
This $group['name']
is not the same as this 'group[name]'
Unfortunately it still not ok... :( Here are my pages now, after the changes...
Plugin.php
<?php namespace Codebugs\Ldap;
use System\Classes\PluginBase;
use Event;
use ShahiemSeymor\Roles\Models\UserGroup;
/**
* Ldap Plugin Information File
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Ldap',
'description' => 'No description provided yet...',
'author' => 'Codebugs',
'icon' => 'icon-leaf'
];
}
public function boot()
{
UserGroup::extend(function($model)
{
$model->hasOne['subgroup_name'] = ['Codebugs\Ldap\Models\Subgroup'];
});
Event::listen('backend.form.extendFields', function($widget){
//Extend groups controller
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
$widget->addFields([
'$group[name]' => [
'label' => 'Sub-group name',
'comment' => 'Select the sub-group name',
'type' => 'text',
'span' => 'auto'
]
]);
});
}
}
Subgroup model (Subgroup.php)
<?php namespace Codebugs\Ldap\Models;
use Model;
/**
* Subgroup Model
*/
class Subgroup extends Model
{
/**
* @var string The database table used by the model.
*/
public $table = 'codebugs_ldap_subgroups';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [
'group' => ['\ShahiemSeymor\Roles\Models\UserGroup', 'foreignKey' => 'user_group_id']
];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
}
Subgroup table scheme
<?php namespace Codebugs\Ldap\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class CreateSubgroupsTable extends Migration
{
public function up()
{
Schema::create('codebugs_ldap_subgroups', function($table)
{
$table->engine = 'InnoDB';
$table->increments('id');
$table->integer('user_group_id');
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('codebugs_ldap_subgroups');
}
}
ShahiemSeymor's UserGroup table scheme
Schema::create('shahiemseymor_roles', function($table)
{
$table->increments('id')->unsigned();
$table->string('name')->unique();
$table->timestamps();
});
What am I doing wrong?
Thank you for your help!
I tried to change by the Forum plugin and my Plugin.php looks like this now:
Plugin.php
<?php namespace Codebugs\Ldap;
use System\Classes\PluginBase;
use Event;
use ShahiemSeymor\Roles\Models\UserGroup;
/**
* Ldap Plugin Information File
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Ldap',
'description' => 'No description provided yet...',
'author' => 'Codebugs',
'icon' => 'icon-leaf'
];
}
public function boot()
{
UserGroup::extend(function($model)
{
$model->hasOne['group'] = ['Codebugs\Ldap\Models\Subgroup'];
});
Event::listen('backend.form.extendFields', function($widget){
//Extend groups controller
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
$widget->addFields([
'group[name]' => [
'label' => 'Sub-group name',
'comment' => 'Select the sub-group name',
'type' => 'text',
'span' => 'auto'
]
]);
});
}
}
But when I try to save the form on backend I receive the following error message:
"Creating default object from empty value"
Can you help me what could be the problem now?
Thank you!
I would really just keep using the forum as an example. Specifically, the way the forum_user
interacts with the Member
and User
model. You'll need to populate the data from the base UserGroup
and make sure it is stored on your group model relationship.
Thank you a2thek26. Just a last question: Are my relationship settings are ok in the Plugin.php and in my Subgroup model?
I ask it because ShahiemSeymor does not use user_group_id field in the shahiemseymor_roles table so the link reference would be the following:
subgroupmodel.user_group_id = usergroupmodel.id (but the usergroup model uses the table shahiemseymor_roles)
So did I set the relationships fine?
Thank you for your help!
One thing to remember is that whatever you set the relationship alias to, is how you will end up referencing the relationship when using the model. So if UserGroup
is the model you are extending by adding a Subgroup
, it is referenced by the alias. You are extending the UserGroup
with the alias group
(which is your subgroup). Because you've aliased Subgroup
as group
and you want the name
field. (you may want to changed the alias to subgroup
just so it is clear)
$userGroup = UserGroup::find(1);
$subGroupName = $userGroup->subgroup->name;
The reverse is the same for referencing the UserGroup
from the Subgroup
:
$subGroup = Subgroup::find(8);
$userGroupName = $subGroup->group->name;
Hope that makes sense.
But how October knows what columns should match if these names are differs? I mean the UserGroup model uses the shahiemseymor_roles table and there is only an id and a name field in it. My Subgroup model uses table codebugs_ldap_subgroups and it also has an id but I would like if the usergroup.id would be linked to subgroups.user_group_id. (usergroup.id = subgroup.user_group_id) and every UserGroup has one subgroup
How should I set the relationships?
Sorry, my english is poor but I hope you understand what I would like to say...
In your Subgroup
Model you should have this:
public $belongsTo = [
'group' => ['\ShahiemSeymor\Roles\Models\UserGroup', 'foreignKey' => 'user_group_id']
];
In your plugin you should have this:
public function boot()
{
UserGroup::extend(function($model)
{
$model->hasOne['subgroup'] = ['Codebugs\Ldap\Models\Subgroup'];
});
Event::listen('backend.form.extendFields', function($widget){
//Extend groups controller
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
$widget->addFields([
'subgroup[name]' => [
'label' => 'Sub-group name',
'comment' => 'Select the sub-group name',
'type' => 'text',
'span' => 'auto'
]
]);
});
}
Last updated
I just noticed some interesting thing...
I've added a new record manualy to my subgroup table and when I checked in the backend form the value appeared in the subgroup field and I was able to change that, so I was able to update the existing record... BUT when I tried to create a new record via backend (so not manually in the database table) I received the error message that "Creating default object from empty value"
Should I make some pre-check if the form uses update or create method?
Or what should I do to make it work when I create brand new record?
Here is my Plugin.php file now:
<?php namespace Codebugs\Ldap;
use Event;
use Backend;
use ShahiemSeymor\Roles\Models\UserGroup;
use Codebugs\Ldap\Models\Subgroup;
use System\Classes\PluginBase;
/**
* Forum Plugin Information File
*/
class Plugin extends PluginBase
{
public $require = ['ShahiemSeymor.Roles'];
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Ldap',
'description' => 'A simple embeddable forum',
'author' => 'Alexey Bobkov, Samuel Georges',
'icon' => 'icon-comments'
];
}
public function boot()
{
UserGroup::extend(function($model) {
$model->hasOne['forume'] = ['Codebugs\Ldap\Models\Subgroup'];
});
Event::listen('backend.form.extendFields', function($widget) {
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
//if ($widget->getContext() != 'update') return;
//if (!Member::getFromUser($widget->model)) return;
$widget->addFields([
'forume[name]' => [
'label' => 'Username',
'tab' => 'Forum',
'comment' => 'The display to represent this user on the forum.',
],
], 'primary');
});
Event::listen('backend.list.extendColumns', function($widget) {
if (!$widget->getController() instanceof \ShahiemSeymor\Roles\Controllers\Groups) return;
if (!$widget->model instanceof \ShahiemSeymor\Roles\Models\UserGroup) return;
$widget->addColumns([
'subgroup_name' => [
'label' => 'Forum Username',
'relation' => 'forume',
'select' => 'name',
'searchable' => true,
]
]);
});
}
}
Thank you for your help!
Last updated
This line if ($widget->getContext() != 'update') return;
will extend the form if it isn't creating the record. So on update
, it will extend the form. Which means it will update properly. So that is the pre-check you are speaking of.
But if I put this line into my code and the page is not the update page but the create page than the subgroup field don't appear on the page...