From 49c4b3579a5a1283a4e4fccf507a6fa7cea59020 Mon Sep 17 00:00:00 2001 From: Derrick Koo Date: Tue, 18 Feb 2025 11:09:46 -0700 Subject: [PATCH] feat: fixes and improvements for WooCommerce Subscriptions Gifting (#3747) * feat(wcsg): create new class for WCSG functionality * fix(wcsg): require shipping fields if gifted shippable product * chore: undo unnecessary change * fix(wcsg): new gift recipients are without password * test: fix failing unit test --- includes/class-newspack.php | 1 + ...lass-woocommerce-subscriptions-gifting.php | 79 +++++++++++++++++++ .../class-reader-activation.php | 9 ++- .../class-woocommerce-my-account.php | 27 +------ tests/unit-tests/reader-activation.php | 2 +- 5 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions-gifting.php diff --git a/includes/class-newspack.php b/includes/class-newspack.php index f67f142b3c..f88e57d862 100644 --- a/includes/class-newspack.php +++ b/includes/class-newspack.php @@ -176,6 +176,7 @@ private function includes() { include_once NEWSPACK_ABSPATH . 'includes/plugins/wc-memberships/class-memberships.php'; include_once NEWSPACK_ABSPATH . 'includes/plugins/class-woocommerce.php'; include_once NEWSPACK_ABSPATH . 'includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions.php'; + include_once NEWSPACK_ABSPATH . 'includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions-gifting.php'; include_once NEWSPACK_ABSPATH . 'includes/plugins/class-teams-for-memberships.php'; include_once NEWSPACK_ABSPATH . 'includes/plugins/class-newspack-elections.php'; diff --git a/includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions-gifting.php b/includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions-gifting.php new file mode 100644 index 0000000000..e01871a10c --- /dev/null +++ b/includes/plugins/woocommerce-subscriptions/class-woocommerce-subscriptions-gifting.php @@ -0,0 +1,79 @@ + $field_config ) { + if ( 'shipping_' !== substr( $field_name, 0, 9 ) && ! in_array( 'billing_' . $field_name, $required_fields, true ) ) { + unset( $fields[ $field_name ] ); + } + } + return $fields; + } + + /** + * Filters the default text shown for the gifting checkbox during checkout. + * + * @return string + */ + public static function default_gifting_checkbox_text() { + return __( 'This purchase is a gift', 'newspack' ); + } + + /** + * New gift recipients don't yet have a password. + * + * @param bool $is_reader_without_password True if the reader has not set a password. + * @param int $user_id The user ID. + * + * @return bool + */ + public static function is_reader_without_password( $is_reader_without_password, $user_id ) { + return 'true' === get_user_meta( $user_id, 'wcsg_update_account', true ); + } +} +WooCommerce_Subscriptions_Gifting::init(); diff --git a/includes/reader-activation/class-reader-activation.php b/includes/reader-activation/class-reader-activation.php index 3c0298b808..028c7dd7d1 100644 --- a/includes/reader-activation/class-reader-activation.php +++ b/includes/reader-activation/class-reader-activation.php @@ -1118,7 +1118,14 @@ public static function is_reader_without_password( $user_or_user_id ) { return new \WP_Error( 'newspack_is_reader_without_password', __( 'Invalid user.', 'newspack-plugin' ) ); } - return (bool) \get_user_meta( $user->ID, self::WITHOUT_PASSWORD, false ); + /** + * Filters whether the user should be considered a reader without a password. + * + * @param bool $is_reader_without_password True if the reader has not set a password. + * @param int $user_id User ID. + * @return bool + */ + return (bool) apply_filters( 'newpack_reader_activation_reader_is_without_password', \get_user_meta( $user->ID, self::WITHOUT_PASSWORD, false ), $user->ID ); } /** diff --git a/includes/reader-revenue/my-account/class-woocommerce-my-account.php b/includes/reader-revenue/my-account/class-woocommerce-my-account.php index 679c5ab758..9eb617cb31 100644 --- a/includes/reader-revenue/my-account/class-woocommerce-my-account.php +++ b/includes/reader-revenue/my-account/class-woocommerce-my-account.php @@ -29,8 +29,6 @@ class WooCommerce_My_Account { */ public static function init() { \add_filter( 'woocommerce_account_menu_items', [ __CLASS__, 'my_account_menu_items' ], 1000 ); - \add_filter( 'wcsg_new_recipient_account_details_fields', [ __CLASS__, 'new_recipient_fields' ] ); - \add_filter( 'wcsg_require_shipping_address_for_virtual_products', '__return_false' ); \add_filter( 'woocommerce_default_address_fields', [ __CLASS__, 'required_address_fields' ] ); \add_filter( 'woocommerce_billing_fields', [ __CLASS__, 'required_address_fields' ] ); \add_filter( 'woocommerce_get_checkout_url', [ __CLASS__, 'get_checkout_url' ] ); @@ -127,7 +125,7 @@ public static function my_account_menu_items( $items ) { unset( $shipping_address[ $ignored_field ] ); } - if ( empty( array_filter( $billing_address ) ) && empty( array_filter( $billing_address ) ) ) { + if ( empty( array_filter( $billing_address ) ) && empty( array_filter( $shipping_address ) ) ) { $default_disabled_items[] = 'edit-address'; } @@ -550,29 +548,6 @@ public static function required_address_fields( $fields ) { return $fields; } - /** - * Ensure that only billing address fields enabled in Reader Revenue settings - * are required for new gift recipient accounts. - * - * See: https://github.com/woocommerce/woocommerce-subscriptions-gifting/blob/trunk/includes/class-wcsg-recipient-details.php#L275 - * - * @param array $fields Address fields. - * @return array - */ - public static function new_recipient_fields( $fields ) { - // Escape hatch to force required shipping address for virtual products. - if ( apply_filters( 'wcsg_require_shipping_address_for_virtual_products', false ) ) { // phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound - return $fields; - } - $required_fields = Donations::get_billing_fields(); - foreach ( $fields as $field_name => $field_config ) { - if ( ! in_array( 'billing_' . $field_name, $required_fields, true ) ) { - unset( $fields[ $field_name ] ); - } - } - return $fields; - } - /** * WC's page templates hijacking. * diff --git a/tests/unit-tests/reader-activation.php b/tests/unit-tests/reader-activation.php index c7f30e7e63..b3813bda61 100644 --- a/tests/unit-tests/reader-activation.php +++ b/tests/unit-tests/reader-activation.php @@ -68,7 +68,7 @@ public function test_register_existing_reader() { $user_id = self::register_sample_reader(); wp_logout(); $result = self::register_sample_reader(); // Reregister the same email. - $this->assertFalse( $result ); + $this->assertTrue( is_wp_error( $result ) ); $this->assertFalse( is_user_logged_in() ); wp_delete_user( $user_id ); // Clean up. }