diff --git a/assets/wizards/readerRevenue/index.js b/assets/wizards/readerRevenue/index.js index 7e309167ac..4878664117 100644 --- a/assets/wizards/readerRevenue/index.js +++ b/assets/wizards/readerRevenue/index.js @@ -47,12 +47,6 @@ const ReaderRevenueWizard = () => { render: Views.Emails, isHidden: usedPlatform !== NEWSPACK, }, - { - label: __( 'Address', 'newspack' ), - path: '/location-setup', - render: Views.LocationSetup, - isHidden: usedPlatform !== NEWSPACK, - }, { label: __( 'Salesforce', 'newspack' ), path: '/salesforce', diff --git a/assets/wizards/readerRevenue/views/donation/index.tsx b/assets/wizards/readerRevenue/views/donation/index.tsx index 76b350536d..8b8f160f0c 100644 --- a/assets/wizards/readerRevenue/views/donation/index.tsx +++ b/assets/wizards/readerRevenue/views/donation/index.tsx @@ -1,3 +1,5 @@ +/* globals newspack_reader_revenue */ + /** * WordPress dependencies. */ @@ -103,6 +105,9 @@ export const DonationAmounts = () => { // Minimum donation is returned by the REST API as a string. const minimumDonationFloat = parseFloat( minimumDonation ); + // Whether we can use the Name Your Price extension. If not, layout is forced to Tiered. + const canUseNameYourPrice = newspack_reader_revenue?.can_use_name_your_price; + return ( <> @@ -114,17 +119,19 @@ export const DonationAmounts = () => { ) } noMargin /> - changeHandler( [ 'tiered' ] )( ! tiered ) } - buttonOptions={ [ - { value: true, label: __( 'Tiered', 'newspack' ) }, - { value: false, label: __( 'Untiered', 'newspack' ) }, - ] } - buttonSmall - value={ tiered } - hideLabelFromVision - /> + { canUseNameYourPrice && ( + changeHandler( [ 'tiered' ] )( ! tiered ) } + buttonOptions={ [ + { value: true, label: __( 'Tiered', 'newspack' ) }, + { value: false, label: __( 'Untiered', 'newspack' ) }, + ] } + buttonSmall + value={ tiered } + hideLabelFromVision + /> + ) } { tiered ? ( diff --git a/assets/wizards/readerRevenue/views/index.js b/assets/wizards/readerRevenue/views/index.js index a719cd80ba..12c176e9ec 100644 --- a/assets/wizards/readerRevenue/views/index.js +++ b/assets/wizards/readerRevenue/views/index.js @@ -1,5 +1,4 @@ export { default as Donation } from './donation'; -export { default as LocationSetup } from './location-setup'; export { default as NRHSettings } from './nrh-settings'; export { default as Platform } from './platform'; export { default as StripeSetup } from './stripe-setup'; diff --git a/assets/wizards/readerRevenue/views/location-setup/index.js b/assets/wizards/readerRevenue/views/location-setup/index.js deleted file mode 100644 index f24b402148..0000000000 --- a/assets/wizards/readerRevenue/views/location-setup/index.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * WordPress dependencies - */ -import { useDispatch } from '@wordpress/data'; -import { __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import { Button, Grid, SelectControl, TextControl, Wizard } from '../../../../components/src'; -import { READER_REVENUE_WIZARD_SLUG } from '../../constants'; - -const LocationSetup = () => { - const wizardData = Wizard.useWizardData( 'reader-revenue' ); - const { updateWizardSettings, saveWizardSettings } = useDispatch( Wizard.STORE_NAMESPACE ); - - const changeHandler = key => value => - updateWizardSettings( { - slug: READER_REVENUE_WIZARD_SLUG, - path: [ 'location_data', key ], - value, - } ); - - const onSave = () => - saveWizardSettings( { - slug: READER_REVENUE_WIZARD_SLUG, - section: 'location', - payloadPath: [ 'location_data' ], - } ); - - return ( - <> - - - - - - - - - - - - - - - { __( 'Save Settings' ) } - - - > - ); -}; - -export default LocationSetup; diff --git a/assets/wizards/readerRevenue/views/platform/index.js b/assets/wizards/readerRevenue/views/platform/index.js index 36fbb2552b..4f090092a3 100644 --- a/assets/wizards/readerRevenue/views/platform/index.js +++ b/assets/wizards/readerRevenue/views/platform/index.js @@ -51,12 +51,7 @@ const Platform = () => { { NEWSPACK === wizardData.platform_data?.platform && ! wizardData.plugin_status && ( { if ( complete ) { updateWizardSettings( { diff --git a/assets/wizards/readerRevenue/views/stripe-setup/index.js b/assets/wizards/readerRevenue/views/stripe-setup/index.js index 036d014bf6..df922b5d73 100644 --- a/assets/wizards/readerRevenue/views/stripe-setup/index.js +++ b/assets/wizards/readerRevenue/views/stripe-setup/index.js @@ -8,7 +8,15 @@ import { useDispatch } from '@wordpress/data'; /** * Internal dependencies */ -import { Button, Grid, Notice, Settings, TextControl, Wizard } from '../../../../components/src'; +import { + Button, + Grid, + Notice, + PluginInstaller, + Settings, + TextControl, + Wizard, +} from '../../../../components/src'; import { READER_REVENUE_WIZARD_SLUG } from '../../constants'; import './style.scss'; @@ -137,6 +145,34 @@ const StripeSetup = () => { payloadPath: [ 'stripe_data' ], } ); + if ( ! data ) { + return ( + <> + + { __( + 'To configure Stripe, install the WooCommerce Stripe Gateway plugin.', + 'newspack-plugin' + ) } + + { + if ( complete ) { + console.log( complete ); + updateWizardSettings( { + slug: 'newspack-reader-revenue-wizard', + path: [ 'stripe_data' ], + value: { activate: true }, + } ); + onSave(); + } + } } + withoutFooterButton={ true } + /> + > + ); + } + return ( <> { errors.length > 0 && diff --git a/includes/class-donations.php b/includes/class-donations.php index f8b387d48b..fe0bf8e462 100644 --- a/includes/class-donations.php +++ b/includes/class-donations.php @@ -107,7 +107,7 @@ public static function should_skip_amp( $skip, $post_id ) { * @return bool|WP_Error True if active. WP_Error if not. */ public static function is_woocommerce_suite_active() { - if ( ! function_exists( 'WC' ) || ! class_exists( 'WC_Subscriptions_Product' ) || ! class_exists( 'WC_Name_Your_Price_Helpers' ) ) { + if ( ! function_exists( 'WC' ) || ! class_exists( 'WC_Subscriptions_Product' ) ) { return new WP_Error( 'newspack_missing_required_plugin', esc_html__( 'The required plugins are not installed and activated. Install and/or activate them to access this feature.', 'newspack' ), @@ -121,6 +121,15 @@ public static function is_woocommerce_suite_active() { return true; } + /** + * Check if the Name Your Price extension is available. + * + * @return bool True if available, false if not. + */ + public static function can_use_name_your_price() { + return class_exists( 'WC_Name_Your_Price_Helpers' ); + } + /** * Get the default donation settings. * @@ -238,7 +247,7 @@ private static function get_donation_product_child_products_ids() { // Add the product IDs for each frequency. foreach ( $product->get_children() as $child_id ) { $child_product = wc_get_product( $child_id ); - if ( ! $child_product || 'trash' === $child_product->get_status() || ! (bool) WC_Name_Your_Price_Helpers::is_nyp( $child_id ) ) { + if ( ! $child_product || 'trash' === $child_product->get_status() ) { continue; } if ( 'subscription' === $child_product->get_type() ) { @@ -422,6 +431,11 @@ public static function get_donation_settings() { $parsed_settings['platform'] = self::get_platform_slug(); $parsed_settings['billingFields'] = self::get_billing_fields(); + // If NYP isn't available, force untiered config. + if ( ! self::can_use_name_your_price() ) { + $parsed_settings['tiered'] = false; + } + return $parsed_settings; } @@ -536,6 +550,7 @@ public static function update_donation_product( $args = [] ) { } $child_product->set_name( $product_name ); + $child_product->set_price( $price ); $child_product->set_regular_price( $price ); $child_product->update_meta_data( '_suggested_price', $price ); $child_product->update_meta_data( '_min_price', wc_format_decimal( $configuration['minimumDonation'] ) ); @@ -705,7 +720,7 @@ function ( $item ) { $cart_item_data = apply_filters( 'newspack_donations_cart_item_data', [ - 'nyp' => (float) \WC_Name_Your_Price_Helpers::standardize_number( $donation_value ), + 'nyp' => class_exists( 'WC_Name_Your_Price_Helpers' ) ? (float) \WC_Name_Your_Price_Helpers::standardize_number( $donation_value ) : null, 'referer' => $referer, 'newspack_popup_id' => filter_input( INPUT_GET, 'newspack_popup_id', FILTER_SANITIZE_NUMBER_INT ), ] diff --git a/includes/class-plugin-manager.php b/includes/class-plugin-manager.php index 0d51d5987d..83d6563be3 100644 --- a/includes/class-plugin-manager.php +++ b/includes/class-plugin-manager.php @@ -831,7 +831,7 @@ private static function reduce_plugin_info( $plugins, $key ) { $path = explode( '/', $key ); $folder = current( $path ); - // Strip version info from key. (e.g. 'woocommerce-stripe-gateway-4.1.2' should just be 'woocommerce-stripe-gateway'). + // Strip version info from key. (e.g. 'woocommerce-gateway-stripe-4.1.2' should just be 'woocommerce-gateway-stripe'). $folder = preg_replace( '/[\-0-9\.]+$/', '', $folder ); $plugins[ $folder ] = $key; diff --git a/includes/configuration_managers/class-woocommerce-configuration-manager.php b/includes/configuration_managers/class-woocommerce-configuration-manager.php index e2fc2a892e..df6110024e 100644 --- a/includes/configuration_managers/class-woocommerce-configuration-manager.php +++ b/includes/configuration_managers/class-woocommerce-configuration-manager.php @@ -86,7 +86,7 @@ public function country_state_fields() { * @return Array Array of payment gateways. */ public static function get_payment_gateways( $only_enabled = false ) { - if ( ! class_exists( '\WC_Payment_Gateways' ) ) { + if ( ! class_exists( 'WC_Payment_Gateways' ) ) { return []; } $gateways = \WC_Payment_Gateways::instance()->payment_gateways(); @@ -149,24 +149,35 @@ public function update_location( $args ) { return true; } + /** + * Get Stripe payment gateway, if available. + * + * @param bool $only_enabled If true, only return the gateway if enabled. + * + * @return WC_Gateway_Stripe|bool WC_Gateway_Stripe instance if Stripe payment gateway is available, false if not. + */ + public static function get_stripe_gateway( $only_enabled = false ) { + $gateways = self::get_payment_gateways(); + return isset( $gateways['stripe'] ) ? $gateways['stripe'] : false; + } + /** * Retrieve Stripe data * - * @return Array Array of Stripe data. + * @return Array|bool Array of Stripe data, or false if Stripe gateway isn't available. */ public function stripe_data() { - $gateways = self::get_payment_gateways(); - if ( ! isset( $gateways['stripe'] ) ) { - return []; + $stripe = self::get_stripe_gateway(); + if ( ! $stripe ) { + return false; } - $gateway = $gateways['stripe']; return [ - 'enabled' => 'yes' === $gateway->get_option( 'enabled', false ) ? true : false, - 'testMode' => 'yes' === $gateway->get_option( 'testmode', false ) ? true : false, - 'publishableKey' => $gateway->get_option( 'publishable_key', '' ), - 'secretKey' => $gateway->get_option( 'secret_key', '' ), - 'testPublishableKey' => $gateway->get_option( 'test_publishable_key', '' ), - 'testSecretKey' => $gateway->get_option( 'test_secret_key', '' ), + 'enabled' => 'yes' === $stripe->get_option( 'enabled', false ) ? true : false, + 'testMode' => 'yes' === $stripe->get_option( 'testmode', false ) ? true : false, + 'publishableKey' => $stripe->get_option( 'publishable_key', '' ), + 'secretKey' => $stripe->get_option( 'secret_key', '' ), + 'testPublishableKey' => $stripe->get_option( 'test_publishable_key', '' ), + 'testSecretKey' => $stripe->get_option( 'test_secret_key', '' ), ]; } @@ -177,25 +188,30 @@ public function stripe_data() { * @return Array|WP_Error The data that was updated or an error. */ public function update_wc_stripe_settings( $args ) { - - if ( ! class_exists( '\WC_Payment_Gateways' ) ) { + if ( ! class_exists( 'WC_Payment_Gateways' ) ) { return false; } - $gateways = WC_Payment_Gateways::instance()->payment_gateways(); - if ( ! isset( $gateways['stripe'] ) ) { + + // Get the Stripe payment gateway instance. + $stripe = self::get_stripe_gateway(); + + if ( ! $stripe ) { if ( isset( $args['enabled'] ) && $args['enabled'] ) { - // Stripe is not installed and we want to use it. Install/Activate/Initialize it. + // Stripe gateway is not installed and we want to use it. Install/Activate/Initialize it. Plugin_Manager::activate( 'woocommerce-gateway-stripe' ); do_action( 'plugins_loaded' ); - WC_Payment_Gateways::instance()->init(); - $gateways = WC_Payment_Gateways::instance()->payment_gateways(); + \WC_Payment_Gateways::instance()->init(); + $stripe = self::get_stripe_gateway(); + if ( ! $stripe ) { + return new WP_Error( 'newspack_stripe_gateway_error', __( 'Error activating the Stripe payment gateway.', 'newspack-plugin' ) ); + } } else { // Stripe is not installed and we don't want to use it. No settings needed. return true; } } - $stripe = $gateways['stripe']; + // Update Stripe payment gateway settings. if ( isset( $args['enabled'] ) ) { $stripe->update_option( 'enabled', $args['enabled'] ? 'yes' : 'no' ); } diff --git a/includes/reader-activation/class-reader-activation.php b/includes/reader-activation/class-reader-activation.php index 1bf4b92c67..d91d100f8f 100644 --- a/includes/reader-activation/class-reader-activation.php +++ b/includes/reader-activation/class-reader-activation.php @@ -484,10 +484,9 @@ public static function get_prerequisites_status() { 'reader_revenue' => [ 'active' => self::is_reader_revenue_ready(), 'plugins' => [ - 'newspack-blocks' => class_exists( '\Newspack_Blocks' ), - 'woocommerce' => function_exists( 'WC' ), - 'woocommerce-subscriptions' => class_exists( 'WC_Subscriptions_Product' ), - 'woocommerce-name-your-price' => class_exists( 'WC_Name_Your_Price_Helpers' ), + 'newspack-blocks' => class_exists( '\Newspack_Blocks' ), + 'woocommerce' => function_exists( 'WC' ), + 'woocommerce-subscriptions' => class_exists( 'WC_Subscriptions_Product' ), ], 'label' => __( 'Reader Revenue', 'newspack-plugin' ), 'description' => __( 'Setting suggested donation amounts is required for enabling a streamlined donation experience.', 'newspack-plugin' ), diff --git a/includes/reader-revenue/stripe/class-stripe-connection.php b/includes/reader-revenue/stripe/class-stripe-connection.php index 2a8cfed971..f35edfc46f 100644 --- a/includes/reader-revenue/stripe/class-stripe-connection.php +++ b/includes/reader-revenue/stripe/class-stripe-connection.php @@ -32,6 +32,9 @@ private static function is_value_non_empty( $value ) { public static function get_stripe_data() { $wc_configuration_manager = Configuration_Managers::configuration_manager_class_for_plugin_slug( 'woocommerce' ); $stripe_data = $wc_configuration_manager->stripe_data(); + if ( ! $stripe_data ) { + return $stripe_data; + } $location_code = 'US'; $currency = 'USD'; diff --git a/includes/wizards/class-reader-revenue-wizard.php b/includes/wizards/class-reader-revenue-wizard.php index 8693139d0f..b7b89c7237 100644 --- a/includes/wizards/class-reader-revenue-wizard.php +++ b/includes/wizards/class-reader-revenue-wizard.php @@ -336,8 +336,10 @@ public function api_update_location( $request ) { * @return WP_REST_Response with the latest settings. */ public function update_stripe_settings( $settings ) { - // Stripe has to be enabled explicitly. - if ( $settings['enabled'] ) { + if ( ! empty( $settings['activate'] ) ) { + // If activating the Stripe Gateway plugin, let's enable it. + $settings = [ 'enabled' => true ]; + } elseif ( $settings['enabled'] ) { if ( $settings['testMode'] && ( ! $this->api_validate_not_empty( $settings['testPublishableKey'] ) || ! $this->api_validate_not_empty( $settings['testSecretKey'] ) ) ) { return new WP_Error( 'newspack_missing_required_field', @@ -373,6 +375,7 @@ public function update_stripe_settings( $settings ) { if ( \is_wp_error( $result ) ) { return $result; } + return $this->fetch_all_data(); } @@ -466,8 +469,6 @@ public function fetch_all_data() { $managed_plugins = Plugin_Manager::get_managed_plugins(); $required_plugins = [ 'woocommerce', - 'woocommerce-gateway-stripe', - 'woocommerce-name-your-price', 'woocommerce-subscriptions', ]; foreach ( $required_plugins as $required_plugin ) { @@ -548,6 +549,7 @@ public function enqueue_scripts_and_styles() { 'emails' => Emails::get_emails( [ Reader_Revenue_Emails::EMAIL_TYPES['RECEIPT'] ], false ), 'email_cpt' => Emails::POST_TYPE, 'salesforce_redirect_url' => Salesforce::get_redirect_url(), + 'can_use_name_your_price' => Donations::can_use_name_your_price(), ] ); \wp_enqueue_script( 'newspack-reader-revenue-wizard' );
+ { __( + 'To configure Stripe, install the WooCommerce Stripe Gateway plugin.', + 'newspack-plugin' + ) } +