Extract sanitizer logic to new service

This commit is contained in:
Philipp Stracker 2025-01-17 18:40:43 +01:00
parent 72d84546d1
commit 57afe4b95e
No known key found for this signature in database
3 changed files with 130 additions and 42 deletions

View file

@ -26,6 +26,7 @@ use WooCommerce\PayPalCommerce\Settings\Service\OnboardingUrlManager;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\Settings\Endpoint\StylingRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Data\StylingSettings;
use WooCommerce\PayPalCommerce\Settings\Service\DataSanitizer;
return array(
'settings.url' => static function ( ContainerInterface $container ) : string {
@ -76,7 +77,10 @@ return array(
return new CommonRestEndpoint( $container->get( 'settings.data.general' ) );
},
'settings.rest.styling' => static function ( ContainerInterface $container ) : StylingRestEndpoint {
return new StylingRestEndpoint( $container->get( 'settings.data.styling' ) );
return new StylingRestEndpoint(
$container->get( 'settings.data.styling' ),
$container->get( 'settings.service.sanitizer' )
);
},
'settings.rest.refresh_feature_status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint {
return new RefreshFeatureStatusEndpoint(
@ -195,6 +199,9 @@ return array(
$container->get( 'woocommerce.logger.woocommerce' ),
);
},
'settings.service.sanitizer' => static function ( ContainerInterface $container ) : DataSanitizer {
return new DataSanitizer();
},
'settings.ajax.switch_ui' => static function ( ContainerInterface $container ) : SwitchSettingsUiEndpoint {
return new SwitchSettingsUiEndpoint(
$container->get( 'woocommerce.logger.woocommerce' ),

View file

@ -14,6 +14,7 @@ use WP_REST_Response;
use WP_REST_Request;
use WooCommerce\PayPalCommerce\Settings\Data\StylingSettings;
use WooCommerce\PayPalCommerce\Settings\DTO\LocationStylingDTO;
use WooCommerce\PayPalCommerce\Settings\Service\DataSanitizer;
/**
* REST controller for the "Styling" settings tab.
@ -36,6 +37,13 @@ class StylingRestEndpoint extends RestEndpoint {
*/
protected StylingSettings $settings;
/**
* Data sanitizer service.
*
* @var DataSanitizer
*/
protected DataSanitizer $sanitizer;
/**
* Field mapping for request to profile transformation.
*
@ -62,16 +70,33 @@ class StylingRestEndpoint extends RestEndpoint {
/**
* Constructor.
*
* @param StylingSettings $settings The settings instance.
* @param StylingSettings $settings The settings instance.
* @param DataSanitizer $sanitizer Data sanitizer service.
*/
public function __construct( StylingSettings $settings ) {
$this->settings = $settings;
public function __construct( StylingSettings $settings, DataSanitizer $sanitizer ) {
$this->settings = $settings;
$this->sanitizer = $sanitizer;
$this->field_map['cart']['sanitize'] = array( $this, 'to_location' );
$this->field_map['classic_checkout']['sanitize'] = array( $this, 'to_location' );
$this->field_map['express_checkout']['sanitize'] = array( $this, 'to_location' );
$this->field_map['mini_cart']['sanitize'] = array( $this, 'to_location' );
$this->field_map['product']['sanitize'] = array( $this, 'to_location' );
$this->field_map['cart']['sanitize'] = array(
$this->sanitizer,
'sanitize_location_style',
);
$this->field_map['classic_checkout']['sanitize'] = array(
$this->sanitizer,
'sanitize_location_style',
);
$this->field_map['express_checkout']['sanitize'] = array(
$this->sanitizer,
'sanitize_location_style',
);
$this->field_map['mini_cart']['sanitize'] = array(
$this->sanitizer,
'sanitize_location_style',
);
$this->field_map['product']['sanitize'] = array(
$this->sanitizer,
'sanitize_location_style',
);
}
/**
@ -142,37 +167,4 @@ class StylingRestEndpoint extends RestEndpoint {
return $this->get_details();
}
/**
* Converts the plain location-style input to a structured DTO.
*
* @param array $data Raw data received from the request.
* @param string $key The field name.
*
* @return LocationStylingDTO
*/
protected function to_location( array $data, string $key ) : LocationStylingDTO {
$is_enabled = ! isset( $data['enabled'] ) || $data['enabled'];
$methods = array();
$shape = sanitize_text_field( $data['shape'] ?? 'rect' );
$label = sanitize_text_field( $data['label'] ?? 'pay' );
$color = sanitize_text_field( $data['color'] ?? 'gold' );
$layout = sanitize_text_field( $data['layout'] ?? 'vertical' );
$tagline = isset( $data['tagline'] ) && $data['tagline'];
if ( isset( $data['methods'] ) && is_array( $data['methods'] ) ) {
$methods = array_map( 'sanitize_text_field', $data['methods'] );
}
return new LocationStylingDTO(
$key,
$is_enabled,
$methods,
$shape,
$label,
$color,
$layout,
$tagline,
);
}
}

View file

@ -0,0 +1,89 @@
<?php
/**
* Provides data sanitization logic.
*
* @package WooCommerce\PayPalCommerce\Settings\Service
*/
declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Settings\Service;
use WooCommerce\PayPalCommerce\Settings\DTO\LocationStylingDTO;
/**
* DataSanitizer service. Generally used by REST endpoints (sanitize input data)
* and data models (sanitize data during DB access)
*/
class DataSanitizer {
/**
* Sanitizes the provided styling data.
*
* @param array $data The styling data to sanitize.
* @param ?string $location Name of the location.
* @return LocationStylingDTO Styling data.
*/
public function sanitize_location_style( array $data, string $location = null ) : LocationStylingDTO {
if ( null === $location ) {
$location = $data['location'] ?? '';
}
$is_enabled = $this->sanitize_bool( $data['enabled'] ?? true );
$shape = $this->sanitize_text( $data['shape'] ?? 'rect' );
$label = $this->sanitize_text( $data['label'] ?? 'pay' );
$color = $this->sanitize_text( $data['color'] ?? 'gold' );
$layout = $this->sanitize_text( $data['layout'] ?? 'vertical' );
$tagline = $this->sanitize_bool( $data['tagline'] ?? false );
$methods = $this->sanitize_array(
$data['methods'] ?? array(),
array( $this, 'sanitize_text' )
);
return new LocationStylingDTO(
$location,
$is_enabled,
$methods,
$shape,
$label,
$color,
$layout,
$tagline
);
}
/**
* Helper. Ensures the value is a string.
*
* @param mixed $value Value to sanitize.
* @param string $default Default value.
* @return string Sanitized string.
*/
protected function sanitize_text( $value, string $default = '' ) : string {
return sanitize_text_field( $value ?? $default );
}
/**
* Helper. Ensures the value is a boolean.
*
* @param mixed $value Value to sanitize.
* @return bool Sanitized boolean.
*/
protected function sanitize_bool( $value ) : bool {
return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
}
/**
* Helper. Ensures the value is an array and all items are sanitized.
*
* @param null|array $array Value to sanitize.
* @param callable $sanitize_callback Callback to sanitize each item in the array.
* @return array Array with sanitized items.
*/
protected function sanitize_array( ?array $array, callable $sanitize_callback ) : array {
if ( ! is_array( $array ) ) {
return array();
}
return array_map( $sanitize_callback, $array );
}
}