I'm trying to learn OctoberCMS and I am confused about the complete process of extending plugins. I've extended the user plugin according to the screencast (https://vimeo.com/108040919). Ultimately, I'm looking to create a new field called "category" which wold store a users category. On a new page, I have the following form which I am trying to use to register a new user based solely on their e-mail address. The "category" is populated based on the page that they registered from and the password should be automatically generated so that the user will set it upon confirming their account from an e-mail activation link. My plugin is called "Profile".
My plugin.php file looks like:
<?php namespace Sser\Profile;
use System\Classes\PluginBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Controllers\Users as UsersController;
use Sser\Profile\Models\Profile as ProfileModel;
/**
* Profile Plugin Information File
*/
class Plugin extends PluginBase
{
/**
* Returns information about this plugin.
*
* @return array
*/
public function pluginDetails()
{
return [
'name' => 'Profile',
'description' => 'Handles user demographic information',
'author' => '',
'icon' => 'icon-leaf'
];
}
public function boot()
{
UserModel::extend(function($model){
$model->hasOne['profile'] = ['Sser\Profile\Models\Profile'];
});
// $user->profile->zip
UserModel::deleting(function($user) {
$user->profile->delete();
});
UsersController::extendFormFields(function($form,$model,$context){
if(!$model instanceof UserModel)
{
return;
}
if(!$model->exists)
{
return;
}
//Ensures that a profile model always exists...
ProfileModel::getFromUser($model);
$form->addTabFields([
'profile[age]'=>[
'label'=>'Age',
'tab'=>'Profile',
'type'=>'number'
],
'profile[gender]'=>[
'label'=>'Gender',
'tab'=>'Profile',
'type'=> 'dropdown',
'options'=>array('male'=>'Male',
'female'=>'Female')
],
'profile[category]'=>[
'label'=>'Category',
'tab'=>'Profile',
'type'=> 'dropdown',
'options'=>array('sink'=>'SINK',
'dink'=>'DINK')
],
'profile[vag]'=>[
'label'=>'VAG',
'tab'=>'Profile',
'type'=> 'dropdown',
'options'=>array('v'=>'V',
'a'=>'A',
'g'=>'G')
]
]);
});
}
}
My profile.php file looks like:
<?php namespace Sser\Profile\Models;
use Model;
use \October\Rain\Database\Traits\Validation;
/**
* Profile Model
*/
class Profile extends Model
{
public $rules = [
'category' => ['required', 'min:0']
];
/**
* @var string The database table used by the model.
*/
public $table = 'sser_profile_profiles';
/**
* @var array Guarded fields
*/
protected $guarded = ['*'];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Relations
*/
public $hasOne = [];
public $hasMany = [];
public $belongsTo = [
'user'=> ['RainLab\User\Models\User']
];
public $belongsToMany = [];
public $morphTo = [];
public $morphOne = [];
public $morphMany = [];
public $attachOne = [];
public $attachMany = [];
public static function getFromUser($user)
{
if($user->profile)
{
return $user->profile;
}
$profile = new static;
$profile->user = $user;
$profile->save();
$user->profile = $profile;
return $profile;
}
}
I am trying to create a user registration form that looks like the following:
<form class="flexiContactForm col s12" role="form" data-request="{{ __SELF__ }}::onSignup" data-request-update="'{{ __SELF__ }}::confirm': '.confirm-container'">;
<button id="signup_button" class="waves-effect waves-light btn" style="float:right;" type="submit">Sign Up</button>
<div style="overflow: hidden; padding-right:0em;">
<input id="signup_email" type="email" class="validate" name="email">
<label id="signup_email_label" for="signup_email" data-error="" data-success="">Email Address</label>
<input type="hidden" name="category" value="{{ data.category }}"/>
</div>
</form>
What I am confused about is how to make an "onSignup" component that will basically extend the functionality of the user plugins "onRegister" component and then automatically generate a password and also save the "category" field. Can anyone provide an example or link to a page that shows an example of this? Thanks.
Okay, I just had to do something like this for my own site. So I'll try and explain the 2 options you have.
1: Override stuff using the theme and page php.
Override the form. To do this, copy register.htm from plugins/rainlabs/user/components/account/register.htm to themes/site-theme/partials/account/register.htm. You can now update the form to have any fields you want.
On your account login/register page, put php in the php section to override the default onRegister() function:
title = "Account"
url = "/account/:code?"
layout = "default"
description = "The account page"
is_hidden = 0
[account]
redirect = "home"
paramCode = "code"
[session]
security = "all"
==
function onRegister()
{
try {
//Do Your Stuff (generate password, category)
//Inject the variables
return $this->account->onSignin();
}
catch (Exception $ex) {
Log::error($ex);
}
}
==
2: Create a component to do it all. This is the way I ended up going
Now you need to update the component AccountExtend.php. First, some changes to make it work right (I haven't included all code, just stuff that needs changes):
use RainLab\User\Components\Account as UserAccount;
class AccountExtend extends UserAccount
And then update the Plugin.php file for your plugin, to activate the component:
public function registerComponents()
{
return [
'Foo\Bar\Components\AccountExtend' => 'account',
];
}
Now you can add the onRegister() function to your AccountExtend.php:
public function onRegister() {
//Do anything you need to do
$redirect = parent::onRegister();
$user = $this->user(); // This is the user that was just created, here for example, dont need to assign it really
// Now you can do stuff with any of the variables that were generated (such as user above)
// Return the redirect so we redirect like normal
return $redirect;
}