Last active
August 3, 2022 16:17
-
-
Save mircobabini/13c083d7a2b312848f97496126d2aff2 to your computer and use it in GitHub Desktop.
PMPro fallback: Try to fix the wp_insert_user failure that is about to happen because PayPal Express gateway lost the session for any reason
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 | |
/** | |
* Test: | |
* - Go to checkout page | |
* - Click on proceed (with PayPal Express) | |
* - Copy the paypal.com link and complete the checkout in anonymous mode (session is empty for sure) | |
* - Check the CREATED USER! :) | |
* | |
* Added a cookie fallback for session lost, when payment completed after a long time. | |
* Doesn't cover the case above though. | |
* | |
* Just with some notices in logs. | |
* @see https://github.com/strangerstudios/paid-memberships-pro/issues/1341 | |
* | |
* DISCUSSION ABOUT THIS: | |
* @see https://github.com/strangerstudios/paid-memberships-pro/issues/1338 | |
*/ | |
/* | |
add_action('init', function(){ | |
$new_user_array = [ | |
'user_login' => '', | |
'user_email' => '', | |
'user_pass' => '', | |
'first_name' => '', | |
'first_name' => '', | |
]; | |
$new_user_array = apply_filters( 'pmpro_checkout_new_user_array', $new_user_array ); | |
var_dump( $new_user_array ); | |
}); | |
*/ | |
/** | |
* Save paypalexpress session user data to cookie as well. | |
* Should last more than sessions, at least until the browser is closed. | |
*/ | |
add_action( 'pmpro_paypalexpress_session_vars', function(){ | |
global $current_user; | |
if( ! $current_user->ID ){ | |
// without expiration, the cookie will expire at the end of the session | |
// so when the browser closes. should last more than the session though | |
setcookie( "pmpro_signup_username", $_SESSION['pmpro_signup_username'] ); | |
setcookie( "pmpro_signup_password", $_SESSION['pmpro_signup_password'] ); | |
setcookie( "pmpro_signup_email", $_SESSION['pmpro_signup_email'] ); | |
/* to simulate issue with session */ | |
if( $simulate_issue_with_session = false ){ | |
$_SESSION['pmpro_signup_username'] = ''; | |
$_SESSION['pmpro_signup_password'] = ''; | |
$_SESSION['pmpro_signup_email'] = ''; | |
} | |
} | |
}, 10 ); | |
/** | |
* Try to fix the wp_insert_user failure that is about to happen | |
* because PayPal Express gateway lost the session for any reason | |
* @see https://github.com/strangerstudios/paid-memberships-pro/issues/1338 | |
*/ | |
add_filter( 'pmpro_checkout_new_user_array', function( $new_user_array ){ | |
global $current_user; | |
$send_debug_email = false; | |
$before_new_user_array = $new_user_array; | |
// if we are reviewing an order | |
if( isset( $_REQUEST['review'] ) ) { | |
$order_code = $_REQUEST['review']; | |
$order = new MemberOrder( $order_code ); | |
} | |
// check: if we are using paypalexpress for this order (not needed I think) | |
// because paypal express is the only one acting this way, isn't it? | |
// if( $order->gateway === 'paypalexpress' ) | |
// check: if we dont already have a user for this order AND the user is not logged in | |
if( $order->user_id == 0 && ! $current_user->ID ){ | |
/** | |
* FALLBACK IF USER_LOGIN IS MISSING | |
*/ | |
// if we will not be able to create user | |
if( empty( $new_user_array['user_login'] ) ){ | |
// debug = true | |
$send_debug_email = true; | |
// try to fetch fallback from cookies | |
if( isset( $_COOKIE['pmpro_signup_username'] ) ){ | |
$fallback_username = $_COOKIE['pmpro_signup_username']; | |
$fallback_password = $_COOKIE['pmpro_signup_password']; | |
$fallback_email = $_COOKIE['pmpro_signup_email']; | |
// now get rid of insecure cookies | |
unset( $_COOKIE['pmpro_signup_username'] ); setcookie( 'pmpro_signup_username', '', time() - 3600, '/' ); | |
unset( $_COOKIE['pmpro_signup_password'] ); setcookie( 'pmpro_signup_password', '', time() - 3600, '/' ); | |
unset( $_COOKIE['pmpro_signup_email'] ); setcookie( 'pmpro_signup_email', '', time() - 3600, '/' ); | |
}else{ | |
// generate a fallbacks | |
$fallback_username = wp_help__generate_unique_username( "$order->FirstName $order->LastName", 'pmpro' ); | |
$fallback_password = wp_generate_password(); | |
$fallback_email = "mirco+$fallback_username@sedweb.it"; | |
} | |
/** avoid other warning, @see https://github.com/strangerstudios/paid-memberships-pro/issues/1341 */ | |
$_SESSION['pmpro_signup_username'] = $fallback_username; | |
$_SESSION['pmpro_signup_password'] = $fallback_password; | |
$_SESSION['pmpro_signup_email'] = $fallback_email; | |
/** fix the new_user_array data */ | |
$new_user_array['user_login'] = $fallback_username; | |
$new_user_array['user_email'] = $fallback_email; | |
$new_user_array['user_pass'] = $fallback_password; | |
} | |
/** | |
* FALLBACK IF USER_LOGIN IS INVALID (incomplete) | |
*/ | |
// if the username is longer then 60 chars | |
if( $new_user_array['user_login'] > 60 ){ | |
// !! can be moved to PMPro checks BEFORE checkout | |
// hard force, user never get noticed... tricky. | |
$new_user_array['user_login'] = wp_help__generate_unique_username( substr( $new_user_array['user_login'], 0, 15 ) ); | |
} | |
// if the username is listed in illegals | |
$illegal_logins = (array) apply_filters( 'illegal_user_logins', array() ); | |
if( in_array( strtolower( $new_user_array['user_login'] ), array_map( 'strtolower', $illegal_logins ) ) ){ | |
// !! can be moved to PMPro checks BEFORE checkout | |
// hard force, user never get noticed... tricky. | |
$new_user_array['user_login'] = wp_help__generate_unique_username( ''); | |
} | |
// if the username already exists | |
if( username_exists( $new_user_array['user_login'] ) ){ | |
// !! can be moved to PMPro checks BEFORE checkout | |
// hard force, user never get noticed... tricky. | |
$new_user_array['user_login'] = wp_help__generate_unique_username( '' ); | |
} | |
/** | |
* Complete user profiles from order data | |
*/ | |
// if first_name not assigned automatically from order | |
if( empty( $new_user_array['first_name'] ) ){ | |
$new_user_array['first_name'] = $order->FirstName; | |
} | |
// if last_name not assigned automatically from order | |
if( empty( $new_user_array['last_name'] ) ){ | |
$new_user_array['last_name'] = $order->LastName; | |
} | |
} | |
// log | |
if( $send_debug_email && function_exists( 'debug__extended' ) ){ | |
debug__extended( [ | |
'where' => str_replace( ABSPATH, '', __FILE__ ) . ':' . __LINE__, | |
'user_array_1' => $before_new_user_array, | |
'user_array_2' => $new_user_array, | |
] ); | |
} | |
return $new_user_array; | |
}, 11 ); | |
/** | |
* Generate a unique username based on the string passed. | |
* If the string is empty, uses the fallback_usrename_base plus a suffix (-1, -2...) | |
* | |
* @param $string_name | |
* @param string $fallback_username_base | |
* @return string | |
*/ | |
function wp_help__generate_unique_username( $string_name, $fallback_username_base = 'pmpro-user' ){ | |
// any string to a valid username | |
$username_base = sanitize_user( $string_name, true ); | |
// only lower chars, numbers and hyphens | |
$username_base = sanitize_title( $username_base ); | |
// ensure it's still valid (may be empty) | |
if( ! validate_username( $username_base ) ){ | |
$username_base = $fallback_username_base; | |
} | |
// append a suffix until it's valid | |
$suffix = 1; | |
while( $suffix < 100000 ){ // dont like infinite loops, avoid using while( true ) | |
$username = "$username_base-$suffix"; | |
if( ! username_exists( $username ) ){ | |
return $username; | |
} | |
$suffix++; | |
} | |
// since I dont like infinite loops and used a limited loops above, | |
// it may be unable to generate a new unique username... amen. | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment