Last active
May 17, 2016 12:12
-
-
Save r-a-y/e098c67f49a57f5d579c to your computer and use it in GitHub Desktop.
WordPress - Redirects login attempts from sub-sites to the main site to login. Supports mapped domains created by WPMU Domain Mapping.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Get login URL. | |
* | |
* If redirect URL is passed, this function attempts to see if the redirect | |
* is using a mapped domain. If so, we switch out the mapped domain with the | |
* original subdomain and force logins from the main site. | |
* | |
* @param string $redirect_to The redirect URL | |
* @return string | |
*/ | |
function hwdsb_get_login_url( $redirect_to = '' ) { | |
if ( function_exists( 'bp_is_root_blog' ) ) { | |
$is_root_blog = bp_is_root_blog(); | |
$root_blog_id = bp_get_root_blog_id(); | |
} else { | |
$is_root_blog = is_main_site(); | |
$root_blog_id = 1; | |
} | |
if ( $is_root_blog ) { | |
return ''; | |
} | |
$login_url = get_site_url( $root_blog_id, 'wp-login.php', 'login' ); | |
$domain = hwdsb_get_original_domain(); | |
if ( ! empty( $redirect_to ) ) { | |
// reconstruct redirect URL to replace mapped domain with subdomain URL | |
if ( hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
$redir = parse_url( $redirect_to ); | |
$path = "{$redir['scheme']}://{$domain}{$redir['path']}"; | |
$path = ! empty( $redir['query'] ) ? "{$path}?{$redir['query']}" : $path; | |
$path = ! empty( $redir['anchor'] ) ? "{$path}#{$redir['anchor']}" : $path; | |
$redirect_to = $path; | |
} | |
$login_url = add_query_arg( 'redirect_to', urlencode( set_url_scheme( $redirect_to ) ), $login_url ); | |
} else { | |
global $current_blog; | |
$login_url = add_query_arg( 'redirect_to', urlencode( set_url_scheme( "http://{$domain}/" ) ), $login_url ); | |
} | |
return $login_url; | |
} | |
/** | |
* Determine if the current blog is domain mapped. | |
* | |
* Requires the WPMU Domain Mapping or Mercator plugin. | |
* | |
* @return bool | |
*/ | |
function hwdsb_is_domain_mapping_enabled_for_current_blog() { | |
// not using mercator or WPMU domain mapping, so stop! | |
if ( ! function_exists( 'Mercator\\startup' ) && ! function_exists( 'get_original_url' ) ) { | |
return false; | |
} | |
// mercator | |
if ( function_exists( 'Mercator\\startup' ) ) { | |
// check if we're on a mapped domain | |
$mapping = $GLOBALS['mercator_current_mapping']; | |
if ( ! empty( $mapping ) ) { | |
return true; | |
} | |
return false; | |
// WPMU Domain Mapping | |
} else { | |
$orig_domain = hwdsb_get_original_domain(); | |
if ( $orig_domain !== $GLOBALS['current_blog']->domain ) { | |
return true; | |
} | |
return false; | |
} | |
} | |
/** | |
* Returns original domain for the current blog. | |
* | |
* @return string The domain without the URL scheme (eg. example.com) | |
*/ | |
function hwdsb_get_original_domain() { | |
// WPMU Domain Mapping | |
if ( function_exists( 'get_original_url' ) ) { | |
$orig_domain = get_original_url( 'siteurl' ); | |
$orig_domain = substr( $orig_domain, strpos( $orig_domain, '://' ) + 3 ); | |
return $orig_domain; | |
// Mercator and everything else | |
} else { | |
return $GLOBALS['current_blog']->domain; | |
} | |
} | |
/** | |
* Redirects login attempts from sub-sites to the main site to login. | |
*/ | |
add_action( 'login_init', function() { | |
if ( function_exists( 'bp_is_root_blog' ) ) { | |
$is_root_blog = bp_is_root_blog(); | |
$root_blog_id = bp_get_root_blog_id(); | |
} else { | |
$is_root_blog = is_main_site(); | |
$root_blog_id = 1; | |
} | |
if ( $is_root_blog ) { | |
return; | |
} | |
// Bail from post password submissions | |
if ( ! empty( $_GET['action'] && 'postpass' === $_GET['action'] ) ) { | |
return; | |
} | |
$logout = ! empty( $_GET['action'] ) && 'logout' === $_GET['action'] ? true : false; | |
$redirect_to = ! empty( $_GET['redirect_to'] ) ? $_GET['redirect_to'] : ''; | |
$login_url = hwdsb_get_login_url( $redirect_to ); | |
// bail out of logout attempts | |
if ( $logout || ! empty( $_GET['loggedout' ] ) ) { | |
return; | |
} | |
wp_redirect( $login_url ); | |
die(); | |
} ); | |
/** | |
* Filters the login URL only when on a mapped domain. | |
*/ | |
add_filter( 'login_url', function( $retval, $redirect_to ) { | |
if ( false === hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return $retval; | |
} | |
// we're on a mapped domain, do the replacement | |
return hwdsb_get_login_url( $redirect_to ); | |
}, 30, 2 ); | |
/** | |
* Redirect subdomain requests to their mapped domain equivalent. | |
* | |
* Requires WPMU Domain Mapping plugin. | |
*/ | |
add_action( 'template_redirect', function() { | |
global $wpdb; | |
if ( ! function_exists( 'get_original_url' ) || is_user_logged_in() ) { | |
return; | |
} | |
if ( hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return; | |
} | |
$domain = $wpdb->get_var( "SELECT domain FROM {$wpdb->dmtable} WHERE blog_id = '{$wpdb->blogid}' AND active = 1 LIMIT 1" ); | |
if ( empty( $domain ) ) { | |
return; | |
} | |
wp_redirect( esc_url_raw( set_url_scheme( 'http://' . $domain . $_SERVER['REQUEST_URI'] ) ) ); | |
die(); | |
}, 0 ); | |
/** | |
* Hack Domain Mapping to allow us to use Remote Login to visit frontend. | |
* | |
* Logging into a subdomain will redirect to the mapped domain. | |
*/ | |
add_filter( 'site_option_dm_remote_login', function( $retval ) { | |
if ( 0 != $retval || ! function_exists( 'get_original_url' ) ) { | |
return $retval; | |
} | |
if ( did_action( 'get_header' ) ) { | |
return $retval; | |
} | |
// this is to pass the check in remote_login_js() | |
if ( isset( $_GET['dm'] ) ) { | |
return 1; | |
} | |
return $retval; | |
} ); | |
/** | |
* Reimplement Domain Mapping's JS. | |
* | |
* Only works if Domain Mapping's Remote Login is disabled. | |
*/ | |
add_action( 'wp_head', function() { | |
global $current_site, $current_blog, $wpdb; | |
if ( ! function_exists( 'get_original_url' ) ) { | |
return; | |
} | |
if ( 0 != get_site_option( 'dm_remote_login' ) || ! is_user_logged_in() ) { | |
return; | |
} | |
if ( hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return; | |
} | |
$referer = wp_get_referer(); | |
// do not break customizer links from WP adminbar | |
if ( false !== strpos( $referer, '/wp-admin/customize.php' ) ) { | |
return; | |
} | |
$domain = $wpdb->get_var( "SELECT domain FROM {$wpdb->dmtable} WHERE blog_id = '{$wpdb->blogid}' AND active = 1 LIMIT 1" ); | |
if ( empty( $domain ) ) { | |
return; | |
} | |
$protocol = is_ssl() ? 'https://' : 'http://'; | |
$hash = get_dm_hash(); | |
echo "<script src='{$protocol}{$current_site->domain}{$current_site->path}?dm={$hash}&action=load&blogid={$current_blog->blog_id}&siteid={$current_blog->site_id}&t=" . mt_rand() . "&back=" . urlencode( esc_url_raw( $protocol . $domain . $_SERVER[ 'REQUEST_URI' ] ) ) . "' type='text/javascript'></script>"; | |
} ); | |
/** | |
* Change admin URLs on mapped domains to use the subdomain URL on the frontend. | |
* | |
* @param string $url URL to check. | |
* @return string | |
*/ | |
function hwdsb_set_admin_url_to_subdomain( $url ) { | |
// bail if we're on a subdomain | |
if ( false === hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return $url; | |
} | |
// bail if we're in the admin area | |
if ( is_admin() ) { | |
return $url; | |
} | |
$domain = hwdsb_get_original_domain(); | |
// darn customizer | |
if ( 'clean_url' === current_filter() ) { | |
$url = str_replace( '%3A%2F%2F' . $GLOBALS['current_blog']->domain, '%3A%2F%2F' . $domain, $url ); | |
// everything else | |
} else { | |
$url = str_replace( '://' . $GLOBALS['current_blog']->domain, '://' . $domain, $url ); | |
$url = set_url_scheme( $url, 'https' ); | |
} | |
return $url; | |
} | |
add_filter( 'admin_url', 'hwdsb_set_admin_url_to_subdomain', 9999999999999 ); | |
add_filter( 'clean_url', 'hwdsb_set_admin_url_to_subdomain', 9999999999999 ); | |
/** | |
* AJAX should always obey the current scheme when on the front end. | |
* | |
* When FORCE_SSL_ADMIN is set to true, the 'ajaxurl' will always use HTTPS. | |
* This causes issues when a user is on the frontend and attempting to use | |
* an AJAX post action since the frontend traditionally uses | |
* HTTP. This function switches calls to 'admin-ajax.php' to always respect | |
* the current URL scheme. | |
* | |
* @param string $url URL to check | |
* @return string | |
*/ | |
function hwdsb_set_admin_url_scheme( $url ) { | |
if ( hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return $url; | |
} | |
if ( is_admin() ) { | |
return $url; | |
} | |
if ( false === strpos( $url, 'admin-ajax.php' ) ) { | |
return $url; | |
} | |
return set_url_scheme( $url, is_ssl() ? 'https' : 'http' ); | |
} | |
add_filter( 'admin_url', 'hwdsb_set_admin_url_scheme', 99 ); | |
/** | |
* Remove WPMU Domain Mapping's default logout routine. | |
*/ | |
add_action( 'plugins_loaded', function() { | |
remove_action( 'wp_logout', 'remote_logout_loader', 9999 ); | |
} ); | |
/** | |
* Redirects logout attempts to the main site. | |
* | |
* Reimplements WPMU Domain Mapping's logout routine. | |
*/ | |
add_action( 'login_init', function() { | |
if ( false === hwdsb_is_domain_mapping_enabled_for_current_blog() ) { | |
return; | |
} | |
if ( ! function_exists( 'get_original_url' ) ) { | |
return; | |
} | |
$logout = ! empty( $_GET['action'] ) && 'logout' === $_GET['action'] ? true : false; | |
if ( false === $logout ) { | |
return; | |
} | |
// clear login cookies for current site | |
wp_clear_auth_cookie(); | |
// now clear login cookies for main site | |
// use WPMU Domain Mapping's code from remote_logout_loader() here | |
global $current_site, $current_blog, $wpdb; | |
$wpdb->dmtablelogins = $wpdb->base_prefix . 'domain_mapping_logins'; | |
$protocol = is_ssl() ? 'https://' : 'http://'; | |
$hash = get_dm_hash(); | |
$key = md5( time() ); | |
$wpdb->query( $wpdb->prepare( "INSERT INTO {$wpdb->dmtablelogins} ( `id`, `user_id`, `blog_id`, `t` ) VALUES( %s, 0, %d, NOW() )", $key, $current_blog->blog_id ) ); | |
$url = $protocol . $current_site->domain . $current_site->path . "?dm={$hash}&action=logout&blogid={$current_blog->blog_id}&k={$key}&t=" . mt_rand(); | |
// redirect to main site to logout | |
wp_redirect( $url ); | |
die(); | |
} ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment