Jump to content

FrontendUserRegister


pwFoo
 Share

Recommended Posts

FrontendUserRegister
(dev / maybe unstable!!!)
 
Simple user registration process. Create a new user with checked values if

  • username & email isn't taken by a existing user and not empty
  • a correct password is set

Required

  • FormHelper Version 0.0.5+

 
Download

Usage

// load module and output the register form 
echo $fur = $modules->get('FrontendUserRegister')->register("{$redirect_after_register}");

Planned features

  • email activation

Module isn't available anymore, but it's planed to replace FrontendUserLogin and FrontendUserRegister with the new FrontendUser module which is not released yet.

A new support topic will be created after FrontendUser module is added to the PW module repo.

Added new FrontendUser module

Edited by pwFoo
  • Like 2
Link to comment
Share on other sites

  • 3 months later...

Register module with plugin feature. Form is unstyled at the moment, but register a user works.

Honeypot plugin is at the moment a visible additional form field (should be hidden by css or js), but should give you an idea about the planned plugin structure.

https://bitbucket.org/pwFoo/frontenduserregister/src/bb750e24afe356d36bc1d2bb064ccd925fd92e9e/FrontendUserRegister/?at=master

Because most methods are hookable module is extendable with plugins like email (pre register?) verification, additional form fields, ...

Link to comment
Share on other sites

  • 1 month later...

New testing FrontendUser module could be replace FrontendUserRegister and FrontendUserLogin module. It requires FormHelper (0.7.1+)

Repo: https://bitbucket.org/pwFoo/frontenduser/src

FrontendUserLogin

Details: https://processwire.com/talk/topic/8001-frontenduserlogin/?p=92538

  • Simple / basic login / logout module
  • error handling
  • default and custom styles / scrips
  • extendable with plugins (PW hooks!), examples: login with email address instead of username, PersistLogin and ProcessForgotPassword integration

FrontendUserRegister

  • Simple / basic user register module (username, email, password)
  • error handling
  • default and custom styles / scrips
  • extendable with plugins (PW hooks!), examples: further down

FrontendUserRegister (simple usage)

Only use basic fields and features.

$fu = $modules->get('FrontendUserRegister');
$content = $fu->render($redirectAfterRegister);

AddRole plugin

Really simple plugin / hook to add a default role before user will be saved

$fu = $modules->get('FrontendUserRegister');
$form = $fu->form();

$fu->addHookBefore('saveUser', function($event) {
    $user = $event->object->attr('userObj');
    $user->addRole('superuser');
});

$content = $fu->validate()->process()->renderForm();

Display name plugin

Username will be sanitized as username, but you could add a field "nickname" to the user template with username value sanitized as text instead of username.

// Dispay- / Nickname
$fu->addHookBefore('saveUser', function($event) {
    $fu = $event->object;
    $form = $fu->attr('form');
    
    if(!count($form->getErrors())) {
        $fu->attr('userObj')->nickname = $form->fhValue('username', 'text');
    }
});

Pre-validate email address plugin

A more complex plugin to add a additional register step. It removes the password field and adds an validation code input field. After submit username and email address you'll get an email with a validation code. Second step enter the code and a password to register a PW user.

The code includes some debugging information / output because it needs more testing...

$fu = $modules->get('FrontendUserRegister');

function validationCodeField() {
    $validation = wire('modules')->get('InputfieldText');
    $validation->attr('id+name', 'EmailPreValidation');
    $validation->placeholder = 'Email validation code';
    $validation->skipLabel = 4;
    $validation->required = 1;
    return $validation;
}

// modified / extended register form
$form = $fu->form(array('username', 'email', validationCodeField(), 'password'))->attr('form');

$form->addhookBefore('processInput', function($event) {
    $form = $event->object;
    
    var_dump(wire('input')->post); echo "<hr />";
    
    if (empty(wire('session')->get('registerStep'))) {
        $form->get('password')->required = false;
        $form->get('EmailPreValidation')->required = false;
    }
});

$form->addhookAfter('processInput', function($event) {
    $form = $event->object;
    $user = $form->get('username');
    $email = $form->get('email');
    
    if (!empty(wire('session')->get('registerStep')) && wire('session')->get('registerEmail') !== $form->fhValue('email')) {
        wire('session')->remove('registerStep');
        $form->get('EmailPreValidation')->value = '';
        $form->fhSubmitBtn->error('Validation broken by email address mismatch!');
        wire('session')->redirect(wire('page')->url, false);
    }
    elseif (empty(wire('session')->get('registerStep')) && !count($user->getErrors()) && !count($email->getErrors())) {
        echo "SET Session values!<br />";
        wire('session')->set('registerToken', md5(uniqid(mt_rand(), true)));
        wire('session')->set('registerUsername', $form->fhValue('username'));
        wire('session')->set('registerEmail', $form->fhValue('email'));
        wire('session')->set('registerStep', 1);
        
        // Send validation code email
        wireMail($form->fhValue('email'), null, 'Email address pre-validation', "Validation token: " . wire('session')->get('registerToken'));        
    }
    elseif (!count($user->getErrors()) && !count($email->getErrors())) {
        if ($form->fhValue('EmailPreValidation') != wire('session')->get('registerToken')) {
            $form->get('EmailPreValidation')->error('Email validation code NOT match!');
        }
    }
});

$form->addhookBefore('render', function($event) {
    $form = $event->object;
    
    if ($form->fhState === null) {
        wire('session')->remove('registerStep');
    }
    elseif (wire('session')->get('registerStep') === 1) {
        $form->fhSubmitBtn->getErrors(true);
    }
    
    if (empty(wire('session')->get('registerStep'))) {
        $form->remove($form->get('password'));
        $form->get('EmailPreValidation')->attr('disabled', true);
        $form->fhSubmitBtn->value = 'Send email validation code';
        
        echo "RESET Session values!<br />";
        wire('session')->remove('registerToken');
        wire('session')->remove('registerUsername');
        wire('session')->remove('registerEmail');
    }
    
    echo "RegisterStep: " . wire('session')->get('registerStep') . "<br />";
    echo "Username: " . wire('session')->get('registerUsername') . "<br />";
    echo "Email: " . wire('session')->get('registerEmail') . " == " . $form->fhValue('email') . "<br />";
    echo "Token: " . wire('session')->get('registerToken') . "<br />";
});

$content = $fu->validate()->process()->renderForm();
  • Like 2
Link to comment
Share on other sites

FrontendUserRegistration module deletion requested, because it's an old and deprecated version.

Last posts here reference to a redesigned and not compatible new module / branch.

I have deleted this module from the directory, but you should consider removing the link from your first post and explain to users what the alternative is.

Link to comment
Share on other sites

  • 2 weeks later...

First, you needn't read and understand all the source code following here. It's a design question ;)

Simple FrontendUser plugins are small code snippets (PW hooks) and could be added to the template.

// add a default role during user registration
$fu->addHookBefore('save', function($event) {
    $user = $event->object->attr('userObj');
    $user->addRole('superuser');
});
// Fill nickname field with username sanitized as text instead of username
$fu->addHookBefore('save', function($event) {
    $fu = $event->object;
    $form = $fu->attr('form');

    if(!count($form->getErrors())) {
        $fu->attr('userObj')->nickname = $form->fhValue('username', 'text');
    }
});
It's to small to build a PW module, isn't it???

But some plugins are more complex like email pre-register validation...

function validationCodeField() {
    $validation = wire('modules')->get('InputfieldText');
    $validation->attr('id+name', 'EmailPreValidation');
    $validation->placeholder = 'Email validation code';
    $validation->skipLabel = 4;
    $validation->required = 1;
    return $validation;
}

$form = $fu->register(array('username', 'email', validationCodeField(), 'password'))->attr('form');

$form->addhookBefore('processInput', function($event) {
    $form = $event->object;

    var_dump(wire('input')->post); echo "<hr />";

    if (empty(wire('session')->get('registerStep'))) {
        $form->get('password')->required = false;
        $form->get('EmailPreValidation')->required = false;
    }
});

$form->addhookAfter('processInput', function($event) {
    $form = $event->object;
    $user = $form->get('username');
    $email = $form->get('email');

    if (!empty(wire('session')->get('registerStep')) && wire('session')->get('registerEmail') !== $form->fhValue('email')) {
        wire('session')->remove('registerStep');
        $form->get('EmailPreValidation')->value = '';
        $form->fhSubmitBtn->error('Validation broken by email address mismatch!');
        wire('session')->redirect(wire('page')->url, false);
    }
    elseif (empty(wire('session')->get('registerStep')) && !count($user->getErrors()) && !count($email->getErrors())) {
        echo "SET Session values!<br />";
        wire('session')->set('registerToken', md5(uniqid(mt_rand(), true)));
        wire('session')->set('registerUsername', $form->fhValue('username'));
        wire('session')->set('registerEmail', $form->fhValue('email'));
        wire('session')->set('registerStep', 1);

        // Send validation code email
        wireMail($form->fhValue('email'), null, 'Email address pre-validation', "Validation token: " . wire('session')->get('registerToken'));        
    }
    elseif (!count($user->getErrors()) && !count($email->getErrors())) {
        if ($form->fhValue('EmailPreValidation') != wire('session')->get('registerToken')) {
            $form->get('EmailPreValidation')->error('Email validation code NOT match!');
        }
    }
});

$form->addhookBefore('render', function($event) {
    $form = $event->object;

    if ($form->fhState === null) {
        wire('session')->remove('registerStep');
    }
    elseif (wire('session')->get('registerStep') === 1) {
        $form->fhSubmitBtn->getErrors(true);
    }

    if (empty(wire('session')->get('registerStep'))) {
        $form->remove($form->get('password'));
        $form->get('EmailPreValidation')->attr('disabled', true);
        $form->fhSubmitBtn->value = 'Send email validation code';

        echo "RESET Session values!<br />";
        wire('session')->remove('registerToken');
        wire('session')->remove('registerUsername');
        wire('session')->remove('registerEmail');
    }

    echo "RegisterStep: " . wire('session')->get('registerStep') . "<br />";
    echo "Username: " . wire('session')->get('registerUsername') . "<br />";
    echo "Email: " . wire('session')->get('registerEmail') . " == " . $form->fhValue('email') . "<br />";
    echo "Token: " . wire('session')->get('registerToken') . "<br />";
});
How to handle such complex plugins? As template "snippet" / include code or as a extension PW module?

Should each plugin be a PW module or shouldn't we create endless quantity of small modules?

Link to comment
Share on other sites

If it makes sense for each snippet to work on it's own, independent of the others, then having modules for each one could make sense. But if most of them are just few-liners I would most likely go with a single central module, where the single snippets can be enabled/disabled in the options. 

  • Like 1
Link to comment
Share on other sites

Thanks LostKobrakai,

I moved the complex email validation plugin, ProcessForgotPassword and LoginPersist module integration into the FrontendUser module for testing.

If anyone would do some tests...

Repo: https://bitbucket.org/pwFoo/frontenduser/overview

Doku: https://bitbucket.org/pwFoo/frontenduser/wiki/Documentation

Current download for testing: https://bitbucket.org/pwFoo/frontenduser/get/master.zip

Edited by pwFoo
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...