pwFoo

FrontendUser: login, logout and register users / members

Recommended Posts

FrontendUser uses a temp PW User object. All existing fields should be saved, but it's done via PW api, not the PW admin create user process (haven't looked into it...).

Send email after user registration? You could write a plugin hook after FrontendUser save() method...

    /**
     * Save the temp User object
     * @param User $user Temp User object to save
     * @return boolean Sucessful (true) saved or not (false)
     */
    protected function ___save($user) {
        if (empty($user->name) || empty($user->email) || $user->pass->hash == '') {
            return $this->_('Register process unexpected failed!');
        }
        if ($user->save()) {
            return true;
        }
        return $this->_('User registration failed!');
    }

Hook after save() method. If return value  === true (exactly true! not "== true") you can send a mail via PW api or load a module to send the email...

  • Like 1

Share this post


Link to post
Share on other sites

Thats actually my code. It works for register but dont work for the Email new user. 

Ive thought i could write i plugin hook but i cant :D

So please help where is the mistake ? 

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

// prepare login form (default parameters)
$fu->login();

// Default parameter
//$fu->login(array('username', 'password'));

// Additional LoginPersist and ProcessForgotPassword module integration (built-in)
$fu->login(array('username', 'password',  'forgot'));

// process login / form submit
$fu->process('../objekte/');

// output form
echo $fu->render();


$modules->get('EmailAdminNewUser'); // lade Modul um den Admin zu benachrichtigen 
$u_vorname = $modules->get('InputfieldText');
$u_vorname->label = $this->_('Vorname');
$u_vorname->attr('id+name', 'u_vorname');
$u_vorname->required = 1;
$u_vorname->fhSanitizer = 'text';

$nachname = $modules->get('InputfieldText');
$nachname->label = $this->_('Nachname');
$nachname->attr('id+name', 'nachname');
$nachname->required = 1;
$nachname->fhSanitizer = 'text';

$unternehmen = $modules->get('InputfieldText');
$unternehmen->label = $this->_('Unternehmen');
$unternehmen->attr('id+name', 'unternehmen');
$unternehmen->required = 1;
$unternehmen->fhSanitizer = 'text';

$strnr = $modules->get('InputfieldText');
$strnr->label = $this->_('Strasse / Hausnummer');
$strnr->attr('id+name', 'strnr');
$strnr->required = 1;
$strnr->fhSanitizer = 'text';

$plz = $modules->get('InputfieldText');
$plz->label = $this->_('Plz / Ort');
$plz->attr('id+name', 'plz');
$plz->required = 1;
$plz->fhSanitizer = 'text';

$tel = $modules->get('InputfieldText');
$tel->label = $this->_('Telefonnummer');
$tel->attr('id+name', 'tel');
$tel->required = 1;
$tel->fhSanitizer = 'text';

$fu->addHookBefore('save', function($event) {
    $form = wire('fu')->form;
    $user = wire('fu')->userObj;
    $user->addRole('registered');

    if(!count($form->getErrors())) {

        wire('fu')->userObj->u_vorname = $form->fhValue('u_vorname', 'text');
        wire('fu')->userObj->u_nachname = $form->fhValue('nachname', 'text');
        wire('fu')->userObj->u_unternehmen = $form->fhValue('unternehmen', 'text');
        wire('fu')->userObj->u_hausnummer = $form->fhValue('strnr', 'text');
        wire('fu')->userObj->u_plzort = $form->fhValue('plz', 'text');
        wire('fu')->userObj->u_telefonnummer = $form->fhValue('tel', 'text');

    
    }
});


// prepare register form
$fu->register();
$fu->register(array('username',  $u_vorname, $nachname, $unternehmen , $strnr, $plz, $tel, 'email', 'password'));
$fu->process('/');
echo $fu->render();

The admin need an email with new user details and a link to activate this user. 

Because there are 3 different view gropus of users. 

Where i put the code for my custom email to the user admin ? 

I tried to understand it with the after hooks but how to hook the press on the registeration button ? 

Thanks 

PS: I have some problems with the forget user funktion. I see it twice ? 

if im logged in i see blank place. can i set a message like you are logged in currently ? 

Share this post


Link to post
Share on other sites

Hi,

$modules->get('EmailAdminNewUser'); // lade Modul um den Admin zu benachrichtigen 

I haven't used or seen EmailAdminNewUser before. So I don't know how it should work / triggered...

    public function init() {
        if($this->data['generatePassword']){
            $this->addHookBefore('InputfieldPassword::render', $this, 'notRequiredNote');
            $this->addHookBefore('InputfieldPassword::processInput', $this, 'removeRequired');
        }
        if(wire('page')->process == "ProcessUser") $this->addHookAfter('ProcessPageEdit::buildFormContent', $this, 'addEmailFields');
        $this->addHookAfter('Password::setPass', $this, 'getPassword');
        $this->pages->addHookBefore('saveReady', $this, 'sendNewUserEmail');
    }

FrontendUser "save()" method won't trigger it I think...

EmailAdminNewUser will only work if it hooks into $user->save().

Share this post


Link to post
Share on other sites

hmm but it doesent relly work for me still ? 

why ? 

The testmail works but the Module not really.

 

Share this post


Link to post
Share on other sites

hmm but it doesent relly work for me still ? 

why ? 

The testmail works but the Module not really.

Try putting $modules->get('EmailAdminNewUser');

After

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

At least that is how I have it.

Do you have this in site/config.php:

/**
* adminEmail: address to send optional fatal error notifications to.
*
*/
$config->adminEmail = 'name@exampledomain.com';

Because my module is getting the email with

wire('config')->adminEmail

I did notice that I didn't even have that config set, but it still always worked for me..

Share this post


Link to post
Share on other sites

I haven't take a look into it, but add hooks have to be done before $fu->process(). After this method the form is processed by PW.

Why not send the email by wireMail() with custom content and recipient?

$mail = wireMail();
$mail->to($adminEmail);
$mail->subject($subject);

// html body
//$mail->bodyHTML($emailContentHtml);

// plain body
$mail->body($emailContentPlain);

$mail->send();

Could be done hooked after FrontendUser::save.

  • Like 1

Share this post


Link to post
Share on other sites

I haven't take a look into it, but add hooks have to be done before $fu->process(). After this method the form is processed by PW.

Why not send the email by wireMail() with custom content and recipient?

$mail = wireMail();
$mail->to($adminEmail);
$mail->subject($subject);

// html body
//$mail->bodyHTML($emailContentHtml);

// plain body
$mail->body($emailContentPlain);

$mail->send();

Could be done hooked after FrontendUser::save.

Thanks heaps! Now I can throw away my silly little module made in a hurry.

Here is a solution that will email to all your superusers, thanks to LostKobrakai for being there on IRC to give advice:

  $form->addHookAfter('FrontendUser::save', function() use($fu, $input) {
    $superusers = wire('users')->find("roles=superuser");
    $emails = $superusers->explode('email');
    $subject = "A new user registered at the site: " . $fu->userObj->fullname;
    $emailContentPlain = "Go and activate them: http://www.mysite.fi/myadmin/";
    $mail = wireMail();
    $mail->to($emails);
    $mail->from('admin@mysite.fi');
    $mail->subject($subject);

    // plain body
    $mail->body($emailContentPlain);

    $mail->send();
  });
 
  $fu->process($redirectDestination);

Note: wire('pages')->find("template=user.. did not work. It had to be wire('users') !!

$fu->userObj->fullname; is getting the value of my extra field, fullname.

  • Like 1

Share this post


Link to post
Share on other sites

Hey there pwFoo this is great! Great module you wrote here. I am working on implementing it into my site and was wondering if I am misunderstanding how to set up registration with email validation. The flow that I am used to on the net is :

register with information - > submit

see splash screen that reminds the user to check their email to confirm

follow email link -> enable account (sometimes this is the step where the user sets a permanent password if none is entered on the sign up form)

redirect to profile page for more information on the user 

How would you recommend that I go about implementing this module in order to accomplish this? 

Share this post


Link to post
Share on other sites

Take a look at the FrontendUserRegisterEmailValidation submodule. It adds an email validation step before the new user will be registered.

Just load the plugin as additional field "emailValidation".

$fu->register(array('username', 'email', 'emailValidation', 'password'));
  • Like 1

Share this post


Link to post
Share on other sites

Apologies for not being more specific. I set the option for email validation and have noticed that the email contains a validation token. Is there any way to implement a flow that allows for a user to follow the link using the token instead of first having to enter the code that was emailed. I would like to just have the user follow the link to the password reset page where they would then enter their own password. Then on reset the user would be automatically logged in. 

Share this post


Link to post
Share on other sites

The Email should contain the token and a link to the second step of user registration form (filled with username, email address and token).

Password reset isn't handled by FrontendUser module, it just uses the ProcessForgotPassword core module.

Your use case is possible and the needed snippets and examples should be here in the forum, but you need to extend FrontendUser to work as you want it. I implemented ProcessForgotPassword because it should be secure and do the password reset job.

  • Like 1

Share this post


Link to post
Share on other sites

Sorry, I wasn't intending to sound critical  :). I just didn't want to start modifying anything before I fully understood the intended behaviour of the module. I now have it implemented and the css is now in place. I have one issue though. When registering you first input your username and your email. When you click to send the code the form posts back as it should, but then the error gets tripped before the whole form has been submitted "Email validation code NOT match!". I think I could locate a fix in the code but I was wondering if this is something that you were planning on dealing with in your own code before I go hacking at the module.

Share this post


Link to post
Share on other sites

It was important to check token mismatch and changed / duplicate username or email address before a new user is saved.

I think you shouldn't use my plugin. Write a submodule which isn't based on FrontendUserRegisterEmailValidation.

Just register an unpublished user. Send an activation mail via hook after save(). User activation could be done as independent (sub-)module.

Share this post


Link to post
Share on other sites

FrontendUser is based on the PW form api and PW inputfields.

Haven't links here, but just search the forum.

https://processwire.com/talk/topic/9467-add-a-css-class-to-an-inputfield-on-render/

https://processwire.com/talk/topic/2089-create-simple-forms-using-api/

I hope that will help you to style your form.

If someone build a base / example style I'll add it to the module / documentation.

  • Like 2

Share this post


Link to post
Share on other sites

Get it to work only with css. Thank you for your links.

How can i change the placeholders inside the textfields? It says username, password and login.

How could i translate that?

Share this post


Link to post
Share on other sites

Get it to work only with css. Thank you for your links.

How can i change the placeholders inside the textfields? It says username, password and login.

How could i translate that?

In PW settings - languages - your lang - select file for translation and give the module file.

  • Like 1

Share this post


Link to post
Share on other sites

In PW settings - languages - your lang - select file for translation and give the module file.

This was new to me. Thank you very much! :frantics:

Share this post


Link to post
Share on other sites

I have some Redirect Issues on Logout in Firefox. When I press Logout in Chrome everything seems working. In FF ive got endless redirects. The way I lougout is:

$fu = $modules->get('FrontendUser');
$fu->logout();

Runs on an own page, means not on the same where the Login/Register is located (There is only a Link to the Logout Page to print a feedback message). Whats the fault? I dont use redirect because I dont need any. 

By the way: I find no elegant way to send an email, when some new user is registrated. Is there any way to send an email out of the box from this module? Every extern way means to send emails in a very general way without events fired directly from my registration form.

Share this post


Link to post
Share on other sites

Easiest way to deal with logging out is to just make a two line template at /logout/

<?php
     if($user->isLoggedin()) $session->logout();
     $session->redirect($pages->get('/')->url);
?>

Share this post


Link to post
Share on other sites

Easiest way to deal with logging out is to just make a two line template at /logout/

<?php
     if($user->isLoggedin()) $session->logout();
     $session->redirect($pages->get('/')->url);
?>

We take a look at the modules logout() method ;)

    public function ___logout ($redirect) {
        $this->session->logout();
        $this->session->redirect($redirect, false);
    }

So just do what you want in the template.

With the redirect above and the modules logout method it looks like that.

// logout the current user
$fu->logout($pages->get('/')->url);

If you use a combined login / logout page or a redirect to the current page you need if / else in the template like that.

if ($user->isGuest()) {
    // do login or just write a "You're logged out..." message 
}
else {
    // do logout
}

I could add a check to prevent a loop, but with a redirect to the current page you have to handle it with if / else to serve the correct page for guests / loggedin users...

Edited by pwFoo
  • Like 2

Share this post


Link to post
Share on other sites

Thank you a lot. I think it would be enough to mention this in your documentation. I was really confused about the endless loop redirects.

And is there any ability to send mails? Because I have the problem that any redirect is looses the data from posting the form. It would be helpful to send the admin an email that a new user is registered.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Robin S
      Another little admin helper module...
      Template Field Widths
      Adds a "Field widths" field to Edit Template that allows you to quickly set the widths of inputfields in the template.

      Why?
      When setting up a new template or trying out different field layouts I find it a bit slow and tedious to have to open each field individually in a modal just to set the width. This module speeds up the process.
      Installation
      Install the Template Field Widths module.
      Config options
      You can set the default presentation of the "Field widths" field to collapsed or open. You can choose Name or Label as the primary identifier shown for the field. The unchosen alternative will become the title attribute shown on hover. You can choose to show the original field width next to the template context field width.  
      https://github.com/Toutouwai/TemplateFieldWidths
      https://modules.processwire.com/modules/template-field-widths/
    • By horst
      Croppable Image 3
      for PW 3.0.20+
      Module Version 1.1.16
      Sponsored by http://dreikon.de/, many thanks Timo & Niko!
      You can get it in the modules directory!
      Please refer to the readme on github for instructions.
       
      -------------------------------------------------------------------------
       
      Updating from prior versions:
       
      Updating from Croppable Image 3 with versions prior to 1.1.7, please do this as a one time step:
      In the PW Admin, go to side -> modules -> new, use "install via ClassName" and use CroppableImage3 for the Module Class Name. This will update your existing CroppableImage3 module sub directory, even if it is called a new install. After that, the module will be recogniced by the PW updater module, what makes it a lot easier on further updates.
      -------------------------------------------------------------------------
       
      For updating from the legacy Thumbnail / CropImage to CroppableImage3 read on here.
       
      -------------------------------------------------------------------------
       
    • By MoritzLost
      UPDATE: I have published a stable version of this module!
      Discussion thread:
      Github: https://github.com/MoritzLost/TextformatterPageTitleLinks
      ---
      Hello there,
      I'm working on a tiny textformatter module that searches the text for titles of other pages on your site and creates hyperlinks to them. I'm not sure if something like this exists already, but I haven't found anything in the module directory, so I wrote my own solution 🙂
      It's not properly tested yet and is still missing some functionality I would like to implement, so at the moment it should be considered in BETA. Features include limiting the pages that will get searched by template, and adding a custom CSS class to the generated hyperlinks. As I'm writing this I noticed that it will probably include unpublished and hidden pages at the moment, so yeah ... it's still in development alright 😅
      You can download the module from Github:
      https://github.com/MoritzLost/TextformatterPageTitleLinks
      There's some more information in the readme as well.
      Anyway, let me know what you think! I'm happy about any feedback, possible improvements or ideas on how to improve the module. Cheers.
    • By blad
      Hi guys!
      I just uploaded a module to explore files based on elFinder. By default it will show the "Files" folder.
      Screenshots:

      Video:
       
      To do:
       More options To fix:
       The function of rotating or scaling an image fails  Image editors V 1.01 (view issue)
      Fixed the bug working with the Multi-Language support ( translation of folders ). Fixed the name of elfinder.en  Github:
      https://github.com/LuisSantiago/ProcessElFinder/
      I hope you like it.
    • By BitPoet
      I'm really in love with FormBuilder, but the one thing missing to match all my end users' expectations were repeatable field groups. Think repeaters, in ProcessWire terms. Our primary application of PW is our corporate intranet, so "lines" of fields are quite common in the forms I build. We have all kinds of request forms where the information for a varying number of colleagues needs to be entered (from meal order to flight booking request) and where it is simply impractical to send a form for each, and I don't want to clutter my forms with multiple instances of fields that may only get used ten percent of the time.
      That's why I started to build FormBuilderMultiplier (link to GitHub).
      What it does:
      Adds an option to make a regular Fieldgroup repeatable Lets you limit the number of instances of a Fieldgroup on the form Adds an "Add row" button the form that adds another instance of the Fieldgroup's fields Adds a counter suffix at the end of every affected field's label Stores the entered values just like regular fields Makes the entered values available in preview and email notifications Supports most text based fields, textareas and selects (really, I haven't had enough time to test all the available choices yet) What it doesn't do (yet):
      Support saving to ProcessWire pages (i.e. real Repeaters) I haven't tested all the validation stuff, Date/Time inputs etc. yet, but since I'm utterly swamped with other stuff at work, I didn't want to wait until I have it polished. Any feedback is welcome. There might also be some issues with different output frameworks that I haven't encountered yet. The forms I work with mostly use UIKit.
      Status:
      Still alpha, so test well before using it in the field.
      Known issues:
      When rows are added, the form's iframe needs to be resized, which isn't completely clean yet.
      How it works:
      The Fieldgroup settings are added through regular hooks, as is the logic that adds the necessary field copies for processing the form and displaying previews.
      "Multiplied" field instances are suffixed with _NUM, where NUM is an incremental integer starting from 1. So if you have add two fields named "surname" and "givenname" to a fieldgroup and check the "multiply" checkbox, the form will initially have "surname_1" and "givenname_1" field (I'm still considering changing that to make the risk to shoot oneself into the foot by having a regular "surname_1" field somewhere else in the form less likely).
      When a "row" is added, the first row is cloned through JS and the counter in the fields' IDs, names and "for" attributes as well as the counter in the label are incremented before appending the copies to the Fieldset container in the form.
      To keep backend and frontend in sync, a hidden field named [name of the fieldset]__multiplier_rows is added to the form. Both the backend and the frontend script use this to store and retrieve the number of "rows".
      ToDo:
      Naturally, add the option to store the data in real repeaters when saving to pages. Do a lot of testing (and likely fixing). Make a few things (like the "Add row" button label etc.) configurable in field(set) context. Add a smooth API to retrieve the multiplied values as WireArrays. The mandatory moving screenshot: