Skip to content

Commit

Permalink
Merge pull request #68 from woocommerce/fix/66
Browse files Browse the repository at this point in the history
Fix/66: Fix the repetitive creation of 'wc_square_init_payment_token_migration' actions in the payment token migration process.
  • Loading branch information
vikrampm1 committed Feb 27, 2024
2 parents e8298f3 + 17decea commit aac82da
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ public function __construct( Payment_Gateway $gateway ) {

$this->environment_id = $gateway->get_environment();

add_action( 'wc_square_init_payment_token_migration', array( $this, 'register_payment_tokens_migration_scheduler' ) );
add_action( 'woocommerce_payment_token_deleted', array( $this, 'remove_token' ), 25, 2 );
add_action( 'wc_payment_gateway_' . $gateway->get_id() . '_payment_method_added', array( $this, 'clear_cache_for_new_token' ), 10, 2 );
add_action( 'action_scheduler_init', array( $this, 'schedule_token_migration_job' ) );
add_filter( 'woocommerce_get_customer_payment_tokens_limit', array( $this, 'increase_query_limit_for_payment_methods' ) );
}

Expand All @@ -75,21 +73,6 @@ public function clear_cache_for_new_token( $token_id, $user_id ) {
$this->clear_transient( $user_id );
}

/**
* Schedules the migration of payment tokens.
*
* @since 3.8.0
*/
public function schedule_token_migration_job() {
if ( false !== get_option( 'wc_square_payment_token_migration_complete' ) ) {
return;
}

if ( false === as_has_scheduled_action( 'wc_square_init_payment_token_migration' ) ) {
as_enqueue_async_action( 'wc_square_init_payment_token_migration', array( 'page' => 1 ) );
}
}

/**
* Sets the `limit` parameter to 30 to retrieve more payment methods by not relying
* on the `posts_per_page` setting.
Expand All @@ -104,59 +87,6 @@ public function increase_query_limit_for_payment_methods() {
return 30;
}

/**
* Migrates payment token from user_meta to WC_Payment_Token_CC.
*
* @param integer $page Pagination number.
* @since 3.8.0
*/
public function register_payment_tokens_migration_scheduler( $page ) {
// Get 5 users in a batch.
$users = get_users(
array(
'fields' => array( 'ID' ),
'number' => 5,
'paged' => $page,
)
);

// If users array is empty, then set status in options to indicate migration is complete.
if ( empty( $users ) ) {
$this->clear_all_transients();
update_option( 'wc_square_payment_token_migration_complete', true );
return;
}

// Re-run scheduler for the next page of users.
as_enqueue_async_action( 'wc_square_init_payment_token_migration', array( 'page' => $page + 1 ) );

foreach ( $users as $user ) {
$user_payment_tokens = get_user_meta( $user->id, $this->get_user_meta_name(), true );

if ( ! is_array( $user_payment_tokens ) || empty( $user_payment_tokens ) ) {
continue;
}

foreach ( $user_payment_tokens as $token => $user_payment_token_data ) {
$payment_token = new Square_Credit_Card_Payment_Token();
$payment_token->set_token( $token );
$payment_token->set_card_type( $user_payment_token_data['card_type'] );
$payment_token->set_last4( $user_payment_token_data['last_four'] );
$payment_token->set_expiry_month( $user_payment_token_data['exp_month'] );
$payment_token->set_expiry_year( $user_payment_token_data['exp_year'] );
$payment_token->set_user_id( $user->id );
$payment_token->set_gateway_id( wc_square()->get_gateway()->get_id() );

if ( isset( $user_payment_token_data['nickname'] ) ) {
$payment_token->set_nickname( $user_payment_token_data['nickname'] );
}

$payment_token->save();
}
}
}


/**
* A factory method to build and return a payment token object for the
* gateway. Concrete classes can override this method to return a custom
Expand Down
9 changes: 9 additions & 0 deletions includes/Gateway/Cash_App_Pay_Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,15 @@ protected function get_method_form_fields() {
return array();
}

/**
* Initialize payment tokens handler.
*
* @since x.x.x
*/
protected function init_payment_tokens_handler() {
// No payment tokens for Cash App Pay, do nothing.
}


/**
* Gets a user's stored customer ID.
Expand Down
89 changes: 89 additions & 0 deletions includes/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
defined( 'ABSPATH' ) || exit;

use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Plugin;
use WooCommerce\Square\Framework\PaymentGateway\PaymentTokens\Square_Credit_Card_Payment_Token;
use WooCommerce\Square\Framework\Square_Helper;
use WooCommerce\Square\Gateway\Cash_App_Pay_Gateway;
use WooCommerce\Square\Handlers\Background_Job;
Expand Down Expand Up @@ -130,6 +131,10 @@ public function __construct() {
add_action( 'admin_notices', array( $this, 'add_admin_notices' ) );
add_filter( 'woocommerce_locate_template', array( $this, 'locate_template' ), 20, 3 );
add_filter( 'woocommerce_locate_core_template', array( $this, 'locate_template' ), 20, 3 );

add_action( 'action_scheduler_init', array( $this, 'schedule_token_migration_job' ) );
add_action( 'wc_square_init_payment_token_migration_v2', array( $this, 'register_payment_tokens_migration_scheduler' ) );
add_action( 'wc_square_init_payment_token_migration', '__return_false' );
}


Expand Down Expand Up @@ -914,5 +919,89 @@ public static function instance() {
return self::$instance;
}

/**
* Schedules the migration of payment tokens.
*
* @since 3.8.0
*/
public function schedule_token_migration_job() {
if ( false !== get_option( 'wc_square_payment_token_migration_complete' ) ) {
return;
}

// Remove all OLD scheduled actions to cleanup DB.
// TODO: Remove this in next release.
global $wpdb;
$wpdb->query( "DELETE FROM {$wpdb->prefix}actionscheduler_actions WHERE hook = 'wc_square_init_payment_token_migration'" );

if ( false === as_has_scheduled_action( 'wc_square_init_payment_token_migration_v2' ) ) {
as_enqueue_async_action( 'wc_square_init_payment_token_migration_v2', array( 'page' => 1 ) );
}
}

/**
* Migrates payment token from user_meta to WC_Payment_Token_CC.
*
* @param integer $page Pagination number.
* @since 3.8.0
*/
public function register_payment_tokens_migration_scheduler( $page ) {
$payment_tokens_handler = wc_square()->get_gateway()->get_payment_tokens_handler();
$meta_key = $payment_tokens_handler->get_user_meta_name();

// Get 5 users in a batch.
$users = get_users(
array(
'fields' => array( 'ID' ),
'number' => 5,
'paged' => $page,
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
array(
'key' => $meta_key,
'compare' => 'EXISTS',
),
),
)
);

// If users array is empty, then set status in options to indicate migration is complete.
if ( empty( $users ) ) {
$payment_tokens_handler->clear_all_transients();
update_option( 'wc_square_payment_token_migration_complete', true );
return;
}

// Re-run scheduler for the next page of users.
as_enqueue_async_action( 'wc_square_init_payment_token_migration_v2', array( 'page' => $page + 1 ) );

foreach ( $users as $user ) {
$user_payment_tokens = get_user_meta( $user->id, $meta_key, true );

if ( ! is_array( $user_payment_tokens ) || empty( $user_payment_tokens ) ) {
continue;
}

foreach ( $user_payment_tokens as $token => $user_payment_token_data ) {
// Check if token already exists in WC_Payment_Token_CC.
if ( $payment_tokens_handler->user_has_token( $user->id, $token ) ) {
continue;
}

$payment_token = new Square_Credit_Card_Payment_Token();
$payment_token->set_token( $token );
$payment_token->set_card_type( $user_payment_token_data['card_type'] );
$payment_token->set_last4( $user_payment_token_data['last_four'] );
$payment_token->set_expiry_month( $user_payment_token_data['exp_month'] );
$payment_token->set_expiry_year( $user_payment_token_data['exp_year'] );
$payment_token->set_user_id( $user->id );
$payment_token->set_gateway_id( wc_square()->get_gateway()->get_id() );

if ( isset( $user_payment_token_data['nickname'] ) ) {
$payment_token->set_nickname( $user_payment_token_data['nickname'] );
}

$payment_token->save();
}
}
}
}

0 comments on commit aac82da

Please sign in to comment.