From cd9ff71cd08d5f21de6b6d7aa47712243a2e01a3 Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Wed, 29 Jan 2025 16:05:14 +0100
Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Update=20the=20settings=20?=
=?UTF-8?q?data=20model=20class?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
modules/ppcp-settings/services.php | 8 +-
.../ppcp-settings/src/Data/SettingsModel.php | 342 +++++++++++++++---
2 files changed, 295 insertions(+), 55 deletions(-)
diff --git a/modules/ppcp-settings/services.php b/modules/ppcp-settings/services.php
index cf397b8bf..d99107890 100644
--- a/modules/ppcp-settings/services.php
+++ b/modules/ppcp-settings/services.php
@@ -81,6 +81,11 @@ return array(
'settings.data.payment' => static function ( ContainerInterface $container ) : PaymentSettings {
return new PaymentSettings();
},
+ 'settings.data.settings' => static function ( ContainerInterface $container ) : SettingsModel {
+ return new SettingsModel(
+ $container->get( 'settings.service.sanitizer' )
+ );
+ },
'settings.rest.onboarding' => static function ( ContainerInterface $container ) : OnboardingRestEndpoint {
return new OnboardingRestEndpoint( $container->get( 'settings.data.onboarding' ) );
},
@@ -230,9 +235,6 @@ return array(
$container->get( 'woocommerce.logger.woocommerce' ),
);
},
- 'settings.data.settings' => static function() : SettingsModel {
- return new SettingsModel();
- },
'settings.rest.todos' => static function ( ContainerInterface $container ) : TodosRestEndpoint {
return new TodosRestEndpoint(
$container->get( 'settings.data.todos' ),
diff --git a/modules/ppcp-settings/src/Data/SettingsModel.php b/modules/ppcp-settings/src/Data/SettingsModel.php
index 9bb2b94bb..915980bd7 100644
--- a/modules/ppcp-settings/src/Data/SettingsModel.php
+++ b/modules/ppcp-settings/src/Data/SettingsModel.php
@@ -9,81 +9,319 @@ declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Settings\Data;
-use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
+use RuntimeException;
+use WooCommerce\PayPalCommerce\Settings\Service\DataSanitizer;
/**
* Class SettingsModel
*
* Handles the storage and retrieval of PayPal Commerce settings in WordPress options table.
- * Provides methods to get and update settings with proper type casting and default values.
*/
-class SettingsModel {
+class SettingsModel extends AbstractDataModel {
+
/**
- * WordPress option name for storing the settings.
+ * Option key where settings are stored.
*
* @var string
*/
- const OPTION_NAME = 'ppcp_settings';
+ protected const OPTION_KEY = 'woocommerce-ppcp-data-settings';
/**
- * Retrieves the formatted settings from WordPress options.
+ * Valid options for subtotal adjustment.
*
- * Loads the raw settings from wp_options table and formats them into a
- * standardized array structure with proper type casting.
- *
- * @return array The formatted settings array.
+ * @var array
*/
- public function get() : array {
- $settings = get_option( self::OPTION_NAME, array() );
+ public const SUBTOTAL_ADJUSTMENT_OPTIONS = array( 'correction', 'no_details', 'skip_details' );
- $formatted = array(
- 'invoicePrefix' => $settings['invoice_prefix'] ?? '',
- 'authorizeOnly' => (bool) ( $settings['authorize_only'] ?? false ),
- 'captureVirtualOnlyOrders' => (bool) ( $settings['capture_virtual_only_orders'] ?? false ),
- 'savePaypalAndVenmo' => (bool) ( $settings['save_paypal_and_venmo'] ?? false ),
- 'saveCardDetails' => (bool) ( $settings['save_credit_card_and_debit_card'] ?? false ),
- 'payNowExperience' => (bool) ( $settings['pay_now_experience'] ?? false ),
- 'logging' => (bool) ( $settings['logging'] ?? false ),
- 'subtotalAdjustment' => $settings['subtotal_mismatch_fallback'] ?? null,
- 'brandName' => $settings['brand_name'] ?? '',
- 'softDescriptor' => $settings['soft_descriptor'] ?? '',
- 'landingPage' => $settings['paypal_landing_page'] ?? null,
- 'buttonLanguage' => $settings['button_language'] ?? '',
- );
+ /**
+ * Valid options for landing page.
+ *
+ * @var array
+ */
+ public const LANDING_PAGE_OPTIONS = array( 'any', 'login', 'guest_checkout' );
- return $formatted;
+ /**
+ * Data sanitizer service.
+ *
+ * @var DataSanitizer
+ */
+ protected DataSanitizer $sanitizer;
+
+ /**
+ * Constructor.
+ *
+ * @param DataSanitizer $sanitizer Data sanitizer service.
+ * @throws RuntimeException If the OPTION_KEY is not defined in the child class.
+ */
+ public function __construct( DataSanitizer $sanitizer ) {
+ $this->sanitizer = $sanitizer;
+ parent::__construct();
}
/**
- * Updates the settings in WordPress options.
+ * Get default values for the model.
*
- * Converts the provided data array from camelCase to snake_case format
- * and saves it to wp_options table. Throws an exception if update fails.
- *
- * @param array $data The settings data to update.
- * @return void
- * @throws RuntimeException When the settings update fails.
+ * @return array
*/
- public function update( array $data ) : void {
- $settings = array(
- 'invoice_prefix' => $data['invoicePrefix'] ?? '',
- 'authorize_only' => (bool) ( $data['authorizeOnly'] ?? false ),
- 'capture_virtual_only_orders' => (bool) ( $data['captureVirtualOnlyOrders'] ?? false ),
- 'save_paypal_and_venmo' => (bool) ( $data['savePaypalAndVenmo'] ?? false ),
- 'save_credit_card_and_debit_card' => (bool) ( $data['saveCardDetails'] ?? false ),
- 'pay_now_experience' => (bool) ( $data['payNowExperience'] ?? false ),
- 'logging' => (bool) ( $data['logging'] ?? false ),
- 'subtotal_mismatch_fallback' => $data['subtotalAdjustment'] ?? null,
- 'brand_name' => $data['brandName'] ?? '',
- 'soft_descriptor' => $data['softDescriptor'] ?? '',
- 'paypal_landing_page' => $data['landingPage'] ?? null,
- 'button_language' => $data['buttonLanguage'] ?? '',
+ protected function get_defaults() : array {
+ return array(
+ // Free-form string values.
+ 'invoice_prefix' => '',
+ 'brand_name' => '',
+ 'soft_descriptor' => '',
+
+ // Enum-type string values.
+ 'subtotal_adjustment' => 'skip_details', // Options: [correction|no_details].
+ 'landing_page' => 'any', // Options: [any|login|guest_checkout].
+ 'button_language' => '', // empty or a 2-letter language code.
+
+ // Boolean flags.
+ 'authorize_only' => false,
+ 'capture_virtual_orders' => false,
+ 'save_paypal_and_venmo' => false,
+ 'save_card_details' => false,
+ 'enable_pay_now' => false,
+ 'enable_logging' => false,
+
+ // Array of string values.
+ 'disabled_cards' => array(),
);
+ }
- $result = update_option( self::OPTION_NAME, $settings );
+ /**
+ * Gets the invoice prefix.
+ *
+ * @return string The invoice prefix.
+ */
+ public function get_invoice_prefix() : string {
+ return $this->data['invoice_prefix'];
+ }
- if ( ! $result ) {
- throw new RuntimeException( 'Failed to update settings' );
- }
+ /**
+ * Sets the invoice prefix.
+ *
+ * @param string $prefix The invoice prefix to set.
+ */
+ public function set_invoice_prefix( string $prefix ) : void {
+ $this->data['invoice_prefix'] = $this->sanitizer->sanitize_text( $prefix );
+ }
+
+ /**
+ * Gets the brand name.
+ *
+ * @return string The brand name.
+ */
+ public function get_brand_name() : string {
+ return $this->data['brand_name'];
+ }
+
+ /**
+ * Sets the brand name.
+ *
+ * @param string $name The brand name to set.
+ */
+ public function set_brand_name( string $name ) : void {
+ $this->data['brand_name'] = $this->sanitizer->sanitize_text( $name );
+ }
+
+ /**
+ * Gets the soft descriptor.
+ *
+ * @return string The soft descriptor.
+ */
+ public function get_soft_descriptor() : string {
+ return $this->data['soft_descriptor'];
+ }
+
+ /**
+ * Sets the soft descriptor.
+ *
+ * @param string $descriptor The soft descriptor to set.
+ */
+ public function set_soft_descriptor( string $descriptor ) : void {
+ $this->data['soft_descriptor'] = $this->sanitizer->sanitize_text( $descriptor );
+ }
+
+ /**
+ * Gets the subtotal adjustment setting.
+ *
+ * @return string The subtotal adjustment setting.
+ */
+ public function get_subtotal_adjustment() : string {
+ return $this->data['subtotal_adjustment'];
+ }
+
+ /**
+ * Sets the subtotal adjustment setting.
+ *
+ * @param string $adjustment The subtotal adjustment to set.
+ */
+ public function set_subtotal_adjustment( string $adjustment ) : void {
+ $this->data['subtotal_adjustment'] = $this->sanitizer->sanitize_enum( $adjustment, self::SUBTOTAL_ADJUSTMENT_OPTIONS );
+ }
+
+ /**
+ * Gets the landing page setting.
+ *
+ * @return string The landing page setting.
+ */
+ public function get_landing_page() : string {
+ return $this->data['landing_page'];
+ }
+
+ /**
+ * Sets the landing page setting.
+ *
+ * @param string $page The landing page to set.
+ */
+ public function set_landing_page( string $page ) : void {
+ $this->data['landing_page'] = $this->sanitizer->sanitize_enum( $page, self::LANDING_PAGE_OPTIONS );
+ }
+
+ /**
+ * Gets the button language setting.
+ *
+ * @return string The button language.
+ */
+ public function get_button_language() : string {
+ return $this->data['button_language'];
+ }
+
+ /**
+ * Sets the button language.
+ *
+ * @param string $language The button language to set.
+ */
+ public function set_button_language( string $language ) : void {
+ $this->data['button_language'] = $this->sanitizer->sanitize_text( $language );
+ }
+
+ /**
+ * Gets the authorize only setting.
+ *
+ * @return bool True if authorize only is enabled, false otherwise.
+ */
+ public function get_authorize_only() : bool {
+ return $this->data['authorize_only'];
+ }
+
+ /**
+ * Sets the authorize only setting.
+ *
+ * @param bool $authorize Whether to enable authorize only.
+ */
+ public function set_authorize_only( bool $authorize ) : void {
+ $this->data['authorize_only'] = $this->sanitizer->sanitize_bool( $authorize );
+ }
+
+ /**
+ * Gets the capture virtual orders setting.
+ *
+ * @return bool True if capturing virtual orders is enabled, false otherwise.
+ */
+ public function get_capture_virtual_orders() : bool {
+ return $this->data['capture_virtual_orders'];
+ }
+
+ /**
+ * Sets the capture virtual orders setting.
+ *
+ * @param bool $capture Whether to capture virtual orders.
+ */
+ public function set_capture_virtual_orders( bool $capture ) : void {
+ $this->data['capture_virtual_orders'] = $this->sanitizer->sanitize_bool( $capture );
+ }
+
+ /**
+ * Gets the save PayPal and Venmo setting.
+ *
+ * @return bool True if saving PayPal and Venmo is enabled, false otherwise.
+ */
+ public function get_save_paypal_and_venmo() : bool {
+ return $this->data['save_paypal_and_venmo'];
+ }
+
+ /**
+ * Sets the save PayPal and Venmo setting.
+ *
+ * @param bool $save Whether to save PayPal and Venmo.
+ */
+ public function set_save_paypal_and_venmo( bool $save ) : void {
+ $this->data['save_paypal_and_venmo'] = $this->sanitizer->sanitize_bool( $save );
+ }
+
+ /**
+ * Gets the save card details setting.
+ *
+ * @return bool True if saving card details is enabled, false otherwise.
+ */
+ public function get_save_card_details() : bool {
+ return $this->data['save_card_details'];
+ }
+
+ /**
+ * Sets the save card details setting.
+ *
+ * @param bool $save Whether to save card details.
+ */
+ public function set_save_card_details( bool $save ) : void {
+ $this->data['save_card_details'] = $this->sanitizer->sanitize_bool( $save );
+ }
+
+ /**
+ * Gets the enable Pay Now setting.
+ *
+ * @return bool True if Pay Now is enabled, false otherwise.
+ */
+ public function get_enable_pay_now() : bool {
+ return $this->data['enable_pay_now'];
+ }
+
+ /**
+ * Sets the enable Pay Now setting.
+ *
+ * @param bool $enable Whether to enable Pay Now.
+ */
+ public function set_enable_pay_now( bool $enable ) : void {
+ $this->data['enable_pay_now'] = $this->sanitizer->sanitize_bool( $enable );
+ }
+
+ /**
+ * Gets the enable logging setting.
+ *
+ * @return bool True if logging is enabled, false otherwise.
+ */
+ public function get_enable_logging() : bool {
+ return $this->data['enable_logging'];
+ }
+
+ /**
+ * Sets the enable logging setting.
+ *
+ * @param bool $enable Whether to enable logging.
+ */
+ public function set_enable_logging( bool $enable ) : void {
+ $this->data['enable_logging'] = $this->sanitizer->sanitize_bool( $enable );
+ }
+
+ /**
+ * Gets the disabled cards.
+ *
+ * @return array The array of disabled cards.
+ */
+ public function get_disabled_cards() : array {
+ return $this->data['disabled_cards'];
+ }
+
+ /**
+ * Sets the disabled cards.
+ *
+ * @param array $cards The array of cards to disable.
+ */
+ public function set_disabled_cards( array $cards ) : void {
+ $this->data['disabled_cards'] = array_map(
+ array( $this->sanitizer, 'sanitize_text' ),
+ $cards
+ );
}
}