Skip to content

Instantly share code, notes, and snippets.

@eteubert
Last active October 6, 2024 19:59
Show Gist options
  • Save eteubert/293e07a49f56f300ddbb to your computer and use it in GitHub Desktop.
Save eteubert/293e07a49f56f300ddbb to your computer and use it in GitHub Desktop.
Multisite: Passwort Reset on Local Blog
<?php
/**
* Plugin Name: Multisite: Passwort Reset on Local Blog
* Plugin URI: https://gist.github.com/eteubert/293e07a49f56f300ddbb
* Description: By default, WordPress Multisite uses the main blog for passwort resets. This plugin enables users to stay in their blog during the whole reset process.
* Version: 1.0.0
* Author: Eric Teubert
* Author URI: http://ericteubert.de
* License: MIT
*/
// fixes "Lost Password?" URLs on login page
add_filter("lostpassword_url", function ($url, $redirect) {
$args = array( 'action' => 'lostpassword' );
if ( !empty($redirect) )
$args['redirect_to'] = $redirect;
return add_query_arg( $args, site_url('wp-login.php') );
}, 10, 2);
// fixes other password reset related urls
add_filter( 'network_site_url', function($url, $path, $scheme) {
if (stripos($url, "action=lostpassword") !== false)
return site_url('wp-login.php?action=lostpassword', $scheme);
if (stripos($url, "action=resetpass") !== false)
return site_url('wp-login.php?action=resetpass', $scheme);
return $url;
}, 10, 3 );
// fixes URLs in email that goes out.
add_filter("retrieve_password_message", function ($message, $key) {
return str_replace(get_site_url(1), get_site_url(), $message);
}, 10, 2);
// fixes email title
add_filter("retrieve_password_title", function($title) {
return "[" . wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) . "] Password Reset";
});
@jdozierezell
Copy link

This is great. Solves so many hassles and works right out of the box. Thanks!

@Surbma
Copy link

Surbma commented Aug 24, 2015

Works great, as expected. I hope WordPress will fix it soon, so we won't need these fixes anymore!

Thank you @eteubert!

Copy link

ghost commented Sep 10, 2015

Can't believe wpmu doesn't support this already. Thanks a ton!

@LouisHoude
Copy link

Thanks a lot! Work out of the box.

@grosscorporation
Copy link

Here is a new error that I am getting:

Your password reset link appears to be invalid. Please request a new link below.

@dipaknuveda
Copy link

You saved my day buddy. Working just perfect. Thanks :)

@tylercollier
Copy link

Awesome!

It still shows the Network Title in the email subject, like this: "[My Network Title] Password Reset". Do you know how to change it so it uses my site's title, and not the network's?

@LyndiLeighWK
Copy link

Works great - thank you!!

@edlefebvre
Copy link

Hi, thanks for this!

For those who install WordPress in a separate folder (https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory), you should use:
return str_replace(network_site_url(), get_site_url().'/', $message);
instead of return str_replace(get_site_url(1), get_site_url(), $message); (line 37)

@csisson
Copy link

csisson commented Feb 22, 2017

WP is throwing a parse error after trying to activate the plugin: "syntax error, unexpected T_FUNCTION on line 13".

Using WP Multiuser 4.7.2.

UPDATE Mar 7, 2017 - Bug solved

Added this line to my htaccess file:

AddHandler application/x-httpd-php55 php

@jonpasquier
Copy link

Works like a charm, thanks!

WP multisite 4.8.1

@13pixlar
Copy link

13pixlar commented Sep 26, 2017

You should replace the hard coded site id on line 37 get_site_url(1) with get_network()->site_id to make:

return str_replace(get_site_url(get_network()->site_id), get_site_url(), $message);

in case the main site is not id 1

@cooperhoward
Copy link

This works great on the "lost password" link underneath the log in details, however, if they type in an incorrect password... the error box shows with the link saying... forgotten your password... click "lost your password" to change it. This link (that appears in the error box) is still taking them back to the main site and not the sub-site that was intended... any thoughts?

Copy link

ghost commented Jan 13, 2018

It works without this plugin but having redirect to main site, it means reset password function works fine without using this plugin but to solve url redirection to related subdomain I'd like to use this plugins so after activating the plugin, I'm getting the following error:
The email could not be sent.
Possible reason: your host may have disabled the mail() function.

PHP 7.0.25
Wordpress multi site version: 4.9.1-0
Server: Debian 9
Mail: SendGrid

Any idea how to fix this?

@blue928
Copy link

blue928 commented Jun 1, 2018

Hello. Great plugin, but I can confirm mehranhzh's issue. As of the current WP version 4.9.6, something seems to have changed in how Wordpress works that breaks its "drop in and go" functionality. Mail is correctly setup sending email with no problem until I activate this plugin. I get the same error:

The email could not be sent.
Possible reason: your host may have disabled the mail() function.

Does this error reference the PHP mail() function? wp_mail() function? Or is it talking about linux mail command?

Thanks!

@SmoothMC
Copy link

SmoothMC commented Mar 6, 2019

on my multisite installation this plugin doesn't work. I try it in different ways..per functions.php as a plugin and as mu-plugin. but no luck
please help thx

@tomchiverton
Copy link

Works great for me on WordPress 5.x Just added to sunrise.php in /wp-content/, with the mod from https://gist.github.com/eteubert/293e07a49f56f300ddbb#gistcomment-2213197 (see above)

@eric7186
Copy link

eric7186 commented Dec 31, 2019

I unzipped then copied folder into my wpmudev host account: pe1.wpmudev.host NOTE: I did rename the folder to:
/site/public_html/wp-content/mu-plugins/Password Reset on Local Blog
Unfortunately, it has no effect for me, on my prod site (hosted on wpmudev) or on my dev site (LocalByFlywheel on my PC). Could the problem just be the misspelled word "passwort" in the Plugin Name and Description?
https://proprietorengine.com/mds/wp-login.php

@davidperezgar
Copy link

Why don't you publish to the official repository?

@eteubert
Copy link
Author

eteubert commented May 8, 2020

@davidperezgar I unfortunately have no time to maintain yet another plugin

@davidperezgar
Copy link

Ok ;)

@adrianaaymerich
Copy link

Nice fix! 👍

@speller
Copy link

speller commented Aug 12, 2020

Thanks!

@halleg
Copy link

halleg commented Jan 8, 2021

Awesome snippets. It works well except 2 things: with Buddypress, they force another email and the link in it redirects to the main site. If I deactivate Buddypress (buddy boss), it works again. Second, there is a Site Name mention in the email shared to the user that is in my case always the main site. Except for thee 2 points, it works like a charm. Kudos!

@Mutusen
Copy link

Mutusen commented Apr 26, 2021

Great, it was just what I needed! A small suggestion for the last lines, for websites that are in other languages:

// fixes email title
add_filter("retrieve_password_title", function($title) {
	return sprintf( __( '[%s] Password Reset' ), wp_specialchars_decode(get_option('blogname'), ENT_QUOTES) );
});

@marlonsabala
Copy link

Is it just me or this has stopped working now?

@blueprin4
Copy link

blueprin4 commented Aug 10, 2022

If you want to change the email body message so it does not say the main site here is the code for that to replace the existing line 35:

// fixes URLs in email that goes out.

add_filter("retrieve_password_message", function ($message, $key, $user_login, $user_data) {
	$message = __( 'Someone has requested a password reset for the following account:' ) . "\r\n\r\n";
	$message .= get_option('blogname') . "\r\n\r\n";
	$message .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n\r\n";
	$message .= __( 'If this was a mistake, ignore this email and nothing will happen.' ) . "\r\n\r\n";
	$message .= __( 'To reset your password, visit the following address:' ) . "\r\n\r\n";
	$message .= network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' ) . '&wp_lang=' . $locale . "\r\n\r\n";

	if ( ! is_user_logged_in() ) {
		$requester_ip = $_SERVER['REMOTE_ADDR'];
		if ( $requester_ip ) {
			$message .= sprintf(
				/* translators: %s: IP address of password reset requester. */
				__( 'This password reset request originated from the IP address %s.' ),
				$requester_ip
			) . "\r\n";
		}
	}
  	return str_replace(get_site_url(1), get_site_url(), $message);
}, 10, 4);

@eteubert thanks so much for this plugin.

@Av10ex
Copy link

Av10ex commented Jan 7, 2023

This plugin really saved my day. However for me it only works with Wordpress Default Login. I am using Paid Memberships Pro and would like to use PmPro login page (in my case named /login). There must be an easy way to tweak the plugin so that wp-login.php is replaced by /login/ in the lostpassword email? That would solve my issue. Secondly - this plugin seems not to work if Maintenance plugin is active.

@ANOVATIS
Copy link

ANOVATIS commented Mar 1, 2024

@Av10ex - does it not work if you replace all the wp-login.php by login?

@KZeni
Copy link

KZeni commented Apr 15, 2024

@Av10ex Not sure if you're still wanting/needing this yet or not... but I think I found a resolution via my forked version of this code at https://gist.github.com/KZeni/7760876c01ebb681ad439a452dc64427.

In effect, I just bumped the priority of the filters from 10 to instead be 12 as it appears (and maybe this is only when the Paid Memberships Pro [PMP] site is also on WPEngine hosting as is it in my case [since PMP then does its own URL adjustments to append wpe-login=1 to the assorted URLs to help with WPE hosting compatibility; which it seems my forked version works without it while on WP Engine [without needing to detect WPE within this gist to then selectively include it... one could also just hard-code the addition of that argument into the gist's $args if one knows the site will be on WPEngine for the foreseeable future] then just honoring the current site URL being viewed in the multi-site/network]) that this needs to happen after any number of adjustments being made to these URLs with a stronger priority than 12 (preventing them from being overwritten by reducing the number of filter[s] that might be remaining & come after this in priority.) Now, maybe the priority of 12 doesn't work for you, but this one change did seem to do the trick for my setup.

I also renamed "passwort" to "password" in a few spots (including the file name), made the URL that's sent out grab what it sees as the current site rather than still sending it as get_site_url(1) per line 37 of this original gist (as it is now; I just commented out the old line and added the new one below it on my fork), pointed it to my forked Gist for the URLs, and ran Prettier on the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment