pwFoo Posted October 18, 2014 Posted October 18, 2014 (edited) FrontendUserLogin Module to handle frontend user login / logout. Also should work with Persistent login for users (mode: automatically) out of the box Version 0.3.1Requires PW 2.5.5 (fields defined by array) Download Processwire module page: http://modules.processwire.com/modules/frontend-user-login/ Bitbucket Repo: https://bitbucket.org/pwFoo/frontenduserlogin/ Usage Readme file 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. FrontendUser module Edited May 3, 2015 by pwFoo 7
pwFoo Posted November 20, 2014 Author Posted November 20, 2014 Released version 0.1.0 minor changes updated compatibility to FormHelper 0.3.2 moved render() out of the login() method to make the form changeable via public FormHelper class variable $this->fh->... username sanitized by FormHelper (sanitizer set in username field array) I would like to make the module flexible and extendable, but at the moment no addons / plugins implemented...
pwFoo Posted January 2, 2015 Author Posted January 2, 2015 New branch with removed FormHelper dependency. Instead it uses the new form api array input support. Works in my local test environment. Simple frontend login module with error handling. After some time playing with JavaScript / ajax I should finish some basic modules *g*
pwFoo Posted February 8, 2015 Author Posted February 8, 2015 (edited) FrontendUserLogin 0.3 released (dev / unstable) Updated initial post. Tests and feedback welcome! FormHelper dependency is removed should work with Persistent login for users (mode: automatically) out of the box simple error handling (login failed, LoginThrottle, missing required value) Strings translatable by using $this->_() code optimized and some hookable methods removed (use PW Session methods instead!) Session::login Session::authenticate Session::logout Session::redirect hookable methods to modify form fields and form process / validation. Also to extend module with plugins / addons. FrontendUserLogin::processForm FrontendUserLogin::buildLoginForm ToDo Change password field type to password (at the moment isn't supported by PW?!) Remove (optional) field labels (seems not working after field is added to the form object?!) maybe a default style and optional add custom css / js code Change integration of Persistent login for users via plugin module (add Remember me checkbox and trigger PersistLogin manual mode) Forgot Password core module integration? Edited February 8, 2015 by pwFoo
pwFoo Posted February 12, 2015 Author Posted February 12, 2015 (edited) Login module should work, but the form is unstyled. A plugin is a module with attach / detach during install / uninstall to the parent module. Demo plugins (minimal tested!) are persistLogin module integration (manual mode, remember me checkbox) ProcessForgotPassword (core module) integration https://bitbucket.org/pwFoo/frontenduserlogin/src/be5b84b78d24060872d0ae96f2e7631f50028099/FrontendUserLogin/?at=master Edited February 12, 2015 by pwFoo
pwFoo Posted March 13, 2015 Author Posted March 13, 2015 I have a local testing version with field callbacks ("prepare" before added to form and "process" after form "basic" process) and preLogin / postLogin callbacks Possible usage: // Integrate LoginPersist module (manual mode) after sucessfully logged in $callback['postLogin'] = function ($fulObj) { if ($fulObj->attr('result')) { wire('modules')->get('LoginPersist')->persist(); } }; // optional login with email address instead of an username... (could also be done as username form field callback "process"! Just an example!!!) $callback['preLogin'] = function ($fulObj) { // callback defined outside the module class, so $this and private class attributes won't work! // module object hand over as function param. Get / set attributes with the attr() method. $email = $fulObj->attr('form')->get('username')->value; $userObj = wire('users')->get("email={$email}"); if ($userObj instanceof User) $fulObj->attr('user', $userObj->name); }; // login call with optional callback echo $ful->login("{$config->urls->root}login", $callback)->render(); Internal field process callback (sanitize input value) /** * Username form field * @return object Username field */ protected function fieldUsername() { $field = $this->modules->get('InputfieldText'); $field->label = $this->_('Username'); $field->attr('id+name', 'username'); $field->required = 1; // Set a "callbackProcess" to sanitize the input value or a "callbackPrepare" executed just before the field will be added to the form $field->fulOption = array( 'callbackProcess' => function ($field) { // 'callbackProcess' => function ($field, $obj) { // to get module object also outside the module class use an additional param // callback defined inside the module class and $this will work here. Also wire() could be used $this->user = wire('sanitizer')->username($field->value); }, 'callbackPrepare' => function ($field) { // Your code here... will be executed before field added to form } ); return $field; } What do you think about the change and usage of dynamic functions as callbacks?
pwFoo Posted April 4, 2015 Author Posted April 4, 2015 (edited) Latest update to my local testing branch... Moved totally from custom callbacks to PW hooks (core and module own hookable methods) Have a working minimal FrontendUserLogin and FrontendUserRegister module. Added FormHelper dependency again (instead of a extended wrapper FormHelper is changed to extend InputfieldForm object) FrontendUserLogin / FrontendUserRegister (simple use) // login echo $modules->get('FrontendUserLogin')->render($redirectAfterLogin); // register echo $modules->get('FrontendUserRegister')->render($redirectAfterRegister); The method render() is a shortcut. Long form with chance to modify parameters, form, ... $fu->form(); $fu->validate(); $fu->process($redirect); $fu->renderForm(); How to add plugins? After $fu->form() define the plugin field and needed processing validation code as a PW hook RememberMe plugin to integrate LoginPersist module // RememberMe field / persistLogin integration $remember = $modules->get('InputfieldCheckboxes'); $remember->name = 'persist'; $remember->attr('id+name', 'persist'); $remember->skipLabel = 4; $remember->addoption('persist', 'Remember me?'); $remember->addHookAfter('processInput', function($event) { $field = $event->object; if (isset($field->value[0]) && $field->value[0] === 'persist') { wire()->addHookAfter('Session::login', function($event) { wire('modules')->get('LoginPersist')->persist(); }); } }); $fu->attr('form')->add($remember); Or an integration of core module ProcessForgotPassword // ForgotPassword integration $forgot = $modules->get('InputfieldMarkup'); $forgot->value = "<a href='{$page->url}?forgot=1'>{$this->_('Forgot password?')}</a>"; $fu->attr('form')->add($forgot); if ($input->get->forgot) { function processForgot($event) { wire('config')->styles->add('/pw/wire/modules/AdminTheme/AdminThemeDefault/styles/main-classic.css'); $event->return = wire('modules')->get('ProcessForgotPassword')->execute(); $event->replace = true; } $fu->addHookBefore('FrontendUserLogin::login', null, 'processForgot'); } Login with email address instead of username? // Email login instead of username $fieldUser = $fu->attr('form')->get('username'); $fieldUser->addHookBefore('FrontendUserLogin::auth', function($event) { $fu = $event->object; $email = $fu->attr('form')->fhValue('username', 'email'); $loginUser = wire('users')->get("email={$email}"); if ($loginUser instanceof User && !$loginUser->isGuest()) { $event->arguments(0, $loginUser->name); } }); You have added a nickname field to user template? The plugin to use the nickname (sanitized text instead of username) to login // Nickname login instead of username $fieldUser = $fu->attr('form')->get('username'); $fieldUser->addHookBefore('FrontendUserLogin::auth', function($event) { $fu = $event->object; $nick = $fu->attr('form')->fhValue('username', 'text'); $loginUser = wire('users')->get("nickname={$nick}"); if ($loginUser instanceof User && !$loginUser->isGuest()) { $event->arguments(0, $loginUser->name); } }); The plugins are tested and working fine, but I don't know how to ship plugins. At the moment it's code inside the template login.php, but should be moved to a separate plugin file or the FrontendUserLogin module... Any suggestions? *Added nickname login plugin and fixed a nickname / email login bug* Edited April 12, 2015 by pwFoo 4
pwFoo Posted April 7, 2015 Author Posted April 7, 2015 Redesigned FormHelper 0.7.1 is available via PW module repo. You can download the FrontendUserLogin and FrontendUserRegister modules bundled as FrontendUser here (Repo). Both modules provide base features. Extendable with examples you see above.
pwFoo Posted April 10, 2015 Author Posted April 10, 2015 Here is a FrontendUserLogin screenshot with additional fields (PersistLogin, ProcessForgotPassword integration) and a basic style (removed list style), Form fields without label and placeholder instead. Default css / js can be added inside the module directory. Custom styles will be loaded from templates/FrontendUserLogin/FrontendUserLogin.<css|js>. FormHelper dependency could be replaced, but in version 0.7+ FormHelper isn't that big and no need to copy & paste form handling to each module with forms or file upload (FrontendUserLogin, FrontendUserRegister, contact form, ...). 1
pwFoo Posted April 12, 2015 Author Posted April 12, 2015 FrontendUserLogin module deletion requested, because it's an old and deprecated version. Last posts here reference to a redesigned and not compatible new module / branch.
adrian Posted April 12, 2015 Posted April 12, 2015 FrontendUserLogin 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.
pwFoo Posted April 20, 2015 Author Posted April 20, 2015 Updated testing branch of FrontendUser module (login / logout + register) https://bitbucket.org/pwFoo/frontenduser/src/1d97e2179784e60c7adad58e35152562291ec8ae/?at=testing
pwFoo Posted May 2, 2015 Author Posted May 2, 2015 FrontendUser module handles login, logout and user registration. 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 2
Webrocker Posted May 16, 2015 Posted May 16, 2015 hi pwFoo, i'm toying around with your great register module. I have a php fatal error and since i'm not-so in-depth to php/versions/objectoriented stuff, would you mind and confirm or not if this may be caused by me being forced to use PW in a php 5.3 environment?PW (2.58) in itself runs fine; but I noticed from the earlier notes in your module that it needed php >5.5 (?). Anyhow the error looks like $this (no pun intented): Fatal error: Using $this when not in object context in /var/www/<snipsnap>/site/modules/FrontendUser/FrontendUser.module on line 252 which refers to this line $username = $this->form->fhValue($field->name); in here: protected function usernameRegister() { $field = $this->modules->get('InputfieldText'); $field->label = $this->_('Username'); $field->attr('id+name', 'username'); $field->required = 1; $field->fhSanitizer = 'username'; $field->addHookAfter('processInput', function($event) { $field = $event->object; $username = $this->form->fhValue($field->name); if (empty($username)) return; elseif (wire('users')->count("name={$username}") == 0) { $this->userObj->name = $username; } else { $field->error(__('Username already taken!')); } }); return $field; } many thx for the module cheersTom
pwFoo Posted May 16, 2015 Author Posted May 16, 2015 Hello Tom, thank You for your feedback here! It's a anonymous function problem / missing feature. I have to add a PHP 5.4 dependency or find a workaround. I missed that because I tested it with a PHP 5.5.24. Version Description 5.4.0 $this can be used in anonymous functions. 5.3.0 Anonymous functions become available. See here: http://php.net/manual/en/functions.anonymous.php That could be a workaround... /** * Username form field * @return InputfieldText Username field */ protected function usernameRegister() { $field = $this->modules->get('InputfieldText'); $field->label = $this->_('Username'); $field->attr('id+name', 'username'); $field->required = 1; $field->fhSanitizer = 'username'; // workaround PHP 5.3 $fu = $this; //$field->addHookAfter('processInput', function($event) { $field->addHookAfter('processInput', function($event) use ($fu) { $field = $event->object; // workaround PHP 5.3 //$username = $this->form->fhValue($field->name); $username = $fu->attr('form')->fhValue($field->name); if (empty($username)) return; elseif (wire('users')->count("name={$username}") == 0) { // workaround PHP 5.3 //$this->userObj->name = $username; $fu->attr('userObj')->name = $username; } else { $field->error(__('Username already taken!')); } }); return $field; } I think some more changes like that have to be done to get it work with PHP 5.3 But I don't know if it make sense to make it PHP 5.3 compatible. But should be no problem if that's all... P.S.: Sorry for confusion of different topics *g* The correct support topic is: https://processwire.com/talk/topic/9811-frontenduser-login-logout-and-register-users-members/ 1
Recommended Posts