251 lines
7.5 KiB
PHP
251 lines
7.5 KiB
PHP
<?php
|
|
/**
|
|
* Class Duplicates_Detection_Service
|
|
*
|
|
* @package WooCommerce\Payments
|
|
*/
|
|
|
|
namespace WCPay;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
use WC_Payments;
|
|
use WCPay\Payment_Methods\Affirm_Payment_Method;
|
|
use WCPay\Payment_Methods\Afterpay_Payment_Method;
|
|
use WCPay\Payment_Methods\Bancontact_Payment_Method;
|
|
use WCPay\Payment_Methods\Becs_Payment_Method;
|
|
use WCPay\Payment_Methods\CC_Payment_Method;
|
|
use WCPay\Payment_Methods\Eps_Payment_Method;
|
|
use WCPay\Payment_Methods\Ideal_Payment_Method;
|
|
use WCPay\Payment_Methods\Klarna_Payment_Method;
|
|
use WCPay\Payment_Methods\P24_Payment_Method;
|
|
use WCPay\Payment_Methods\Sepa_Payment_Method;
|
|
use WCPay\Payment_Methods\Grabpay_Payment_Method;
|
|
use WCPay\PaymentMethods\Configs\Registry\PaymentMethodDefinitionRegistry;
|
|
|
|
/**
|
|
* Class handling detection of payment methods enabled by multiple plugins simultaneously.
|
|
*/
|
|
class Duplicates_Detection_Service {
|
|
|
|
/**
|
|
* Registered gateways.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $registered_gateways = null;
|
|
|
|
/**
|
|
* Gateways qualified by duplicates detector.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $gateways_qualified_by_duplicates_detector = [];
|
|
|
|
/**
|
|
* Find duplicates.
|
|
*
|
|
* @return array Duplicated gateways.
|
|
*/
|
|
public function find_duplicates() {
|
|
try {
|
|
$this->gateways_qualified_by_duplicates_detector = [];
|
|
|
|
$this->search_for_cc()
|
|
->search_for_additional_payment_methods()
|
|
->search_for_payment_request_buttons()
|
|
->keep_gateways_enabled_in_woopayments()
|
|
->keep_duplicates_only();
|
|
|
|
// Return payment method IDs list so that front-end can successfully compare with its own list.
|
|
return $this->gateways_qualified_by_duplicates_detector;
|
|
} catch ( \Exception $e ) {
|
|
Logger::warning( 'Duplicates detection service failed silently with the following error: ' . $e->getMessage() );
|
|
|
|
// Fail silently and return an empty array in case of any exception.
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search for credit card gateways.
|
|
*
|
|
* @return Duplicates_Detection_Service
|
|
*/
|
|
private function search_for_cc() {
|
|
$keywords = [ 'credit_card', 'creditcard', 'cc', 'card' ];
|
|
$special_keywords = [ 'woocommerce_payments', 'stripe' ];
|
|
|
|
foreach ( $this->get_enabled_gateways() as $gateway ) {
|
|
if ( $this->gateway_contains_keyword( $gateway->id, $keywords ) || in_array( $gateway->id, $special_keywords, true ) ) {
|
|
$this->gateways_qualified_by_duplicates_detector[ CC_Payment_Method::PAYMENT_METHOD_STRIPE_ID ][] = $gateway->id;
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Search for additional payment methods.
|
|
*
|
|
* @return Duplicates_Detection_Service
|
|
*/
|
|
private function search_for_additional_payment_methods() {
|
|
/**
|
|
* FLAG: PAYMENT_METHODS_LIST
|
|
* As payment methods are converted to use definitions, they need to be removed from the list below.
|
|
*/
|
|
$keywords = [
|
|
'bancontact' => Bancontact_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'sepa' => Sepa_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'p24' => P24_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'przelewy24' => P24_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'ideal' => Ideal_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'becs' => Becs_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'eps' => Eps_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'affirm' => Affirm_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'afterpay' => Afterpay_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'clearpay' => Afterpay_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'klarna' => Klarna_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
'grabpay' => Grabpay_Payment_Method::PAYMENT_METHOD_STRIPE_ID,
|
|
];
|
|
|
|
// Get all payment method definitions.
|
|
$payment_method_definitions = PaymentMethodDefinitionRegistry::instance()->get_all_payment_method_definitions();
|
|
|
|
// This gets all the registered payment method definitions. As new payment methods are converted from the legacy style, they need to be removed from the list above.
|
|
foreach ( $payment_method_definitions as $definition_class ) {
|
|
$definition_keywords = $definition_class::get_keywords();
|
|
foreach ( $definition_keywords as $keyword ) {
|
|
$keywords[ $keyword ] = $definition_class::get_id();
|
|
}
|
|
}
|
|
|
|
foreach ( $this->get_enabled_gateways() as $gateway ) {
|
|
foreach ( $keywords as $keyword => $payment_method ) {
|
|
if ( strpos( $gateway->id, $keyword ) !== false ) {
|
|
$this->gateways_qualified_by_duplicates_detector[ $payment_method ][] = $gateway->id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Search for payment request buttons.
|
|
*
|
|
* @return Duplicates_Detection_Service
|
|
*/
|
|
private function search_for_payment_request_buttons() {
|
|
$prb_payment_method = 'apple_pay_google_pay';
|
|
$keywords = [
|
|
'apple_pay',
|
|
'applepay',
|
|
'google_pay',
|
|
'googlepay',
|
|
];
|
|
|
|
foreach ( $this->get_registered_gateways() as $gateway ) {
|
|
if ( 'yes' === $gateway->enabled ) {
|
|
foreach ( $keywords as $keyword ) {
|
|
if ( strpos( $gateway->id, $keyword ) !== false ) {
|
|
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
|
|
break;
|
|
} elseif ( 'yes' === $gateway->get_option( 'payment_request' ) && in_array( $gateway->id, [ 'woocommerce_payments', 'stripe' ], true ) ) {
|
|
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
|
|
break;
|
|
} elseif ( 'yes' === $gateway->get_option( 'express_checkout_enabled' ) ) {
|
|
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Keep only WooCommerce Payments enabled gateways.
|
|
*
|
|
* @return Duplicates_Detection_Service
|
|
*/
|
|
private function keep_gateways_enabled_in_woopayments() {
|
|
$woopayments_gateway_ids = array_map(
|
|
function ( $gateway ) {
|
|
return $gateway->id; },
|
|
array_values( WC_Payments::get_payment_gateway_map() )
|
|
);
|
|
|
|
foreach ( $this->gateways_qualified_by_duplicates_detector as $gateway_id => $gateway_ids ) {
|
|
if ( empty( array_intersect( $gateway_ids, $woopayments_gateway_ids ) ) ) {
|
|
unset( $this->gateways_qualified_by_duplicates_detector[ $gateway_id ] );
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Filter payment methods found to keep duplicates only.
|
|
*
|
|
* @return Duplicates_Detection_Service
|
|
*/
|
|
private function keep_duplicates_only() {
|
|
foreach ( $this->gateways_qualified_by_duplicates_detector as $gateway_id => $gateway_ids ) {
|
|
if ( count( $gateway_ids ) < 2 ) {
|
|
unset( $this->gateways_qualified_by_duplicates_detector[ $gateway_id ] );
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Filter enabled gateways only.
|
|
*
|
|
* @return array Enabled gateways only.
|
|
*/
|
|
private function get_enabled_gateways() {
|
|
return array_filter(
|
|
$this->get_registered_gateways(),
|
|
function ( $gateway ) {
|
|
return 'yes' === $gateway->enabled;
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if gateway ID contains any of the keywords.
|
|
*
|
|
* @param string $gateway_id Gateway ID.
|
|
* @param array $keywords Keywords to search for.
|
|
*
|
|
* @return bool True if gateway ID contains any of the keywords, false otherwise.
|
|
*/
|
|
private function gateway_contains_keyword( $gateway_id, $keywords ) {
|
|
foreach ( $keywords as $keyword ) {
|
|
if ( strpos( $gateway_id, $keyword ) !== false ) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Lazy load registered gateways.
|
|
*
|
|
* @return array Registered gateways.
|
|
*/
|
|
private function get_registered_gateways() {
|
|
if ( null === $this->registered_gateways ) {
|
|
$this->registered_gateways = WC()->payment_gateways->payment_gateways();
|
|
}
|
|
return $this->registered_gateways;
|
|
}
|
|
}
|