diff --git a/modules/ppcp-settings/resources/css/components/reusable-components/_settings-card.scss b/modules/ppcp-settings/resources/css/components/reusable-components/_settings-card.scss
index 441cf4608..30826351f 100644
--- a/modules/ppcp-settings/resources/css/components/reusable-components/_settings-card.scss
+++ b/modules/ppcp-settings/resources/css/components/reusable-components/_settings-card.scss
@@ -69,4 +69,17 @@ $width_gap: 24px;
color: var(--color-text-teriary);
margin: 0;
}
+
+ .ppcp--card-actions {
+ opacity: 0.5;
+ transition: opacity 0.3s;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ .components-button.is-tertiary:first-child {
+ padding-left: 0;
+ }
+ }
}
diff --git a/modules/ppcp-settings/resources/css/components/screens/_modals.scss b/modules/ppcp-settings/resources/css/components/screens/_modals.scss
new file mode 100644
index 000000000..fee98d538
--- /dev/null
+++ b/modules/ppcp-settings/resources/css/components/screens/_modals.scss
@@ -0,0 +1,13 @@
+/**
+ * Modal for disconnecting the merchant from the current PayPal account.
+ */
+.ppcp--modal-disconnect {
+ .ppcp--toggle-danger {
+ --wp-components-color-accent: #cc1818
+ }
+
+ .ppcp--action-buttons {
+ text-align: right;
+ margin-top: 32px;
+ }
+}
diff --git a/modules/ppcp-settings/resources/css/style.scss b/modules/ppcp-settings/resources/css/style.scss
index 0875dcad5..d70b4533f 100644
--- a/modules/ppcp-settings/resources/css/style.scss
+++ b/modules/ppcp-settings/resources/css/style.scss
@@ -11,3 +11,4 @@
@import './components/reusable-components/payment-method-modal';
@import './components/screens/fullscreen';
+@import './components/screens/modals';
diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/ConnectionStatus.js b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/ConnectionStatus.js
index 5ddc31a7c..341f11a3d 100644
--- a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/ConnectionStatus.js
+++ b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/ConnectionStatus.js
@@ -59,7 +59,9 @@ const ConnectionDescription = () => {
'Your PayPal account connection details.',
'woocommerce-paypal-payments'
) }
-
+
+
+
>
);
};
diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/Parts/DisconnectButton.js b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/Parts/DisconnectButton.js
index aabdd2192..8e5fbe9d6 100644
--- a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/Parts/DisconnectButton.js
+++ b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Components/Settings/Parts/DisconnectButton.js
@@ -1,5 +1,5 @@
import { __ } from '@wordpress/i18n';
-import { Button, Modal } from '@wordpress/components';
+import { Button, Modal, ToggleControl } from '@wordpress/components';
import { useCallback, useState } from '@wordpress/element';
import { CommonHooks } from '../../../../../../data';
@@ -7,6 +7,7 @@ import { HStack } from '../../../../../ReusableComponents/Stack';
const DisconnectButton = () => {
const [ isOpen, setIsOpen ] = useState( false );
+ const [ resetFlag, setResetFlag ] = useState( false );
const { disconnectMerchant } = CommonHooks.useDisconnectMerchant();
const handleOpen = useCallback( () => {
@@ -18,9 +19,9 @@ const DisconnectButton = () => {
}, [] );
const handleConfirm = useCallback( async () => {
- await disconnectMerchant();
+ await disconnectMerchant( resetFlag );
window.location.reload();
- }, [ disconnectMerchant ] );
+ }, [ disconnectMerchant, resetFlag ] );
const confirmationTitle = __(
'Disconnect from PayPal?',
@@ -39,6 +40,7 @@ const DisconnectButton = () => {
{ isOpen && (
{
'woocommerce-paypal-payments'
) }
-
+
+
diff --git a/modules/ppcp-settings/resources/js/data/common/actions-thunk.js b/modules/ppcp-settings/resources/js/data/common/actions-thunk.js
index 0de08f245..8e7448af8 100644
--- a/modules/ppcp-settings/resources/js/data/common/actions-thunk.js
+++ b/modules/ppcp-settings/resources/js/data/common/actions-thunk.js
@@ -153,13 +153,17 @@ export function authenticateWithOAuth( sharedId, authCode, useSandbox ) {
/**
* Side effect. Checks webhook simulation.
*
+ * @param {boolean} fullReset When true, all plugin settings are reset to initial values.
* @return {Function} The thunk function.
*/
-export function disconnectMerchant() {
+export function disconnectMerchant( fullReset = false ) {
return async () => {
return await apiFetch( {
path: REST_DISCONNECT_MERCHANT_PATH,
method: 'POST',
+ data: {
+ reset: fullReset,
+ },
} );
};
}
diff --git a/modules/ppcp-settings/services.php b/modules/ppcp-settings/services.php
index 9381fee1b..e5ab98d74 100644
--- a/modules/ppcp-settings/services.php
+++ b/modules/ppcp-settings/services.php
@@ -38,6 +38,7 @@ use WooCommerce\PayPalCommerce\Settings\Service\OnboardingUrlManager;
use WooCommerce\PayPalCommerce\Settings\Service\TodosEligibilityService;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\Settings\Service\DataSanitizer;
+use WooCommerce\PayPalCommerce\Settings\Service\SettingsDataManager;
return array(
'settings.url' => static function ( ContainerInterface $container ) : string {
@@ -122,9 +123,10 @@ return array(
$container->get( 'woocommerce.logger.woocommerce' )
);
},
- 'settings.rest.connect_manual' => static function ( ContainerInterface $container ) : AuthenticationRestEndpoint {
+ 'settings.rest.authentication' => static function ( ContainerInterface $container ) : AuthenticationRestEndpoint {
return new AuthenticationRestEndpoint(
$container->get( 'settings.service.authentication_manager' ),
+ $container->get( 'settings.service.data-manager' )
);
},
'settings.rest.login_link' => static function ( ContainerInterface $container ) : LoginLinkRestEndpoint {
@@ -246,6 +248,19 @@ return array(
'settings.service.sanitizer' => static function ( ContainerInterface $container ) : DataSanitizer {
return new DataSanitizer();
},
+ 'settings.service.data-manager' => static function ( ContainerInterface $container ) : SettingsDataManager {
+ $models = array(
+ $container->get( 'settings.data.onboarding' ),
+ $container->get( 'settings.data.general' ),
+ $container->get( 'settings.data.styling' ),
+ $container->get( 'settings.data.payment' ),
+ $container->get( 'settings.data.settings' ),
+ $container->get( 'settings.data.todos' ),
+ $container->get( 'settings.data.definition.todos' ),
+ );
+
+ return new SettingsDataManager( $models );
+ },
'settings.ajax.switch_ui' => static function ( ContainerInterface $container ) : SwitchSettingsUiEndpoint {
return new SwitchSettingsUiEndpoint(
$container->get( 'woocommerce.logger.woocommerce' ),
@@ -270,14 +285,14 @@ return array(
$container->get( 'settings.data.general' )
);
},
- 'settings.service.todos_eligibilities' => static function( ContainerInterface $container ): TodosEligibilityService {
+ 'settings.service.todos_eligibilities' => static function ( ContainerInterface $container ) : TodosEligibilityService {
$features = apply_filters(
'woocommerce_paypal_payments_rest_common_merchant_features',
array()
);
$payment_endpoint = $container->get( 'settings.rest.payment' );
- $settings = $payment_endpoint->get_details()->get_data();
+ $settings = $payment_endpoint->get_details()->get_data();
$pay_later_endpoint = $container->get( 'settings.rest.pay_later_messaging' );
$pay_later_settings = $pay_later_endpoint->get_details()->get_data();
@@ -312,20 +327,20 @@ return array(
$is_pay_later_messaging_enabled_for_any_location = ! array_filter( $pay_later_statuses );
return new TodosEligibilityService(
- $capabilities['acdc'] && ! $gateways['axo'], // Enable Fastlane.
- $capabilities['acdc'] && ! $gateways['card-button'], // Enable Credit and Debit Cards on your checkout.
- $is_pay_later_messaging_enabled_for_any_location, // Enable Pay Later messaging.
- ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['product'], // Add Pay Later messaging (Product page).
- ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['cart'], // Add Pay Later messaging (Cart).
- ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['checkout'], // Add Pay Later messaging (Checkout).
- true, // Configure a PayPal Subscription.
- true, // Add PayPal buttons.
- true, // Register Domain for Apple Pay.
+ $capabilities['acdc'] && ! $gateways['axo'], // Enable Fastlane.
+ $capabilities['acdc'] && ! $gateways['card-button'], // Enable Credit and Debit Cards on your checkout.
+ $is_pay_later_messaging_enabled_for_any_location, // Enable Pay Later messaging.
+ ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['product'], // Add Pay Later messaging (Product page).
+ ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['cart'], // Add Pay Later messaging (Cart).
+ ! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['checkout'], // Add Pay Later messaging (Checkout).
+ true, // Configure a PayPal Subscription.
+ true, // Add PayPal buttons.
+ true, // Register Domain for Apple Pay.
$capabilities['acdc'] && ! ( $capabilities['apple_pay'] && $capabilities['google_pay'] ), // Add digital wallets to your account.
- $capabilities['acdc'] && ! $capabilities['apple_pay'], // Add Apple Pay to your account.
- $capabilities['acdc'] && ! $capabilities['google_pay'], // Add Google Pay to your account.
- true, // Configure a PayPal Subscription.
- $capabilities['apple_pay'] && ! $gateways['apple_pay'], // Enable Apple Pay.
+ $capabilities['acdc'] && ! $capabilities['apple_pay'], // Add Apple Pay to your account.
+ $capabilities['acdc'] && ! $capabilities['google_pay'], // Add Google Pay to your account.
+ true, // Configure a PayPal Subscription.
+ $capabilities['apple_pay'] && ! $gateways['apple_pay'], // Enable Apple Pay.
$capabilities['google_pay'] && ! $gateways['google_pay'], // Enable Google Pay.
);
},
diff --git a/modules/ppcp-settings/src/Data/AbstractDataModel.php b/modules/ppcp-settings/src/Data/AbstractDataModel.php
index 070015af2..13c3d1ddd 100644
--- a/modules/ppcp-settings/src/Data/AbstractDataModel.php
+++ b/modules/ppcp-settings/src/Data/AbstractDataModel.php
@@ -69,6 +69,13 @@ abstract class AbstractDataModel {
update_option( static::OPTION_KEY, $this->data );
}
+ /**
+ * Deletes the settings entry from the WordPress database.
+ */
+ public function purge() : void {
+ delete_option( static::OPTION_KEY );
+ }
+
/**
* Gets all model data as an array.
*
diff --git a/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php b/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php
index 55a3b8353..d6499270b 100644
--- a/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php
+++ b/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php
@@ -14,6 +14,7 @@ use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use WooCommerce\PayPalCommerce\Settings\Service\AuthenticationManager;
+use WooCommerce\PayPalCommerce\Settings\Service\SettingsDataManager;
/**
* REST controller for authenticating and connecting to a PayPal merchant account.
@@ -40,6 +41,13 @@ class AuthenticationRestEndpoint extends RestEndpoint {
*/
private AuthenticationManager $authentication_manager;
+ /**
+ * Settings data manager service.
+ *
+ * @var SettingsDataManager
+ */
+ private SettingsDataManager $data_manager;
+
/**
* Defines the JSON response format (when connection was successful).
*
@@ -58,9 +66,12 @@ class AuthenticationRestEndpoint extends RestEndpoint {
* Constructor.
*
* @param AuthenticationManager $authentication_manager The authentication manager.
+ * @param SettingsDataManager $data_manager Settings data manager, to reset
+ * settings.
*/
- public function __construct( AuthenticationManager $authentication_manager ) {
+ public function __construct( AuthenticationManager $authentication_manager, SettingsDataManager $data_manager ) {
$this->authentication_manager = $authentication_manager;
+ $this->data_manager = $data_manager;
}
/**
@@ -209,11 +220,19 @@ class AuthenticationRestEndpoint extends RestEndpoint {
/**
* Disconnect the merchant and clear the authentication details.
*
+ * @param WP_REST_Request $request Full data about the request.
+ *
* @return WP_REST_Response
*/
- public function disconnect() : WP_REST_Response {
+ public function disconnect( WP_REST_Request $request ) : WP_REST_Response {
+ $reset_settings = $request->get_param( 'reset' );
+
$this->authentication_manager->disconnect();
+ if ( $reset_settings ) {
+ $this->data_manager->reset_all_settings();
+ }
+
return $this->return_success( 'OK' );
}
}
diff --git a/modules/ppcp-settings/src/Service/SettingsDataManager.php b/modules/ppcp-settings/src/Service/SettingsDataManager.php
new file mode 100644
index 000000000..cb7aa6275
--- /dev/null
+++ b/modules/ppcp-settings/src/Service/SettingsDataManager.php
@@ -0,0 +1,62 @@
+models[] = $data_model;
+ }
+ }
+ }
+
+ /**
+ * Completely purges all settings from the DB.
+ *
+ * @return void
+ */
+ public function reset_all_settings() : void {
+ /**
+ * Broadcast the settings-reset event to allow other modules to perform
+ * cleanup tasks, if needed.
+ */
+ do_action( 'woocommerce_paypal_payments_reset_settings' );
+
+ foreach ( $this->models as $model ) {
+ $model->purge();
+ }
+
+ // Clear any caches.
+ wp_cache_flush();
+ }
+}
diff --git a/modules/ppcp-settings/src/SettingsModule.php b/modules/ppcp-settings/src/SettingsModule.php
index 707f55e24..2035011d6 100644
--- a/modules/ppcp-settings/src/SettingsModule.php
+++ b/modules/ppcp-settings/src/SettingsModule.php
@@ -232,7 +232,7 @@ class SettingsModule implements ServiceModule, ExecutableModule {
$endpoints = array(
'onboarding' => $container->get( 'settings.rest.onboarding' ),
'common' => $container->get( 'settings.rest.common' ),
- 'connect_manual' => $container->get( 'settings.rest.connect_manual' ),
+ 'connect_manual' => $container->get( 'settings.rest.authentication' ),
'login_link' => $container->get( 'settings.rest.login_link' ),
'webhooks' => $container->get( 'settings.rest.webhooks' ),
'refresh_feature_status' => $container->get( 'settings.rest.refresh_feature_status' ),