mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-08 21:52:55 +08:00
Merge pull request #2909 from woocommerce/PCP-4028-fix-php-notices-related-to-settings-mapping
Fix PHP notices related to settings-mapping (4028)
This commit is contained in:
commit
10f251c73f
2 changed files with 144 additions and 46 deletions
|
@ -9,62 +9,149 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Compat;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* A helper for mapping the new/old settings.
|
||||
* A helper class to manage the transition between legacy and new settings.
|
||||
*
|
||||
* This utility provides mapping from old setting keys to new ones and retrieves
|
||||
* their corresponding values from the appropriate models. The class uses lazy
|
||||
* loading and caching to optimize performance during runtime.
|
||||
*/
|
||||
class SettingsMapHelper {
|
||||
|
||||
/**
|
||||
* A list of mapped settings.
|
||||
* A list of settings maps containing mapping definitions.
|
||||
*
|
||||
* @var SettingsMap[]
|
||||
*/
|
||||
protected array $settings_map;
|
||||
|
||||
/**
|
||||
* Indexed map for faster lookups, initialized lazily.
|
||||
*
|
||||
* @var array|null Associative array where old keys map to metadata.
|
||||
*/
|
||||
protected ?array $key_to_model = null;
|
||||
|
||||
/**
|
||||
* Cache for results of `to_array()` calls on models.
|
||||
*
|
||||
* @var array Associative array where keys are model IDs.
|
||||
*/
|
||||
protected array $model_cache = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param SettingsMap[] $settings_map A list of mapped settings.
|
||||
* @param SettingsMap[] $settings_map A list of settings maps containing key definitions.
|
||||
* @throws RuntimeException When an old key has multiple mappings.
|
||||
*/
|
||||
public function __construct( array $settings_map ) {
|
||||
$this->validate_settings_map( $settings_map );
|
||||
$this->settings_map = $settings_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the mapped value from the new settings.
|
||||
* Validates the settings map for duplicate keys.
|
||||
*
|
||||
* @param string $key The key.
|
||||
* @return ?mixed the mapped value or Null if it doesn't exist.
|
||||
* @param SettingsMap[] $settings_map The settings map to validate.
|
||||
* @throws RuntimeException When an old key has multiple mappings.
|
||||
*/
|
||||
public function mapped_value( string $key ) {
|
||||
if ( ! $this->has_mapped_key( $key ) ) {
|
||||
return null;
|
||||
}
|
||||
protected function validate_settings_map( array $settings_map ) : void {
|
||||
$seen_keys = array();
|
||||
|
||||
foreach ( $this->settings_map as $settings_map ) {
|
||||
$mapped_key = array_search( $key, $settings_map->get_map(), true );
|
||||
$new_settings = $settings_map->get_model()->to_array();
|
||||
if ( ! empty( $new_settings[ $mapped_key ] ) ) {
|
||||
return $new_settings[ $mapped_key ];
|
||||
foreach ( $settings_map as $settings_map_instance ) {
|
||||
foreach ( $settings_map_instance->get_map() as $old_key => $new_key ) {
|
||||
if ( isset( $seen_keys[ $old_key ] ) ) {
|
||||
throw new RuntimeException( "Duplicate mapping for legacy key '$old_key'." );
|
||||
}
|
||||
$seen_keys[ $old_key ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given key exists in the new settings.
|
||||
* Retrieves the value of a mapped key from the new settings.
|
||||
*
|
||||
* @param string $key The key.
|
||||
* @return bool true if the given key exists in the new settings, otherwise false.
|
||||
* @param string $old_key The key from the legacy settings.
|
||||
*
|
||||
* @return mixed|null The value of the mapped setting, or null if not found.
|
||||
*/
|
||||
public function has_mapped_key( string $key ) : bool {
|
||||
foreach ( $this->settings_map as $settings_map ) {
|
||||
if ( in_array( $key, $settings_map->get_map(), true ) ) {
|
||||
return true;
|
||||
public function mapped_value( string $old_key ) {
|
||||
$this->ensure_map_initialized();
|
||||
|
||||
if ( ! isset( $this->key_to_model[ $old_key ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$mapping = $this->key_to_model[ $old_key ];
|
||||
$model_id = spl_object_id( $mapping['model'] );
|
||||
|
||||
return $this->get_cached_model_value( $model_id, $mapping['new_key'], $mapping['model'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given legacy key exists in the new settings.
|
||||
*
|
||||
* @param string $old_key The key from the legacy settings.
|
||||
*
|
||||
* @return bool True if the key exists in the new settings, false otherwise.
|
||||
*/
|
||||
public function has_mapped_key( string $old_key ) : bool {
|
||||
$this->ensure_map_initialized();
|
||||
|
||||
return isset( $this->key_to_model[ $old_key ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a cached model value or caches it if not already cached.
|
||||
*
|
||||
* @param int $model_id The unique identifier for the model object.
|
||||
* @param string $new_key The key in the new settings structure.
|
||||
* @param object $model The model object.
|
||||
*
|
||||
* @return mixed|null The value of the key in the model, or null if not found.
|
||||
*/
|
||||
protected function get_cached_model_value( int $model_id, string $new_key, object $model ) {
|
||||
if ( ! isset( $this->model_cache[ $model_id ] ) ) {
|
||||
$this->model_cache[ $model_id ] = $model->to_array();
|
||||
}
|
||||
|
||||
return $this->model_cache[ $model_id ][ $new_key ] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the map of old-to-new settings is initialized.
|
||||
*
|
||||
* This method initializes the `key_to_model` array lazily to improve performance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function ensure_map_initialized() : void {
|
||||
if ( $this->key_to_model === null ) {
|
||||
$this->initialize_key_map();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
/**
|
||||
* Initializes the indexed map of old-to-new settings keys.
|
||||
*
|
||||
* This method processes the provided settings maps and indexes the legacy
|
||||
* keys to their corresponding metadata for efficient lookup.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize_key_map() : void {
|
||||
$this->key_to_model = array();
|
||||
|
||||
foreach ( $this->settings_map as $settings_map_instance ) {
|
||||
foreach ( $settings_map_instance->get_map() as $old_key => $new_key ) {
|
||||
$this->key_to_model[ $old_key ] = array(
|
||||
'new_key' => $new_key,
|
||||
'model' => $settings_map_instance->get_model(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
|||
class Settings implements ContainerInterface {
|
||||
|
||||
const KEY = 'woocommerce-ppcp-settings';
|
||||
|
||||
const CONNECTION_TAB_ID = 'ppcp-connection';
|
||||
|
||||
const PAY_LATER_TAB_ID = 'ppcp-pay-later';
|
||||
|
||||
/**
|
||||
|
@ -27,35 +29,35 @@ class Settings implements ContainerInterface {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
private $settings = array();
|
||||
private array $settings = array();
|
||||
|
||||
/**
|
||||
* The list of selected default button locations.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $default_button_locations;
|
||||
protected array $default_button_locations;
|
||||
|
||||
/**
|
||||
* The list of selected default pay later button locations.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $default_pay_later_button_locations;
|
||||
protected array $default_pay_later_button_locations;
|
||||
|
||||
/**
|
||||
* The list of selected default pay later messaging locations.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $default_pay_later_messaging_locations;
|
||||
protected array $default_pay_later_messaging_locations;
|
||||
|
||||
/**
|
||||
* The default ACDC gateway title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $default_dcc_gateway_title;
|
||||
protected string $default_dcc_gateway_title;
|
||||
|
||||
/**
|
||||
* A helper for mapping the new/old settings.
|
||||
|
@ -67,11 +69,17 @@ class Settings implements ContainerInterface {
|
|||
/**
|
||||
* Settings constructor.
|
||||
*
|
||||
* @param string[] $default_button_locations The list of selected default button locations.
|
||||
* @param string $default_dcc_gateway_title The default ACDC gateway title.
|
||||
* @param string[] $default_pay_later_button_locations The list of selected default pay later button locations.
|
||||
* @param string[] $default_pay_later_messaging_locations The list of selected default pay later messaging locations.
|
||||
* @param SettingsMapHelper $settings_map_helper A helper for mapping the new/old settings.
|
||||
* @param string[] $default_button_locations The list of selected default
|
||||
* button locations.
|
||||
* @param string $default_dcc_gateway_title The default ACDC gateway
|
||||
* title.
|
||||
* @param string[] $default_pay_later_button_locations The list of selected default
|
||||
* pay later button locations.
|
||||
* @param string[] $default_pay_later_messaging_locations The list of selected default
|
||||
* pay later messaging
|
||||
* locations.
|
||||
* @param SettingsMapHelper $settings_map_helper A helper for mapping the
|
||||
* new/old settings.
|
||||
*/
|
||||
public function __construct(
|
||||
array $default_button_locations,
|
||||
|
@ -90,10 +98,11 @@ class Settings implements ContainerInterface {
|
|||
/**
|
||||
* Returns the value for an id.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
* @throws NotFoundException When nothing was found.
|
||||
*
|
||||
* @param string $id The value identifier.
|
||||
*
|
||||
* @return mixed
|
||||
* @throws NotFoundException When nothing was found.
|
||||
*/
|
||||
public function get( $id ) {
|
||||
if ( ! $this->has( $id ) ) {
|
||||
|
@ -106,23 +115,24 @@ class Settings implements ContainerInterface {
|
|||
/**
|
||||
* Whether a value exists.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
* @param string $id The value identifier.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has( $id ) {
|
||||
public function has( string $id ) {
|
||||
if ( $this->settings_map_helper->has_mapped_key( $id ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->load();
|
||||
|
||||
return array_key_exists( $id, $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value.
|
||||
*
|
||||
* @param string $id The value identificator.
|
||||
* @param string $id The value identifier.
|
||||
* @param mixed $value The value.
|
||||
*/
|
||||
public function set( $id, $value ) {
|
||||
|
@ -175,6 +185,7 @@ class Settings implements ContainerInterface {
|
|||
}
|
||||
$this->settings[ $key ] = $value;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue