Handling Account Changes
You may want to change the display name, email address and/or password in your Login Handler's database when the user changes those details locally. This is especially likely for Username/Password Handlers.
There are lots of possible combinations of login handlers. A community might be using your login handler in combination with many other different handlers, or they might be using only your login handler and even have disabled the standard login handler. The two Username/Password Handlers in Invision Community (MySQL database and LDAP) both provide settings to allow the administrator to control if this syncing should be done and so it is recommended that you do the same (you can copy the code for creating these settings).
You will implement several methods. Here is some sample code for the methods you need to implement, including the code for creating the settings:
/** * ACP Settings Form * * @param string $url URL to redirect user to after successful submission * @return array List of settings to save - settings will be stored to core_login_methods.login_settings DB field * @code return array( 'savekey' => new \IPS\Helpers\Form\[Type]( ... ), ... ); * @endcode */ public function acpForm() { $return = array(); $return[] = 'account_management_settings'; $return['sync_name_changes'] = new \IPS\Helpers\Form\Radio( 'login_sync_name_changes', isset( $this->settings['sync_name_changes'] ) ? $this->settings['sync_name_changes'] : 1, FALSE, array( 'options' => array( 1 => 'login_sync_changes_yes', 0 => 'login_sync_changes_no', ) ) ); if ( \IPS\Settings::i()->allow_email_changes == 'normal' ) { $return['sync_email_changes'] = new \IPS\Helpers\Form\Radio( 'login_sync_email_changes', isset( $this->settings['sync_email_changes'] ) ? $this->settings['sync_email_changes'] : 1, FALSE, array( 'options' => array( 1 => 'login_sync_changes_yes', 0 => 'login_sync_changes_no', ) ) ); } if ( \IPS\Settings::i()->allow_password_changes == 'normal' ) { $return['sync_password_changes'] = new \IPS\Helpers\Form\Radio( 'login_sync_password_changes', isset( $this->settings['sync_password_changes'] ) ? $this->settings['sync_password_changes'] : 1, FALSE, array( 'options' => array( 1 => 'login_sync_changes_yes', 0 => 'login_sync_password_changes_no', ) ) ); } return $return; } /** * Can this handler process a password change for a member? * * @return bool */ public function canChangePassword( \IPS\Member $member ) { if ( !isset( $this->settings['sync_password_changes'] ) or $this->settings['sync_password_changes'] ) { // NOTE: This looks up if there is a core_login_links record for the member (i.e. if they have signed in with // your login handler before). return $this->canProcess( $member ); } return FALSE; } /** * Change Email Address * * @param \IPS\Member $member The member * @param string $oldEmail Old Email Address * @param string $newEmail New Email Address * @return void * @throws \IPS\Db\Exception */ public function changeEmail( \IPS\Member $member, $oldEmail, $newEmail ) { if ( !isset( $this->settings['sync_email_changes'] ) or $this->settings['sync_email_changes'] ) { // @todo - actually change the email in the Login Handler database } } /** * Change Password * * @param \IPS\Member $member The member * @param string $newPassword New Password * @return void * @throws \IPS\Db\Exception */ public function changePassword( \IPS\Member $member, $newPassword ) { if ( !isset( $this->settings['sync_password_changes'] ) or $this->settings['sync_password_changes'] ) { // @todo - actually change the password in the Login Handler database } } /** * Change Username * * @param \IPS\Member $member The member * @param string $oldUsername Old Username * @param string $newUsername New Username * @return void * @throws \IPS\Db\Exception */ public function changeUsername( \IPS\Member $member, $oldUsername, $newUsername ) { if ( !isset( $this->settings['sync_name_changes'] ) or $this->settings['sync_name_changes'] ) { // @todo - actually change the username in the Login Handler database } }
Checking if Email or Username Is In Use
You may want to prevent users using email addresses or usernames which exist in your Login Handler's database even before that user has created their local account. This is especially likely for Username/Password Handlers.
To do this you will implement several methods. Here is are the skeletons for the methods you need to implement. They should return a boolean value.
/** * Email is in use? * Used when registering or changing an email address to check the new one is available * * @param string $email Email Address * @param \IPS\Member|NULL $eclude Member to exclude * @return bool|NULL Boolean indicates if email is in use (TRUE means is in use and thus not registerable) or NULL if this handler does not support such an API */ public function emailIsInUse( $email, \IPS\Member $exclude=NULL ) { return NULL; } /** * Username is in use? * Used when registering or changing an username to check the new one is available * * @param string $username Username * @param \IPS\Member|NULL $eclude Member to exclude * @return bool|NULL Boolean indicates if username is in use (TRUE means is in use and thus not registerable) or NULL if this handler does not support such an API */ public function usernameIsInUse( $username, \IPS\Member $exclude=NULL ) { return NULL; }
Handling Forgotten Passwords
If a user uses the "Forgot Password" tool, you may want to redirect them to your site if they enter a email address which has been used, or could be used, by your Login Handler. This is especially likely for Username/Password Handlers.
First, you should implement the emailIsInUse() method described above first. Then you will need to implement this method, returning an \IPS\Http\Url object:
/** * Forgot Password URL * * @return \IPS\Http\Url|NULL */ public function forgotPasswordUrl() { return NULL; }
When viewing their Recently Used Devices, Invision Community will indicate what Login Method was used to assist the user in identifying if they performed the log in. You can optionally provide a logo to display alongside the Login Method name on this screen.
Simply implement the logoForDeviceInformation() method, returning an \IPS\Http\Url object:
/**
* Get logo to display in information about logins with this method
* Returns NULL for methods where it is not necessary to indicate the method, e..g Standard
*
* @return \IPS\Http\Url
*/
public function logoForDeviceInformation()
{
return NULL;
}
Report Document