From 38135bc94e12df483394f0c8d23833e7d84a5a1b Mon Sep 17 00:00:00 2001 From: Alex P Date: Fri, 4 Feb 2022 10:50:54 +0200 Subject: [PATCH] Allow to switch between live and sandbox --- .../ppcp-onboarding/assets/css/onboarding.css | 52 +++------------ .../ppcp-onboarding/assets/js/onboarding.js | 63 ++++++++++++++++--- modules/ppcp-onboarding/assets/js/settings.js | 6 +- .../src/Assets/OnboardingAssets.php | 9 ++- .../src/OnboardingRESTController.php | 32 +--------- modules/ppcp-onboarding/src/State.php | 17 +++++ modules/ppcp-wc-gateway/services.php | 30 ++++++--- .../src/Settings/SettingsRenderer.php | 1 + 8 files changed, 117 insertions(+), 93 deletions(-) diff --git a/modules/ppcp-onboarding/assets/css/onboarding.css b/modules/ppcp-onboarding/assets/css/onboarding.css index 212ac2033..a09a150d9 100644 --- a/modules/ppcp-onboarding/assets/css/onboarding.css +++ b/modules/ppcp-onboarding/assets/css/onboarding.css @@ -2,25 +2,19 @@ display: none; } -#field-merchant_email_production, -#field-merchant_id_production, -#field-client_id_production, -#field-client_secret_production, -#field-merchant_email_sandbox, -#field-merchant_id_sandbox, -#field-client_id_sandbox, -#field-client_secret_sandbox{ +.ppcp-onboarded .ppcp-onboarding-element:not(.ppcp-always-shown-element) { display: none; } -#field-merchant_email_production.show, -#field-merchant_id_production.show, -#field-client_id_production.show, -#field-client_secret_production.show, -#field-merchant_email_sandbox.show, -#field-merchant_id_sandbox.show, -#field-client_id_sandbox.show, -#field-client_secret_sandbox.show { +.ppcp-onboarding .ppcp-settings-field:not(.ppcp-onboarding-element):not(.ppcp-always-shown-element) { + display: none; +} + +.ppcp-settings-field.hide { + display: none; +} + +.ppcp-settings-field.show { display: table-row; } @@ -37,32 +31,6 @@ padding: 0; } -#field-sandbox_on.onboarded { - display: none; -} - -#field-merchant_email_sandbox.onboarded, -#field-merchant_id_sandbox.onboarded, -#field-client_id_sandbox.onboarded, -#field-client_secret_sandbox.onboarded, -#field-merchant_email_production.onboarded, -#field-merchant_id_production.onboarded, -#field-client_id_production.onboarded, -#field-client_secret_production.onboarded { - display:table-row; -} - -#field-merchant_email_sandbox.onboarded.hide, -#field-merchant_id_sandbox.onboarded.hide, -#field-client_id_sandbox.onboarded.hide, -#field-client_secret_sandbox.onboarded.hide, -#field-merchant_email_production.onboarded.hide, -#field-merchant_id_production.onboarded.hide, -#field-client_id_production.onboarded.hide, -#field-client_secret_production.onboarded.hide { - display:none; -} - /* Probably not the best location for this but will do until there's a general purpose settings CSS file. */ .ppcp-settings-field-heading td, .ppcp-settings-field-heading th, .ppcp-settings-no-title-col td { padding-left: 0; diff --git a/modules/ppcp-onboarding/assets/js/onboarding.js b/modules/ppcp-onboarding/assets/js/onboarding.js index 43582ac4d..950c50483 100644 --- a/modules/ppcp-onboarding/assets/js/onboarding.js +++ b/modules/ppcp-onboarding/assets/js/onboarding.js @@ -4,6 +4,9 @@ const ppcp_onboarding = { PAYPAL_JS_ID: 'ppcp-onboarding-paypal-js', _timeout: false, + STATE_START: 'start', + STATE_ONBOARDED: 'onboarded', + init: function() { document.addEventListener('DOMContentLoaded', this.reload); }, @@ -132,7 +135,7 @@ const updateOptionsState = () => { ); }; -const updateManualInputControls = (shown, isSandbox) => { +const updateManualInputControls = (shown, isSandbox, isAnyEnvOnboarded) => { const productionElementsSelectors = [ '#field-merchant_email_production', '#field-merchant_id_production', @@ -146,9 +149,11 @@ const updateManualInputControls = (shown, isSandbox) => { '#field-client_secret_sandbox', ]; const otherElementsSelectors = [ - '#field-sandbox_on', '.woocommerce-save-button', ]; + if (!isAnyEnvOnboarded) { + otherElementsSelectors.push('#field-sandbox_on'); + } document.querySelectorAll(productionElementsSelectors.join()).forEach( element => { @@ -167,6 +172,24 @@ const updateManualInputControls = (shown, isSandbox) => { ); }; +const updateEnvironmentControls = (isSandbox) => { + const productionElementsSelectors = [ + '#field-ppcp_disconnect_production', + '#field-credentials_production_heading', + ]; + const sandboxElementsSelectors = [ + '#field-ppcp_disconnect_sandbox', + '#field-credentials_sandbox_heading', + ]; + + document.querySelectorAll(productionElementsSelectors.join()).forEach( + element => element.style.display = !isSandbox ? '' : 'none' + ); + document.querySelectorAll(sandboxElementsSelectors.join()).forEach( + element => element.style.display = isSandbox ? '' : 'none' + ); +}; + const disconnect = (event) => { event.preventDefault(); const fields = event.target.classList.contains('production') ? [ @@ -203,6 +226,9 @@ const preventDirtyCheckboxPropagation = event => { }; (() => { + const isAnyEnvOnboarded = PayPalCommerceGatewayOnboarding.sandbox_state === ppcp_onboarding.STATE_ONBOARDED || + PayPalCommerceGatewayOnboarding.production_state === ppcp_onboarding.STATE_ONBOARDED; + document.querySelectorAll('.ppcp-disconnect').forEach( (button) => { button.addEventListener( @@ -224,32 +250,55 @@ const preventDirtyCheckboxPropagation = event => { updateOptionsState(); + const settingsContainer = document.querySelector('#mainform .form-table'); + + const markCurrentOnboardingState = (isOnboarded) => { + settingsContainer.classList.remove('ppcp-onboarded', 'ppcp-onboarding'); + settingsContainer.classList.add(isOnboarded ? 'ppcp-onboarded' : 'ppcp-onboarding'); + } + + markCurrentOnboardingState(PayPalCommerceGatewayOnboarding.current_state === ppcp_onboarding.STATE_ONBOARDED); + const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on'); const manualInputToggleButton = document.querySelector('#field-toggle_manual_input button'); - let isManualInputShown = manualInputToggleButton === null; // toggle is removed after onboarding and the fields are always shown + let isManualInputShown = isAnyEnvOnboarded; - manualInputToggleButton?.addEventListener( + manualInputToggleButton.addEventListener( 'click', (event) => { event.preventDefault(); isManualInputShown = !isManualInputShown; - updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked); + updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked, isAnyEnvOnboarded); } ); sandboxSwitchElement.addEventListener( 'click', (event) => { - updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked); + const isSandbox = sandboxSwitchElement.checked; + + if (isAnyEnvOnboarded) { + const onboardingState = isSandbox ? PayPalCommerceGatewayOnboarding.sandbox_state : PayPalCommerceGatewayOnboarding.production_state; + const isOnboarded = onboardingState === ppcp_onboarding.STATE_ONBOARDED; + + markCurrentOnboardingState(isOnboarded); + isManualInputShown = isOnboarded; + } + + updateManualInputControls(isManualInputShown, isSandbox, isAnyEnvOnboarded); + + updateEnvironmentControls(isSandbox); preventDirtyCheckboxPropagation(event); } ); - updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked); + updateManualInputControls(isManualInputShown, sandboxSwitchElement.checked, isAnyEnvOnboarded); + + updateEnvironmentControls(sandboxSwitchElement.checked); // Onboarding buttons. ppcp_onboarding.init(); diff --git a/modules/ppcp-onboarding/assets/js/settings.js b/modules/ppcp-onboarding/assets/js/settings.js index e30b45856..9af409f07 100644 --- a/modules/ppcp-onboarding/assets/js/settings.js +++ b/modules/ppcp-onboarding/assets/js/settings.js @@ -23,7 +23,7 @@ document.addEventListener( } group.forEach( (elementToShow) => { - document.querySelector(elementToShow).style.display = 'table-row'; + document.querySelector(elementToShow).style.display = ''; }) if('ppcp-message_enabled' === event.target.getAttribute('id')){ @@ -56,7 +56,7 @@ document.addEventListener( return; } if (value === elementToToggle.value && domElement.style.display !== 'none') { - domElement.style.display = 'table-row'; + domElement.style.display = ''; return; } domElement.style.display = 'none'; @@ -69,7 +69,7 @@ document.addEventListener( const value = event.target.value; group.forEach( (elementToToggle) => { if (value === elementToToggle.value) { - document.querySelector(elementToToggle.selector).style.display = 'table-row'; + document.querySelector(elementToToggle.selector).style.display = ''; return; } document.querySelector(elementToToggle.selector).style.display = 'none'; diff --git a/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php b/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php index 57a632860..9c883e960 100644 --- a/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php +++ b/modules/ppcp-onboarding/src/Assets/OnboardingAssets.php @@ -103,9 +103,12 @@ class OnboardingAssets { */ public function get_script_data() { return array( - 'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ), - 'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ), - 'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js', + 'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ), + 'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ), + 'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js', + 'sandbox_state' => State::get_state_name( $this->state->sandbox_state() ), + 'production_state' => State::get_state_name( $this->state->production_state() ), + 'current_state' => State::get_state_name( $this->state->current_state() ), ); } diff --git a/modules/ppcp-onboarding/src/OnboardingRESTController.php b/modules/ppcp-onboarding/src/OnboardingRESTController.php index 8e9a60290..209534564 100644 --- a/modules/ppcp-onboarding/src/OnboardingRESTController.php +++ b/modules/ppcp-onboarding/src/OnboardingRESTController.php @@ -10,7 +10,6 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\Onboarding; use Psr\Container\ContainerInterface; -use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; /** @@ -138,13 +137,13 @@ class OnboardingRESTController { return array( 'environment' => $environment->current_environment(), 'onboarded' => ( $state->current_state() >= State::STATE_ONBOARDED ), - 'state' => $this->get_onboarding_state_name( $state->current_state() ), + 'state' => State::get_state_name( $state->current_state() ), 'sandbox' => array( - 'state' => $this->get_onboarding_state_name( $state->sandbox_state() ), + 'state' => State::get_state_name( $state->sandbox_state() ), 'onboarded' => ( $state->sandbox_state() >= State::STATE_ONBOARDED ), ), 'production' => array( - 'state' => $this->get_onboarding_state_name( $state->production_state() ), + 'state' => State::get_state_name( $state->production_state() ), 'onboarded' => ( $state->production_state() >= State::STATE_ONBOARDED ), ), ); @@ -265,31 +264,6 @@ class OnboardingRESTController { return add_query_arg( $this->return_url_args, $url ); } - /** - * Translates an onboarding state to a string. - * - * @param int $state An onboarding state to translate as returned by {@link State} methods. - * @return string A string representing the state: "start", "progressive" or "onboarded". - * @see State::current_state(), State::sandbox_state(), State::production_state(). - */ - public function get_onboarding_state_name( $state ) { - $name = 'unknown'; - - switch ( absint( $state ) ) { - case State::STATE_START: - $name = 'start'; - break; - case State::STATE_ONBOARDED: - $name = 'onboarded'; - break; - default: - break; - - } - - return $name; - } - /** * Generates a signup link for onboarding for a given environment and optionally adding certain URL arguments * to the URL users are redirected after completing the onboarding flow. diff --git a/modules/ppcp-onboarding/src/State.php b/modules/ppcp-onboarding/src/State.php index 370fe95b4..9967ac406 100644 --- a/modules/ppcp-onboarding/src/State.php +++ b/modules/ppcp-onboarding/src/State.php @@ -115,6 +115,23 @@ class State { ); } + /** + * Translates an onboarding state to a string. + * + * @param int $state An onboarding state to translate. + * @return string A string representing the state: "start" or "onboarded". + */ + public static function get_state_name( int $state ) : string { + switch ( $state ) { + case self::STATE_START: + return 'start'; + case self::STATE_ONBOARDED: + return 'onboarded'; + default: + return 'unknown'; + } + } + /** * Returns the state based on progressive and onboarded values being looked up in the settings. * diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index e4319ac8a..bb879bdd4 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -272,6 +272,7 @@ return array( $fields = array( 'ppcp_onboarading_header' => array( 'type' => 'ppcp-text', + 'classes' => array( 'ppcp-onboarding-element' ), 'text' => '
@@ -296,6 +297,7 @@ return array(
', 'screens' => array( State::STATE_START, + State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', @@ -307,6 +309,7 @@ return array( 'screens' => array( State::STATE_ONBOARDED, ), + 'state_from' => Environment::PRODUCTION, 'requirements' => array(), 'gateway' => 'paypal', ), @@ -316,6 +319,7 @@ return array( 'screens' => array( State::STATE_ONBOARDED, ), + 'state_from' => Environment::SANDBOX, 'requirements' => array(), 'gateway' => 'paypal', 'description' => __( 'Your account is connected to sandbox, no real charging takes place. To accept live payments, disconnect and connect your live PayPal account.', 'woocommerce-paypal-payments' ), @@ -323,10 +327,12 @@ return array( 'ppcp_onboarading_options' => array( 'type' => 'ppcp-text', + 'classes' => array( 'ppcp-onboarding-element' ), 'text' => $onboarding_options_renderer->render( $is_shop_supports_dcc ), 'raw' => true, 'screens' => array( State::STATE_START, + State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', @@ -337,6 +343,7 @@ return array( // is to have the buttons before loading the script. 'ppcp_onboarding_production_ppcp' => array( 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), 'screens' => array( State::STATE_START, ), @@ -348,6 +355,7 @@ return array( ), 'ppcp_onboarding_production_express' => array( 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), 'screens' => array( State::STATE_START, ), @@ -359,6 +367,7 @@ return array( ), 'ppcp_onboarding_sandbox_ppcp' => array( 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), 'screens' => array( State::STATE_START, ), @@ -371,6 +380,7 @@ return array( ), 'ppcp_onboarding_sandbox_express' => array( 'type' => 'ppcp_onboarding', + 'classes' => array( 'ppcp-onboarding-element' ), 'screens' => array( State::STATE_START, ), @@ -411,15 +421,17 @@ return array( 'toggle_manual_input' => array( 'type' => 'ppcp-text', 'text' => '', + 'classes' => array( 'ppcp-onboarding-element' ), 'screens' => array( State::STATE_START, + State::STATE_ONBOARDED, ), 'requirements' => array(), 'gateway' => 'paypal', ), 'sandbox_on' => array( 'title' => __( 'Sandbox', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() || State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( 'ppcp-onboarding-element', 'ppcp-always-shown-element' ), 'type' => 'checkbox', 'label' => __( 'To test your WooCommerce installation, you can use the sandbox mode.', 'woocommerce-paypal-payments' ), 'default' => 0, @@ -432,7 +444,7 @@ return array( ), 'merchant_email_production' => array( 'title' => __( 'Live Email address', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'text', 'required' => true, 'desc_tip' => true, @@ -447,7 +459,7 @@ return array( ), 'merchant_id_production' => array( 'title' => __( 'Live Merchant Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ), @@ -461,7 +473,7 @@ return array( ), 'client_id_production' => array( 'title' => __( 'Live Client Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ), @@ -475,7 +487,7 @@ return array( ), 'client_secret_production' => array( 'title' => __( 'Live Secret Key', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-password', 'desc_tip' => true, 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ), @@ -490,7 +502,7 @@ return array( 'merchant_email_sandbox' => array( 'title' => __( 'Sandbox Email address', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'text', 'required' => true, 'desc_tip' => true, @@ -505,7 +517,7 @@ return array( ), 'merchant_id_sandbox' => array( 'title' => __( 'Sandbox Merchant Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ), @@ -519,7 +531,7 @@ return array( ), 'client_id_sandbox' => array( 'title' => __( 'Sandbox Client Id', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-text-input', 'desc_tip' => true, 'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ), @@ -533,7 +545,7 @@ return array( ), 'client_secret_sandbox' => array( 'title' => __( 'Sandbox Secret Key', 'woocommerce-paypal-payments' ), - 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '' ), + 'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ), 'type' => 'ppcp-password', 'desc_tip' => true, 'description' => __( 'The secret key of your api', 'woocommerce-paypal-payments' ), diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php b/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php index d5d68be4b..61e3f8313 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php @@ -419,6 +419,7 @@ $data_rows_html $config['id'] = $id; $colspan = ( 'ppcp-heading' !== $config['type'] && isset( $config['title'] ) ) ? 1 : 2; $classes = isset( $config['classes'] ) ? $config['classes'] : array(); + $classes[] = 'ppcp-settings-field'; $classes[] = sprintf( 'ppcp-settings-field-%s', str_replace( 'ppcp-', '', $config['type'] ) ); if ( 1 !== $colspan ) { $classes[] = 'ppcp-settings-no-title-col';