From 79831e0bbfd58c263fea0ff346b698ecf87f35c5 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:14:14 +0100 Subject: [PATCH 01/33] Email the site admin when a payment gateway is enabled --- .../abstracts/abstract-wc-payment-gateway.php | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index a264a8ddf2f..8dfd505cf49 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -562,3 +562,68 @@ abstract class WC_Payment_Gateway extends WC_Settings_API { ); } } + +/** + * Email the site admin when a payment gateway is enabled. + * + * @since 8.4.0 + */ +function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { + $gateway_option_keys = array(); + $wc_payment_gateways = WC_Payment_Gateways::instance()->payment_gateways(); + foreach ( $wc_payment_gateways as $gateway ) { + $gateway_option_keys[] = $gateway->get_option_key(); + } + if ( ! in_array( $option, $gateway_option_keys ) ) { + return; + } + // this is a change to a payment gateway's settings + if ( 'no' === $old_value[ 'enabled' ] && 'yes' === $value[ 'enabled' ] ) { + // the gateway was just enabled, let's send an email to the admin + $admin_email = get_option( 'admin_email' ); + /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ + $email_text = __( + 'Howdy ###USERNAME###, + +The payment gateway "###GATEWAY_TITLE###" was just enabled on this site: +###SITEURL### + +If this was intentional you can safely ignore and delete this email. + +If you did not enable this payment gateway, please log in to your site and consider disabling it here: +###GATEWAY_SETTINGS_URL### + +This email has been sent to ###EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL###' + ); + $user = get_user_by( 'email', $admin_email ); + $username = $user ? $user->user_login : $admin_email; + $email_text = str_replace( '###USERNAME###', $username, $email_text ); + $email_text = str_replace( '###GATEWAY_TITLE###', $value[ 'title' ], $email_text ); + $email_text = str_replace( '###GATEWAY_SETTINGS_URL###', self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ), $email_text ); + $email_text = str_replace( '###EMAIL###', $admin_email, $email_text ); + $email_text = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $email_text ); + $email_text = str_replace( '###SITEURL###', home_url(), $email_text ); + + if ( '' !== get_option( 'blogname' ) ) { + $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + } else { + $site_title = parse_url( home_url(), PHP_URL_HOST ); + } + + wp_mail( + $admin_email, + sprintf( + /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ + __( '[%1$s] Payment gateway %2$s enabled' ), + $site_title, + $value[ 'title' ] + ), + $email_text + ); + } +} +add_action( 'update_option', 'wc_notify_payment_gateway_enabled', 10, 3 ); From 81e7fce52a0c7bbd00e8134d36b8275af4bada20 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:18:51 +0100 Subject: [PATCH 02/33] appease the linter --- .../abstracts/abstract-wc-payment-gateway.php | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 8dfd505cf49..6a08064635c 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -565,21 +565,24 @@ abstract class WC_Payment_Gateway extends WC_Settings_API { /** * Email the site admin when a payment gateway is enabled. - * + * + * @param string $option Option name. + * @param array $old_value Old value. + * @param array $value New value. * @since 8.4.0 */ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { $gateway_option_keys = array(); $wc_payment_gateways = WC_Payment_Gateways::instance()->payment_gateways(); - foreach ( $wc_payment_gateways as $gateway ) { + foreach ( $wc_payment_gateways as $gateway ) { $gateway_option_keys[] = $gateway->get_option_key(); } - if ( ! in_array( $option, $gateway_option_keys ) ) { + if ( ! in_array( $option, $gateway_option_keys, true ) ) { return; } - // this is a change to a payment gateway's settings - if ( 'no' === $old_value[ 'enabled' ] && 'yes' === $value[ 'enabled' ] ) { - // the gateway was just enabled, let's send an email to the admin + // This is a change to a payment gateway's settings. + if ( 'no' === $old_value['enabled'] && 'yes' === $value['enabled'] ) { + // The gateway was just enabled, let's send an email to the admin. $admin_email = get_option( 'admin_email' ); /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ $email_text = __( @@ -597,12 +600,13 @@ This email has been sent to ###EMAIL### Regards, All at ###SITENAME### -###SITEURL###' +###SITEURL###', + 'woocommerce' ); $user = get_user_by( 'email', $admin_email ); $username = $user ? $user->user_login : $admin_email; $email_text = str_replace( '###USERNAME###', $username, $email_text ); - $email_text = str_replace( '###GATEWAY_TITLE###', $value[ 'title' ], $email_text ); + $email_text = str_replace( '###GATEWAY_TITLE###', $value['title'], $email_text ); $email_text = str_replace( '###GATEWAY_SETTINGS_URL###', self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ), $email_text ); $email_text = str_replace( '###EMAIL###', $admin_email, $email_text ); $email_text = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $email_text ); @@ -611,16 +615,16 @@ All at ###SITENAME### if ( '' !== get_option( 'blogname' ) ) { $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); } else { - $site_title = parse_url( home_url(), PHP_URL_HOST ); + $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); } - + wp_mail( $admin_email, sprintf( /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ - __( '[%1$s] Payment gateway %2$s enabled' ), + __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), $site_title, - $value[ 'title' ] + $value['title'] ), $email_text ); From 335289179444d413f3c78526f603ffb17fa81834 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:21:46 +0100 Subject: [PATCH 03/33] ensure the option values are arrays --- .../includes/abstracts/abstract-wc-payment-gateway.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 6a08064635c..ac6c81d27e6 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -580,6 +580,9 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { if ( ! in_array( $option, $gateway_option_keys, true ) ) { return; } + if ( empty( $old_value ) || empty( $value ) || ! is_array( $old_value ) || ! is_array( $value ) ) { + return; + } // This is a change to a payment gateway's settings. if ( 'no' === $old_value['enabled'] && 'yes' === $value['enabled'] ) { // The gateway was just enabled, let's send an email to the admin. From 7bda29426b2222dab5c033ec2940301d896cc57f Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:25:20 +0100 Subject: [PATCH 04/33] ensure the value key is set --- .../includes/abstracts/abstract-wc-payment-gateway.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index ac6c81d27e6..040a73d406a 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -583,6 +583,9 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { if ( empty( $old_value ) || empty( $value ) || ! is_array( $old_value ) || ! is_array( $value ) ) { return; } + if ( ! isset( $old_value['enabled'] ) || ! isset( $value['enabled'] ) ) { + return; + } // This is a change to a payment gateway's settings. if ( 'no' === $old_value['enabled'] && 'yes' === $value['enabled'] ) { // The gateway was just enabled, let's send an email to the admin. From e4c6d9a532330a6f01313fdedf101eac83d7a8c9 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:25:58 +0100 Subject: [PATCH 05/33] invert the conditional so we can remove the nesting and go for an early return instead --- .../abstracts/abstract-wc-payment-gateway.php | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 040a73d406a..836a9ff7f70 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -586,13 +586,15 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { if ( ! isset( $old_value['enabled'] ) || ! isset( $value['enabled'] ) ) { return; } + if ( 'no' !== $old_value['enabled'] || 'yes' !== $value['enabled'] ) { + return; + } // This is a change to a payment gateway's settings. - if ( 'no' === $old_value['enabled'] && 'yes' === $value['enabled'] ) { - // The gateway was just enabled, let's send an email to the admin. - $admin_email = get_option( 'admin_email' ); - /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ - $email_text = __( - 'Howdy ###USERNAME###, + // The gateway was just enabled, let's send an email to the admin. + $admin_email = get_option( 'admin_email' ); + /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ + $email_text = __( + 'Howdy ###USERNAME###, The payment gateway "###GATEWAY_TITLE###" was just enabled on this site: ###SITEURL### @@ -607,33 +609,32 @@ This email has been sent to ###EMAIL### Regards, All at ###SITENAME### ###SITEURL###', - 'woocommerce' - ); - $user = get_user_by( 'email', $admin_email ); - $username = $user ? $user->user_login : $admin_email; - $email_text = str_replace( '###USERNAME###', $username, $email_text ); - $email_text = str_replace( '###GATEWAY_TITLE###', $value['title'], $email_text ); - $email_text = str_replace( '###GATEWAY_SETTINGS_URL###', self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ), $email_text ); - $email_text = str_replace( '###EMAIL###', $admin_email, $email_text ); - $email_text = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $email_text ); - $email_text = str_replace( '###SITEURL###', home_url(), $email_text ); + 'woocommerce' + ); + $user = get_user_by( 'email', $admin_email ); + $username = $user ? $user->user_login : $admin_email; + $email_text = str_replace( '###USERNAME###', $username, $email_text ); + $email_text = str_replace( '###GATEWAY_TITLE###', $value['title'], $email_text ); + $email_text = str_replace( '###GATEWAY_SETTINGS_URL###', self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ), $email_text ); + $email_text = str_replace( '###EMAIL###', $admin_email, $email_text ); + $email_text = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $email_text ); + $email_text = str_replace( '###SITEURL###', home_url(), $email_text ); - if ( '' !== get_option( 'blogname' ) ) { - $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - } else { - $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); - } - - wp_mail( - $admin_email, - sprintf( - /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ - __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), - $site_title, - $value['title'] - ), - $email_text - ); + if ( '' !== get_option( 'blogname' ) ) { + $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + } else { + $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); } + + wp_mail( + $admin_email, + sprintf( + /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ + __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), + $site_title, + $value['title'] + ), + $email_text + ); } add_action( 'update_option', 'wc_notify_payment_gateway_enabled', 10, 3 ); From 82f1bddaa5e261c33569d5d759243746d098da1f Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 19:28:51 +0100 Subject: [PATCH 06/33] add changelog file --- plugins/woocommerce/changelog/add-notify-payment-changes | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/woocommerce/changelog/add-notify-payment-changes diff --git a/plugins/woocommerce/changelog/add-notify-payment-changes b/plugins/woocommerce/changelog/add-notify-payment-changes new file mode 100644 index 00000000000..8171fe65984 --- /dev/null +++ b/plugins/woocommerce/changelog/add-notify-payment-changes @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Email the site admin when a payment gateway is enabled. From 247bf534e3f740202c78cdcfd513b2f4cc1be949 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Wed, 22 Nov 2023 23:25:58 +0100 Subject: [PATCH 07/33] optimize the checks a bit --- .../abstracts/abstract-wc-payment-gateway.php | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 836a9ff7f70..1860799943b 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -572,14 +572,6 @@ abstract class WC_Payment_Gateway extends WC_Settings_API { * @since 8.4.0 */ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { - $gateway_option_keys = array(); - $wc_payment_gateways = WC_Payment_Gateways::instance()->payment_gateways(); - foreach ( $wc_payment_gateways as $gateway ) { - $gateway_option_keys[] = $gateway->get_option_key(); - } - if ( ! in_array( $option, $gateway_option_keys, true ) ) { - return; - } if ( empty( $old_value ) || empty( $value ) || ! is_array( $old_value ) || ! is_array( $value ) ) { return; } @@ -589,8 +581,19 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { if ( 'no' !== $old_value['enabled'] || 'yes' !== $value['enabled'] ) { return; } - // This is a change to a payment gateway's settings. - // The gateway was just enabled, let's send an email to the admin. + + $gateway_found = false; + foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { + if ( $option === $gateway->get_option_key() ) { + $gateway_found = true; + break; + } + } + if ( ! $gateway_found ) { + return; + } + + // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. $admin_email = get_option( 'admin_email' ); /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ $email_text = __( From 71ec30268a196811e48810469937ed6f92a7f5ef Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 12:32:22 +0100 Subject: [PATCH 08/33] use proper sprintf for placeholders --- .../abstracts/abstract-wc-payment-gateway.php | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 1860799943b..bcc0fde5ee7 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -595,33 +595,41 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. $admin_email = get_option( 'admin_email' ); - /* translators: Do not translate USERNAME, GATEWAY_TITLE, GATEWAY_SETTINGS_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ - $email_text = __( - 'Howdy ###USERNAME###, + $user = get_user_by( 'email', $admin_email ); + $username = $user ? $user->user_login : $admin_email; + $gateway_title = $value['title']; + $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + $site_url = home_url(); -The payment gateway "###GATEWAY_TITLE###" was just enabled on this site: -###SITEURL### + /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ + $email_text = sprintf( + __( + 'Howdy %1$s, + +The payment gateway "%2$s" was just enabled on this site: +%3$s If this was intentional you can safely ignore and delete this email. If you did not enable this payment gateway, please log in to your site and consider disabling it here: -###GATEWAY_SETTINGS_URL### +%4$s -This email has been sent to ###EMAIL### +This email has been sent to %5$s Regards, -All at ###SITENAME### -###SITEURL###', - 'woocommerce' +All at %6$s +%7$s', + 'woocommerce' + ), + $username, + $gateway_title, + $site_url, + $gateway_settings_url, + $admin_email, + $site_name, + $site_url ); - $user = get_user_by( 'email', $admin_email ); - $username = $user ? $user->user_login : $admin_email; - $email_text = str_replace( '###USERNAME###', $username, $email_text ); - $email_text = str_replace( '###GATEWAY_TITLE###', $value['title'], $email_text ); - $email_text = str_replace( '###GATEWAY_SETTINGS_URL###', self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ), $email_text ); - $email_text = str_replace( '###EMAIL###', $admin_email, $email_text ); - $email_text = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $email_text ); - $email_text = str_replace( '###SITEURL###', home_url(), $email_text ); if ( '' !== get_option( 'blogname' ) ) { $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); From 7faf9b9f3b56592e1a5b84d632f81becd5c81f4a Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 12:33:25 +0100 Subject: [PATCH 09/33] indent assignments correctly --- .../abstracts/abstract-wc-payment-gateway.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index bcc0fde5ee7..ee217e51873 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -594,13 +594,13 @@ function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { } // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. - $admin_email = get_option( 'admin_email' ); - $user = get_user_by( 'email', $admin_email ); - $username = $user ? $user->user_login : $admin_email; - $gateway_title = $value['title']; + $admin_email = get_option( 'admin_email' ); + $user = get_user_by( 'email', $admin_email ); + $username = $user ? $user->user_login : $admin_email; + $gateway_title = $value['title']; $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); - $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - $site_url = home_url(); + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + $site_url = home_url(); /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ $email_text = sprintf( From d1fc46e658dfbce0a10532a3704bcaebc0064984 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 14:18:57 +0100 Subject: [PATCH 10/33] cover both update_option and add_option --- .../abstracts/abstract-wc-payment-gateway.php | 93 ++++++++++++------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index ee217e51873..c3ae8b74ab8 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -563,41 +563,10 @@ abstract class WC_Payment_Gateway extends WC_Settings_API { } } -/** - * Email the site admin when a payment gateway is enabled. - * - * @param string $option Option name. - * @param array $old_value Old value. - * @param array $value New value. - * @since 8.4.0 - */ -function wc_notify_payment_gateway_enabled( $option, $old_value, $value ) { - if ( empty( $old_value ) || empty( $value ) || ! is_array( $old_value ) || ! is_array( $value ) ) { - return; - } - if ( ! isset( $old_value['enabled'] ) || ! isset( $value['enabled'] ) ) { - return; - } - if ( 'no' !== $old_value['enabled'] || 'yes' !== $value['enabled'] ) { - return; - } - - $gateway_found = false; - foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { - if ( $option === $gateway->get_option_key() ) { - $gateway_found = true; - break; - } - } - if ( ! $gateway_found ) { - return; - } - - // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. +function notify_admin_payment_gateway_enabled( $gateway_title ) { $admin_email = get_option( 'admin_email' ); $user = get_user_by( 'email', $admin_email ); $username = $user ? $user->user_login : $admin_email; - $gateway_title = $value['title']; $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); @@ -637,7 +606,7 @@ All at %6$s $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); } - wp_mail( + return wp_mail( $admin_email, sprintf( /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ @@ -648,4 +617,60 @@ All at %6$s $email_text ); } -add_action( 'update_option', 'wc_notify_payment_gateway_enabled', 10, 3 ); + +function option_is_gateway_settings( $option ) { + foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { + if ( $option === $gateway->get_option_key() ) { + return true; + } + } + return false; +} + +function gateway_settings_enabled( $value, $old_value = null ) { + if ( $old_value === null ) { + // There was no old value, so this is a new option. + if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' ) { + return true; + } + return false; + } + // There was an old value, so this is an update. + if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' ) { + return true; + } + return false; +} + +/** + * Email the site admin when a payment gateway is enabled. + * + * @param string $option Option name. + * @param array $old_value Old value. + * @param array $value New value. + * @since 8.4.0 + */ +function wc_notify_payment_gateway_enabled_update_option( $option, $old_value, $value ) { + if ( ! gateway_settings_enabled( $value, $old_value ) ) { + return; + } + if ( ! option_is_gateway_settings( $option ) ) { + return; + } + + // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. + notify_admin_payment_gateway_enabled( $value['title'] ); +} +function wc_notify_payment_gateway_enabled_add_option( $option, $value ) { + if ( ! gateway_settings_enabled( $value ) ) { + return; + } + if ( ! option_is_gateway_settings( $option ) ) { + return; + } + + // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. + notify_admin_payment_gateway_enabled( $value['title'] ); +} +add_action( 'add_option', 'wc_notify_payment_gateway_enabled_add_option', 10, 2 ); +add_action( 'update_option', 'wc_notify_payment_gateway_enabled_update_option', 10, 3 ); From a0304bedef7ea5e7b2973c6df0f6adba2939b7de Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 14:52:42 +0100 Subject: [PATCH 11/33] ensure gateway title is set --- .../includes/abstracts/abstract-wc-payment-gateway.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index c3ae8b74ab8..21b22569042 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -630,13 +630,13 @@ function option_is_gateway_settings( $option ) { function gateway_settings_enabled( $value, $old_value = null ) { if ( $old_value === null ) { // There was no old value, so this is a new option. - if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' ) { + if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' && isset( $value['title'] ) ) { return true; } return false; } // There was an old value, so this is an update. - if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' ) { + if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' && isset( $value['title'] ) ) { return true; } return false; From 7254e99ec849d7a4ddf8364ca10eb0b930ac8c71 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 15:06:23 +0100 Subject: [PATCH 12/33] move things into the WC_Payment_Gateways class --- .../abstracts/abstract-wc-payment-gateway.php | 112 ----------------- .../includes/class-wc-payment-gateways.php | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+), 112 deletions(-) diff --git a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php index 21b22569042..a264a8ddf2f 100644 --- a/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php +++ b/plugins/woocommerce/includes/abstracts/abstract-wc-payment-gateway.php @@ -562,115 +562,3 @@ abstract class WC_Payment_Gateway extends WC_Settings_API { ); } } - -function notify_admin_payment_gateway_enabled( $gateway_title ) { - $admin_email = get_option( 'admin_email' ); - $user = get_user_by( 'email', $admin_email ); - $username = $user ? $user->user_login : $admin_email; - $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); - $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - $site_url = home_url(); - - /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ - $email_text = sprintf( - __( - 'Howdy %1$s, - -The payment gateway "%2$s" was just enabled on this site: -%3$s - -If this was intentional you can safely ignore and delete this email. - -If you did not enable this payment gateway, please log in to your site and consider disabling it here: -%4$s - -This email has been sent to %5$s - -Regards, -All at %6$s -%7$s', - 'woocommerce' - ), - $username, - $gateway_title, - $site_url, - $gateway_settings_url, - $admin_email, - $site_name, - $site_url - ); - - if ( '' !== get_option( 'blogname' ) ) { - $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); - } else { - $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); - } - - return wp_mail( - $admin_email, - sprintf( - /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ - __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), - $site_title, - $value['title'] - ), - $email_text - ); -} - -function option_is_gateway_settings( $option ) { - foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { - if ( $option === $gateway->get_option_key() ) { - return true; - } - } - return false; -} - -function gateway_settings_enabled( $value, $old_value = null ) { - if ( $old_value === null ) { - // There was no old value, so this is a new option. - if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' && isset( $value['title'] ) ) { - return true; - } - return false; - } - // There was an old value, so this is an update. - if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' && isset( $value['title'] ) ) { - return true; - } - return false; -} - -/** - * Email the site admin when a payment gateway is enabled. - * - * @param string $option Option name. - * @param array $old_value Old value. - * @param array $value New value. - * @since 8.4.0 - */ -function wc_notify_payment_gateway_enabled_update_option( $option, $old_value, $value ) { - if ( ! gateway_settings_enabled( $value, $old_value ) ) { - return; - } - if ( ! option_is_gateway_settings( $option ) ) { - return; - } - - // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. - notify_admin_payment_gateway_enabled( $value['title'] ); -} -function wc_notify_payment_gateway_enabled_add_option( $option, $value ) { - if ( ! gateway_settings_enabled( $value ) ) { - return; - } - if ( ! option_is_gateway_settings( $option ) ) { - return; - } - - // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. - notify_admin_payment_gateway_enabled( $value['title'] ); -} -add_action( 'add_option', 'wc_notify_payment_gateway_enabled_add_option', 10, 2 ); -add_action( 'update_option', 'wc_notify_payment_gateway_enabled_update_option', 10, 3 ); diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 04520322ee0..0117c9c63c5 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -113,8 +113,123 @@ class WC_Payment_Gateways { } ksort( $this->payment_gateways ); + + // Listen for gateways being enabled so as to notify the admin. + add_action( 'add_option', [ $this, 'payment_gateway_settings_add_option' ], 10, 2 ); + add_action( 'update_option', [ $this, 'payment_gateway_settings_update_option' ], 10, 3 ); } + /** + * Email the site admin when a payment gateway is enabled. + * + * @param string $option Option name. + * @param array $old_value Old value. + * @param array $value New value. + * @since 8.4.0 + */ + public function payment_gateway_settings_update_option( $option, $old_value, $value ) { + if ( ! $this->gateway_settings_enabled( $value, $old_value ) ) { + return; + } + if ( ! $this->option_is_gateway_settings( $option ) ) { + return; + } + + // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. + $this->notify_admin_payment_gateway_enabled( $value['title'] ); + } + + public function payment_gateway_settings_add_option( $option, $value ) { + if ( ! $this->gateway_settings_enabled( $value ) ) { + return; + } + if ( ! $this->option_is_gateway_settings( $option ) ) { + return; + } + + // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. + $this->notify_admin_payment_gateway_enabled( $value['title'] ); + } + + private function notify_admin_payment_gateway_enabled( $gateway_title ) { + $admin_email = get_option( 'admin_email' ); + $user = get_user_by( 'email', $admin_email ); + $username = $user ? $user->user_login : $admin_email; + $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + $site_url = home_url(); + + /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ + $email_text = sprintf( + __( + 'Howdy %1$s, + +The payment gateway "%2$s" was just enabled on this site: +%3$s + +If this was intentional you can safely ignore and delete this email. + +If you did not enable this payment gateway, please log in to your site and consider disabling it here: +%4$s + +This email has been sent to %5$s + +Regards, +All at %6$s +%7$s', + 'woocommerce' + ), + $username, + $gateway_title, + $site_url, + $gateway_settings_url, + $admin_email, + $site_name, + $site_url + ); + + if ( '' !== get_option( 'blogname' ) ) { + $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + } else { + $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); + } + + return wp_mail( + $admin_email, + sprintf( + /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ + __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), + $site_title, + $value['title'] + ), + $email_text + ); + } + + private function option_is_gateway_settings( $option ) { + foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { + if ( $option === $gateway->get_option_key() ) { + return true; + } + } + return false; + } + + private function gateway_settings_enabled( $value, $old_value = null ) { + if ( $old_value === null ) { + // There was no old value, so this is a new option. + if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' && isset( $value['title'] ) ) { + return true; + } + return false; + } + // There was an old value, so this is an update. + if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' && isset( $value['title'] ) ) { + return true; + } + return false; + } + /** * Get gateways. * From 6b12ffb5f5fea96da0296289ff97d5777e3d13ce Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 20:21:10 +0100 Subject: [PATCH 13/33] use AccessiblePrivateMethods, a single callback for both added and updated options, and subscribe to gateway-specific hooks --- .../includes/class-wc-payment-gateways.php | 53 ++++++++----------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 0117c9c63c5..ccd0b2eda59 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -8,6 +8,8 @@ * @package WooCommerce\Classes\Payment */ +use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods; + defined( 'ABSPATH' ) || exit; /** @@ -15,6 +17,8 @@ defined( 'ABSPATH' ) || exit; */ class WC_Payment_Gateways { + use AccessiblePrivateMethods; + /** * Payment gateway classes. * @@ -114,9 +118,17 @@ class WC_Payment_Gateways { ksort( $this->payment_gateways ); - // Listen for gateways being enabled so as to notify the admin. - add_action( 'add_option', [ $this, 'payment_gateway_settings_add_option' ], 10, 2 ); - add_action( 'update_option', [ $this, 'payment_gateway_settings_update_option' ], 10, 3 ); + // Hook in actions. + add_action( 'wc_payment_gateways_initialized', [ $this, 'on_payment_gateways_initialized' ], 10, 1 ); + do_action( 'wc_payment_gateways_initialized' ); + } + + public function on_payment_gateways_initialized() { + foreach ( $this->payment_gateways as $gateway ) { + $option_key = $gateway->get_option_key(); + self::add_action( 'add_option_' . $option_key, [ $this, 'payment_gateway_settings_option_changed' ], 10, 2 ); + self::add_action( 'update_option_' . $option_key, [ $this, 'payment_gateway_settings_option_changed' ], 10, 3 ); + } } /** @@ -127,23 +139,13 @@ class WC_Payment_Gateways { * @param array $value New value. * @since 8.4.0 */ - public function payment_gateway_settings_update_option( $option, $old_value, $value ) { - if ( ! $this->gateway_settings_enabled( $value, $old_value ) ) { - return; + private function payment_gateway_settings_option_changed( $old_value, $value, $option = null ) { + if ( null === $option ) { + // We're in the add_option_ hook so there's no old value and parameter order is different. + $option = $old_value; + $old_value = null; } - if ( ! $this->option_is_gateway_settings( $option ) ) { - return; - } - - // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. - $this->notify_admin_payment_gateway_enabled( $value['title'] ); - } - - public function payment_gateway_settings_add_option( $option, $value ) { - if ( ! $this->gateway_settings_enabled( $value ) ) { - return; - } - if ( ! $this->option_is_gateway_settings( $option ) ) { + if ( ! $this->was_gateway_enabled( $value, $old_value ) ) { return; } @@ -200,22 +202,13 @@ All at %6$s /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), $site_title, - $value['title'] + $gateway_title ), $email_text ); } - private function option_is_gateway_settings( $option ) { - foreach ( WC_Payment_Gateways::instance()->payment_gateways() as $gateway ) { - if ( $option === $gateway->get_option_key() ) { - return true; - } - } - return false; - } - - private function gateway_settings_enabled( $value, $old_value = null ) { + private function was_gateway_enabled( $value, $old_value = null ) { if ( $old_value === null ) { // There was no old value, so this is a new option. if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' && isset( $value['title'] ) ) { From 3cd4b5078c2e029b87ea6d44a1e0d9095560fa56 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 20:25:26 +0100 Subject: [PATCH 14/33] appease the linter --- .../includes/class-wc-payment-gateways.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index ccd0b2eda59..5acdf750f6e 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -119,15 +119,15 @@ class WC_Payment_Gateways { ksort( $this->payment_gateways ); // Hook in actions. - add_action( 'wc_payment_gateways_initialized', [ $this, 'on_payment_gateways_initialized' ], 10, 1 ); + add_action( 'wc_payment_gateways_initialized', array( $this, 'on_payment_gateways_initialized' ), 10, 1 ); do_action( 'wc_payment_gateways_initialized' ); } public function on_payment_gateways_initialized() { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); - self::add_action( 'add_option_' . $option_key, [ $this, 'payment_gateway_settings_option_changed' ], 10, 2 ); - self::add_action( 'update_option_' . $option_key, [ $this, 'payment_gateway_settings_option_changed' ], 10, 3 ); + self::add_action( 'add_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 2 ); + self::add_action( 'update_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 3 ); } } @@ -142,7 +142,7 @@ class WC_Payment_Gateways { private function payment_gateway_settings_option_changed( $old_value, $value, $option = null ) { if ( null === $option ) { // We're in the add_option_ hook so there's no old value and parameter order is different. - $option = $old_value; + $option = $old_value; $old_value = null; } if ( ! $this->was_gateway_enabled( $value, $old_value ) ) { @@ -160,9 +160,9 @@ class WC_Payment_Gateways { $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); - - /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ + $email_text = sprintf( + /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ __( 'Howdy %1$s, @@ -189,13 +189,13 @@ All at %6$s $site_name, $site_url ); - + if ( '' !== get_option( 'blogname' ) ) { $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); } else { $site_title = wp_parse_url( home_url(), PHP_URL_HOST ); } - + return wp_mail( $admin_email, sprintf( @@ -207,22 +207,22 @@ All at %6$s $email_text ); } - + private function was_gateway_enabled( $value, $old_value = null ) { - if ( $old_value === null ) { + if ( null === $old_value ) { // There was no old value, so this is a new option. - if ( ! empty( $value) && is_array( $value ) && isset( $value['enabled'] ) && $value['enabled'] === 'yes' && isset( $value['title'] ) ) { + if ( ! empty( $value ) && is_array( $value ) && isset( $value['enabled'] ) && 'yes' === $value['enabled'] && isset( $value['title'] ) ) { return true; } return false; } // There was an old value, so this is an update. - if ( ! empty( $value) && ! empty( $old_value) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && $value['enabled'] === 'yes' && $old_value['enabled'] !== 'yes' && isset( $value['title'] ) ) { + if ( ! empty( $value ) && ! empty( $old_value ) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && 'yes' === $value['enabled'] && 'yes' !== $old_value['enabled'] && isset( $value['title'] ) ) { return true; } return false; } - + /** * Get gateways. * From 20cd022334a52449a20ce92c7f813ec77d6718f5 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 20:32:10 +0100 Subject: [PATCH 15/33] document all the things --- .../includes/class-wc-payment-gateways.php | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 5acdf750f6e..dc67f9dfc22 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -118,11 +118,20 @@ class WC_Payment_Gateways { ksort( $this->payment_gateways ); - // Hook in actions. add_action( 'wc_payment_gateways_initialized', array( $this, 'on_payment_gateways_initialized' ), 10, 1 ); + /** + * Hook that is called when the payment gateways have been initialized. + * + * @since 8.5.0 + */ do_action( 'wc_payment_gateways_initialized' ); } + /** + * Hook into payment gateway settings changes. + * + * @since 8.5.0 + */ public function on_payment_gateways_initialized() { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); @@ -132,12 +141,12 @@ class WC_Payment_Gateways { } /** - * Email the site admin when a payment gateway is enabled. + * Callback for when a gateway settings option was added or updated. * + * @param mixed $old_value Old value. Option name when called via add_option_ hook. + * @param mixed $value New value. * @param string $option Option name. - * @param array $old_value Old value. - * @param array $value New value. - * @since 8.4.0 + * @since 8.5.0 */ private function payment_gateway_settings_option_changed( $old_value, $value, $option = null ) { if ( null === $option ) { @@ -153,6 +162,13 @@ class WC_Payment_Gateways { $this->notify_admin_payment_gateway_enabled( $value['title'] ); } + /** + * Email the site admin when a payment gateway has been enabled. + * + * @param string $gateway_title Gateway title. + * @return bool Whether the email was sent or not. + * @since 8.5.0 + */ private function notify_admin_payment_gateway_enabled( $gateway_title ) { $admin_email = get_option( 'admin_email' ); $user = get_user_by( 'email', $admin_email ); @@ -208,6 +224,13 @@ All at %6$s ); } + /** + * Determines from changes in settings if a gateway was enabled. + * + * @param array $value New value. + * @param array $old_value Old value. + * @return bool Whether the gateway was enabled or not. + */ private function was_gateway_enabled( $value, $old_value = null ) { if ( null === $old_value ) { // There was no old value, so this is a new option. From 26b664f29f8e3a0a2941f0f046a728fc3ee57503 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 20:42:23 +0100 Subject: [PATCH 16/33] add logging --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index dc67f9dfc22..efba40119d4 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -177,6 +177,9 @@ class WC_Payment_Gateways { $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); + $logger = wc_get_logger(); + $logger->info( sprintf( 'Payment gateway enabled: "%s"', $gateway_title ) ); + $email_text = sprintf( /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */ __( From e23839294fca0997a3d584d27fcd30524dc9dea7 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 22:27:12 +0100 Subject: [PATCH 17/33] guard against unset array key --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index efba40119d4..ca949e8aa12 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -159,7 +159,8 @@ class WC_Payment_Gateways { } // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. - $this->notify_admin_payment_gateway_enabled( $value['title'] ); + // "untitled" shouldn't happen, but just in case. + $this->notify_admin_payment_gateway_enabled( $value['title'] ?? 'untitled' ); } /** From 86fa398d5acf83c2e622059a6854211e904099f1 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 22:27:46 +0100 Subject: [PATCH 18/33] allow adding email addresses to the notification via a filter --- .../includes/class-wc-payment-gateways.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index ca949e8aa12..391604afee4 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -177,6 +177,17 @@ class WC_Payment_Gateways { $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); + /** + * Allows adding to the addresses that receive payment gateway enabled notifications. + * + * @param array $email_addresses Email addresses. + * @since 8.5.0 + */ + $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array() ); + $email_addresses = array_unique( array_filter( $email_addresses, function( $email_address ) { + return filter_var( $email_address, FILTER_VALIDATE_EMAIL ); + } ) ); + $email_addresses[] = $admin_email; $logger = wc_get_logger(); $logger->info( sprintf( 'Payment gateway enabled: "%s"', $gateway_title ) ); @@ -217,7 +228,7 @@ All at %6$s } return wp_mail( - $admin_email, + $email_addresses, sprintf( /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), From 665a6ce721e1b397a9e6fd943d65d39bc002d29c Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Thu, 23 Nov 2023 22:30:50 +0100 Subject: [PATCH 19/33] once more, appease the linter --- .../includes/class-wc-payment-gateways.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 391604afee4..413f1c2e660 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -183,10 +183,15 @@ class WC_Payment_Gateways { * @param array $email_addresses Email addresses. * @since 8.5.0 */ - $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array() ); - $email_addresses = array_unique( array_filter( $email_addresses, function( $email_address ) { - return filter_var( $email_address, FILTER_VALIDATE_EMAIL ); - } ) ); + $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array() ); + $email_addresses = array_unique( + array_filter( + $email_addresses, + function( $email_address ) { + return filter_var( $email_address, FILTER_VALIDATE_EMAIL ); + } + ) + ); $email_addresses[] = $admin_email; $logger = wc_get_logger(); From bbdbb026ea623e9d3cc89a633455f694517f067b Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:13:44 +0100 Subject: [PATCH 20/33] pass WC_Payment_Gateways instance to wc_payment_gateways_initialized hook --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 413f1c2e660..80b322998e5 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -123,8 +123,10 @@ class WC_Payment_Gateways { * Hook that is called when the payment gateways have been initialized. * * @since 8.5.0 + * + * @param WC_Payment_Gateways $wc_payment_gateways The payment gateways instance. */ - do_action( 'wc_payment_gateways_initialized' ); + do_action( 'wc_payment_gateways_initialized', $this ); } /** @@ -132,7 +134,7 @@ class WC_Payment_Gateways { * * @since 8.5.0 */ - public function on_payment_gateways_initialized() { + public function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); self::add_action( 'add_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 2 ); From e3c2c7938907b9722fd94a2bad20141cc11ac9ae Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:14:19 +0100 Subject: [PATCH 21/33] make on_payment_gateways_initialized private --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 80b322998e5..cd72bb12f7c 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -118,7 +118,7 @@ class WC_Payment_Gateways { ksort( $this->payment_gateways ); - add_action( 'wc_payment_gateways_initialized', array( $this, 'on_payment_gateways_initialized' ), 10, 1 ); + self::add_action( 'wc_payment_gateways_initialized', array( $this, 'on_payment_gateways_initialized' ) ); /** * Hook that is called when the payment gateways have been initialized. * @@ -134,7 +134,7 @@ class WC_Payment_Gateways { * * @since 8.5.0 */ - public function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) { + private function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); self::add_action( 'add_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 2 ); From ee04b60a83d5013a87b0f85e973481be4ee61bca Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:43:34 +0100 Subject: [PATCH 22/33] pass the whole gateway instance into notify_admin_payment_gateway_enabled --- .../includes/class-wc-payment-gateways.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index cd72bb12f7c..950635e6f4a 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -137,8 +137,12 @@ class WC_Payment_Gateways { private function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); - self::add_action( 'add_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 2 ); - self::add_action( 'update_option_' . $option_key, array( $this, 'payment_gateway_settings_option_changed' ), 10, 3 ); + self::add_action( 'add_option_' . $option_key, function( $option, $value ) use ( $gateway) { + $this->payment_gateway_settings_option_changed( $gateway, $value, $option ); + }, 10, 2 ); + self::add_action( 'update_option_' . $option_key, function( $old_value, $value, $option ) use ( $gateway) { + $this->payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value ); + }, 10, 3 ); } } @@ -150,19 +154,14 @@ class WC_Payment_Gateways { * @param string $option Option name. * @since 8.5.0 */ - private function payment_gateway_settings_option_changed( $old_value, $value, $option = null ) { - if ( null === $option ) { - // We're in the add_option_ hook so there's no old value and parameter order is different. - $option = $old_value; - $old_value = null; - } + private function payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value = null ) { if ( ! $this->was_gateway_enabled( $value, $old_value ) ) { return; } // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin. // "untitled" shouldn't happen, but just in case. - $this->notify_admin_payment_gateway_enabled( $value['title'] ?? 'untitled' ); + $this->notify_admin_payment_gateway_enabled( $gateway ); } /** @@ -172,11 +171,12 @@ class WC_Payment_Gateways { * @return bool Whether the email was sent or not. * @since 8.5.0 */ - private function notify_admin_payment_gateway_enabled( $gateway_title ) { + private function notify_admin_payment_gateway_enabled( $gateway ) { $admin_email = get_option( 'admin_email' ); $user = get_user_by( 'email', $admin_email ); $username = $user ? $user->user_login : $admin_email; $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); + $gateway_title = $gateway->get_title(); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); /** From d6f1adb4cf4b694387bd49af882db7842ededf91 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:44:56 +0100 Subject: [PATCH 23/33] pass the gateway instance into the wc_payment_gateway_enabled_notification_email_addresses hook --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 950635e6f4a..8f509c16ff3 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -182,10 +182,12 @@ class WC_Payment_Gateways { /** * Allows adding to the addresses that receive payment gateway enabled notifications. * - * @param array $email_addresses Email addresses. + * @param array $email_addresses The array of email addresses to notify. + * @param WC_Payment_Gateway $gateway The gateway that was enabled. + * @return array The augmented array of email addresses to notify. * @since 8.5.0 */ - $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array() ); + $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array(), $gateway ); $email_addresses = array_unique( array_filter( $email_addresses, From 488084d7ce6e866bb33d33d56c39c3a4b853e945 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:45:33 +0100 Subject: [PATCH 24/33] use the gateway ID to make gateway_settings_url a direct link to the enabled gateway's settings page --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 8f509c16ff3..a267d1f1b69 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -175,8 +175,8 @@ class WC_Payment_Gateways { $admin_email = get_option( 'admin_email' ); $user = get_user_by( 'email', $admin_email ); $username = $user ? $user->user_login : $admin_email; - $gateway_settings_url = self_admin_url( 'admin.php?page=wc-settings&tab=checkout' ); $gateway_title = $gateway->get_title(); + $gateway_settings_url = sanitize_url( self_admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id ) ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); /** From d638cc44a94748f0b5e816337f3b027be0588e18 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 11:45:43 +0100 Subject: [PATCH 25/33] tweak email subject --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index a267d1f1b69..a2c4ce133b9 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -240,7 +240,7 @@ All at %6$s $email_addresses, sprintf( /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */ - __( '[%1$s] Payment gateway %2$s enabled', 'woocommerce' ), + __( '[%1$s] Payment gateway "%2$s" enabled', 'woocommerce' ), $site_title, $gateway_title ), From 5a3ba9a0cb1e2de4850d2d0dd62f43d2ce762914 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 15:36:10 +0100 Subject: [PATCH 26/33] appease the linter --- .../includes/class-wc-payment-gateways.php | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index a2c4ce133b9..22acb50655f 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -122,9 +122,8 @@ class WC_Payment_Gateways { /** * Hook that is called when the payment gateways have been initialized. * - * @since 8.5.0 - * * @param WC_Payment_Gateways $wc_payment_gateways The payment gateways instance. + * @since 8.5.0 */ do_action( 'wc_payment_gateways_initialized', $this ); } @@ -132,26 +131,38 @@ class WC_Payment_Gateways { /** * Hook into payment gateway settings changes. * + * @param WC_Payment_Gateways $wc_payment_gateways The WC_Payment_Gateways instance. * @since 8.5.0 */ private function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) { foreach ( $this->payment_gateways as $gateway ) { $option_key = $gateway->get_option_key(); - self::add_action( 'add_option_' . $option_key, function( $option, $value ) use ( $gateway) { - $this->payment_gateway_settings_option_changed( $gateway, $value, $option ); - }, 10, 2 ); - self::add_action( 'update_option_' . $option_key, function( $old_value, $value, $option ) use ( $gateway) { - $this->payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value ); - }, 10, 3 ); + self::add_action( + 'add_option_' . $option_key, + function( $option, $value ) use ( $gateway ) { + $this->payment_gateway_settings_option_changed( $gateway, $value, $option ); + }, + 10, + 2 + ); + self::add_action( + 'update_option_' . $option_key, + function( $old_value, $value, $option ) use ( $gateway ) { + $this->payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value ); + }, + 10, + 3 + ); } } /** * Callback for when a gateway settings option was added or updated. * - * @param mixed $old_value Old value. Option name when called via add_option_ hook. - * @param mixed $value New value. - * @param string $option Option name. + * @param WC_Payment_Gateway $gateway The gateway for which the option was added or updated. + * @param mixed $value New value. + * @param string $option Option name. + * @param mixed $old_value Old value. `null` when called via add_option_ hook. * @since 8.5.0 */ private function payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value = null ) { @@ -167,7 +178,7 @@ class WC_Payment_Gateways { /** * Email the site admin when a payment gateway has been enabled. * - * @param string $gateway_title Gateway title. + * @param WC_Payment_Gateway $gateway The gateway that was enabled. * @return bool Whether the email was sent or not. * @since 8.5.0 */ @@ -176,7 +187,7 @@ class WC_Payment_Gateways { $user = get_user_by( 'email', $admin_email ); $username = $user ? $user->user_login : $admin_email; $gateway_title = $gateway->get_title(); - $gateway_settings_url = sanitize_url( self_admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id ) ); + $gateway_settings_url = esc_url_raw( self_admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id ) ); $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); $site_url = home_url(); /** From 3850a07a2c619491fdb1bd2d702120d2fd2b3cf8 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Fri, 24 Nov 2023 19:33:59 +0100 Subject: [PATCH 27/33] add a test that ensures the email and log message get generated --- .../includes/class-wc-payment-gateways.php | 3 +- .../payment-gateways/payment-gateways.php | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 22acb50655f..1880a6834ac 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -9,6 +9,7 @@ */ use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods; +use Automattic\WooCommerce\Proxies\LegacyProxy; defined( 'ABSPATH' ) || exit; @@ -209,7 +210,7 @@ class WC_Payment_Gateways { ); $email_addresses[] = $admin_email; - $logger = wc_get_logger(); + $logger = wc_get_container()->get( LegacyProxy::class )->call_function( 'wc_get_logger' ); $logger->info( sprintf( 'Payment gateway enabled: "%s"', $gateway_title ) ); $email_text = sprintf( diff --git a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php index 960b4aeb066..cbd44d2c01f 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php @@ -13,6 +13,8 @@ class WC_Tests_Payment_Gateway extends WC_Unit_Test_Case { */ public function setUp(): void { parent::setUp(); + $this->reset_legacy_proxy_mocks(); + WC()->session = null; $wc_payment_gateways = WC_Payment_Gateways::instance(); $wc_payment_gateways->init(); @@ -56,4 +58,63 @@ class WC_Tests_Payment_Gateway extends WC_Unit_Test_Case { $this->assertTrue( $current_gateway->chosen ); } + /** + * Test that enabling a gateway sends an email to the site admin and logs the event. + */ + public function test_wc_payment_gateway_enabled_notification() { + // Create a fake logger to capture log entries. + // phpcs:disable Squiz.Commenting + $fake_logger = new class() { + public $infos = array(); + + public function info( $message, $data = array() ) { + $this->infos[] = array( + 'message' => $message, + 'data' => $data, + ); + } + }; + // phpcs:enable Squiz.Commenting + $this->register_legacy_proxy_function_mocks( + array( + 'wc_get_logger' => function() use ( $fake_logger ) { + return $fake_logger; + }, + ) + ); + + // Register a watcher for wp_mail to capture email details. + $email_details = array(); + $watcher = function( $args ) use ( &$email_details ) { + $email_details = $args; + }; + add_filter( 'wp_mail', $watcher ); + + // Enable each gateway and check that the email and log entry are created. + foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) { + // Disable the gateway and save the settings. + $gateway->settings['enabled'] = 'no'; + update_option( $gateway->get_option_key(), $gateway->settings ); + + // Enable the gateway and save its settings; this should send the email and add a log entry. + $gateway->settings['enabled'] = 'yes'; + update_option( $gateway->get_option_key(), $gateway->settings ); + + // Check that the log entry was created. + $this->assertEquals( 'Payment gateway enabled: "' . $gateway->get_title() . '"', end( $fake_logger->infos )['message'] ); + + // Check that the email was sent correctly. + $this->assertStringContainsString( '@', $email_details['to'][0] ); + $this->assertEquals( get_option( 'admin_email' ), $email_details['to'][0] ); + $this->assertEquals( '[Test Blog] Payment gateway "' . $gateway->get_title() . '" enabled', $email_details['subject'] ); + $this->assertStringContainsString( 'The payment gateway "' . $gateway->get_title() . '" was just enabled on this site', $email_details['message'] ); + $this->assertStringContainsString( 'If you did not enable this payment gateway, please log in to your site and consider disabling it here:', $email_details['message'] ); + $this->assertStringContainsString( '/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id, $email_details['message'] ); + + // Reset the email details. + $email_details = array(); + } + remove_filter( 'wp_mail', $watcher ); + } + } From 21ad8d547fe2f9b150a8c6cda4891ccee6bfc878 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Sat, 25 Nov 2023 15:23:43 +0100 Subject: [PATCH 28/33] move the test to the proper file --- .../payment-gateways/payment-gateways.php | 60 --------------- .../class-wc-payment-gateways-test.php | 77 +++++++++++++++++++ 2 files changed, 77 insertions(+), 60 deletions(-) create mode 100644 plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php diff --git a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php index cbd44d2c01f..88b8a81695c 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/payment-gateways/payment-gateways.php @@ -57,64 +57,4 @@ class WC_Tests_Payment_Gateway extends WC_Unit_Test_Case { WC()->payment_gateways()->set_current_gateway( $gateways ); $this->assertTrue( $current_gateway->chosen ); } - - /** - * Test that enabling a gateway sends an email to the site admin and logs the event. - */ - public function test_wc_payment_gateway_enabled_notification() { - // Create a fake logger to capture log entries. - // phpcs:disable Squiz.Commenting - $fake_logger = new class() { - public $infos = array(); - - public function info( $message, $data = array() ) { - $this->infos[] = array( - 'message' => $message, - 'data' => $data, - ); - } - }; - // phpcs:enable Squiz.Commenting - $this->register_legacy_proxy_function_mocks( - array( - 'wc_get_logger' => function() use ( $fake_logger ) { - return $fake_logger; - }, - ) - ); - - // Register a watcher for wp_mail to capture email details. - $email_details = array(); - $watcher = function( $args ) use ( &$email_details ) { - $email_details = $args; - }; - add_filter( 'wp_mail', $watcher ); - - // Enable each gateway and check that the email and log entry are created. - foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) { - // Disable the gateway and save the settings. - $gateway->settings['enabled'] = 'no'; - update_option( $gateway->get_option_key(), $gateway->settings ); - - // Enable the gateway and save its settings; this should send the email and add a log entry. - $gateway->settings['enabled'] = 'yes'; - update_option( $gateway->get_option_key(), $gateway->settings ); - - // Check that the log entry was created. - $this->assertEquals( 'Payment gateway enabled: "' . $gateway->get_title() . '"', end( $fake_logger->infos )['message'] ); - - // Check that the email was sent correctly. - $this->assertStringContainsString( '@', $email_details['to'][0] ); - $this->assertEquals( get_option( 'admin_email' ), $email_details['to'][0] ); - $this->assertEquals( '[Test Blog] Payment gateway "' . $gateway->get_title() . '" enabled', $email_details['subject'] ); - $this->assertStringContainsString( 'The payment gateway "' . $gateway->get_title() . '" was just enabled on this site', $email_details['message'] ); - $this->assertStringContainsString( 'If you did not enable this payment gateway, please log in to your site and consider disabling it here:', $email_details['message'] ); - $this->assertStringContainsString( '/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id, $email_details['message'] ); - - // Reset the email details. - $email_details = array(); - } - remove_filter( 'wp_mail', $watcher ); - } - } diff --git a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php new file mode 100644 index 00000000000..3e19522ac0a --- /dev/null +++ b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php @@ -0,0 +1,77 @@ +reset_legacy_proxy_mocks(); + } + + /** + * Test that enabling a gateway sends an email to the site admin and logs the event. + */ + public function test_wc_payment_gateway_enabled_notification() { + // Create a fake logger to capture log entries. + // phpcs:disable Squiz.Commenting + $fake_logger = new class() { + public $infos = array(); + + public function info( $message, $data = array() ) { + $this->infos[] = array( + 'message' => $message, + 'data' => $data, + ); + } + }; + // phpcs:enable Squiz.Commenting + $this->register_legacy_proxy_function_mocks( + array( + 'wc_get_logger' => function() use ( $fake_logger ) { + return $fake_logger; + }, + ) + ); + + // Register a watcher for wp_mail to capture email details. + $email_details = array(); + $watcher = function( $args ) use ( &$email_details ) { + $email_details = $args; + }; + add_filter( 'wp_mail', $watcher ); + + // Enable each gateway and check that the email and log entry are created. + foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) { + // Disable the gateway and save the settings. + $gateway->settings['enabled'] = 'no'; + update_option( $gateway->get_option_key(), $gateway->settings ); + + // Enable the gateway and save its settings; this should send the email and add a log entry. + $gateway->settings['enabled'] = 'yes'; + update_option( $gateway->get_option_key(), $gateway->settings ); + + // Check that the log entry was created. + $this->assertEquals( 'Payment gateway enabled: "' . $gateway->get_title() . '"', end( $fake_logger->infos )['message'] ); + + // Check that the email was sent correctly. + $this->assertStringContainsString( '@', $email_details['to'][0] ); + $this->assertEquals( get_option( 'admin_email' ), $email_details['to'][0] ); + $this->assertEquals( '[Test Blog] Payment gateway "' . $gateway->get_title() . '" enabled', $email_details['subject'] ); + $this->assertStringContainsString( 'The payment gateway "' . $gateway->get_title() . '" was just enabled on this site', $email_details['message'] ); + $this->assertStringContainsString( 'If you did not enable this payment gateway, please log in to your site and consider disabling it here:', $email_details['message'] ); + $this->assertStringContainsString( '/wp-admin/admin.php?page=wc-settings&tab=checkout§ion=' . $gateway->id, $email_details['message'] ); + + // Reset the email details. + $email_details = array(); + } + remove_filter( 'wp_mail', $watcher ); + } +} From d64603764a17d5baec36e4e4c2a60cf44b081398 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Sat, 25 Nov 2023 17:16:16 +0100 Subject: [PATCH 29/33] extend test setup --- .../tests/php/includes/class-wc-payment-gateways-test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php index 3e19522ac0a..f4cb060fad0 100644 --- a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php +++ b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php @@ -14,6 +14,9 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { public function setUp(): void { parent::setUp(); $this->reset_legacy_proxy_mocks(); + $container = wc_get_container(); + $container->reset_all_resolved(); + WC_Payment_Gateways::instance()->init(); } /** From 5469dd3f01b2ea778925857b1d4a602f1312496f Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Sun, 26 Nov 2023 22:43:12 +0100 Subject: [PATCH 30/33] ensure the WC_Payment_Gateways instance we're testing is isolated from the other unit tests --- .../php/includes/class-wc-payment-gateways-test.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php index f4cb060fad0..db584be9914 100644 --- a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php +++ b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php @@ -8,6 +8,11 @@ */ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { + /** + * @var WC_Payment_Gateways The system under test. + */ + private $sut; + /** * Setup, enable payment gateways Cash on delivery and direct bank deposit. */ @@ -16,7 +21,8 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { $this->reset_legacy_proxy_mocks(); $container = wc_get_container(); $container->reset_all_resolved(); - WC_Payment_Gateways::instance()->init(); + $this->$sut = new WC_Payment_Gateways(); + $this->$sut->init(); } /** @@ -52,7 +58,7 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { add_filter( 'wp_mail', $watcher ); // Enable each gateway and check that the email and log entry are created. - foreach ( WC()->payment_gateways()->payment_gateways() as $gateway ) { + foreach ( $this->$sut->payment_gateways() as $gateway ) { // Disable the gateway and save the settings. $gateway->settings['enabled'] = 'no'; update_option( $gateway->get_option_key(), $gateway->settings ); From 5aa6f29b85c3cc4c76c7ee0a4c577a3428d5a0c5 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Sun, 26 Nov 2023 23:12:40 +0100 Subject: [PATCH 31/33] fix typo --- .../tests/php/includes/class-wc-payment-gateways-test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php index db584be9914..0cdceb610ca 100644 --- a/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php +++ b/plugins/woocommerce/tests/php/includes/class-wc-payment-gateways-test.php @@ -21,8 +21,8 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { $this->reset_legacy_proxy_mocks(); $container = wc_get_container(); $container->reset_all_resolved(); - $this->$sut = new WC_Payment_Gateways(); - $this->$sut->init(); + $this->sut = new WC_Payment_Gateways(); + $this->sut->init(); } /** @@ -58,7 +58,7 @@ class WC_Payment_Gateways_Test extends WC_Unit_Test_Case { add_filter( 'wp_mail', $watcher ); // Enable each gateway and check that the email and log entry are created. - foreach ( $this->$sut->payment_gateways() as $gateway ) { + foreach ( $this->sut->payment_gateways() as $gateway ) { // Disable the gateway and save the settings. $gateway->settings['enabled'] = 'no'; update_option( $gateway->get_option_key(), $gateway->settings ); From 7f839980ec1b5c4426e961879852727e1b22cef3 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Tue, 28 Nov 2023 13:02:49 +0100 Subject: [PATCH 32/33] add admin email address before removing duplicates --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index 1880a6834ac..cbb6bb11774 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -200,6 +200,7 @@ class WC_Payment_Gateways { * @since 8.5.0 */ $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array(), $gateway ); + $email_addresses[] = $admin_email; $email_addresses = array_unique( array_filter( $email_addresses, @@ -208,7 +209,6 @@ class WC_Payment_Gateways { } ) ); - $email_addresses[] = $admin_email; $logger = wc_get_container()->get( LegacyProxy::class )->call_function( 'wc_get_logger' ); $logger->info( sprintf( 'Payment gateway enabled: "%s"', $gateway_title ) ); From 2a12fea81dc0cab5cb1cfa8becca082bf4243036 Mon Sep 17 00:00:00 2001 From: Leif Singer Date: Tue, 28 Nov 2023 13:03:07 +0100 Subject: [PATCH 33/33] simplify conditional --- plugins/woocommerce/includes/class-wc-payment-gateways.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-payment-gateways.php b/plugins/woocommerce/includes/class-wc-payment-gateways.php index cbb6bb11774..8bfbfe244b9 100644 --- a/plugins/woocommerce/includes/class-wc-payment-gateways.php +++ b/plugins/woocommerce/includes/class-wc-payment-gateways.php @@ -10,6 +10,7 @@ use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods; use Automattic\WooCommerce\Proxies\LegacyProxy; +use Automattic\WooCommerce\Utilities\ArrayUtil; defined( 'ABSPATH' ) || exit; @@ -276,7 +277,10 @@ All at %6$s return false; } // There was an old value, so this is an update. - if ( ! empty( $value ) && ! empty( $old_value ) && is_array( $value ) && is_array( $old_value ) && isset( $value['enabled'] ) && isset( $old_value['enabled'] ) && 'yes' === $value['enabled'] && 'yes' !== $old_value['enabled'] && isset( $value['title'] ) ) { + if ( + ArrayUtil::get_value_or_default( $value, 'enabled' ) === 'yes' && + ArrayUtil::get_value_or_default( $old_value, 'enabled' ) !== 'yes' && + isset( $value['title'] ) ) { return true; } return false;