Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OctoberCMS How To Create Custom User Registration Form With Fields From Plugin Extension

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.

like image 794
user2694306 Avatar asked Jan 08 '16 16:01

user2694306


People also ask

How do I add a field in user registration form?

Step 2: Add Custom Fields to Your Registration Form To do that, go to Custom Fields » Add New. Then give your field group a name like “User Profile.” After that, click Add New to add a field to that group and enter the name and label details.

How do I create a custom registration form in WordPress?

You need to create a new post/page or edit an existing one. In your WordPress editor, click on the plus (+) sign at the top and then scroll down to the widgets section to add a WPForms block. After that, you can select your custom registration form from the dropdown menu in the WPForms block.


2 Answers

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.

  1. 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.

  2. 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

  1. php artisan create:component Foo.Bar AccountExtend to create your component
  2. Now go into the component and change some things around. First you'll need to copy all the files from plugins/rainlabs/user/components/account/ to plugins/Foo/Bar/components/accountextend/
  3. 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
    
  4. And then update the Plugin.php file for your plugin, to activate the component:

        public function registerComponents()
        {
            return [
               'Foo\Bar\Components\AccountExtend' => 'account',
            ];
        }
    
  5. 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;
      }
    
like image 196
Fooldj Avatar answered Oct 27 '22 19:10

Fooldj


It's definitely confusing. Take a look at the User Plus plugin as a guide and the locations plugin (required) to add country/state dropdown.

  1. You'll have to add a new table or add a field to user's table using "updates/migrations" to add something like "category_id" for the user. it will save it for you.

  2. Make sure this is set fillable as user creation will fill the model with the form data otherwise it won't save. this is on boot, the user's plus plugin has this so check it out.

  3. Make a new table for you're categories, and make a component part that can fetch the list. see the locations plugin for this... the part that fetches the data/seeds the list is in the component.

  4. You'll need to make a new component partial or use it right in the cms partial specifying the new fields.

Far as making the password random, not 100% the best way but you can use onInit for your component to just seed one in the form post data. the password field has to be added to the post data since the user's plugin passes the post fields to the model (which is why you must set category_id as fillable or it gets blocked for security reasons).

I am messing with this stuff myself and the users plus with the location plugin helped a lot.

Sorry i couldn't be more detailed.

like image 2
Eric Kelly Avatar answered Oct 27 '22 19:10

Eric Kelly