Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions woocommerce/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*** SkyVerge WooCommerce Plugin Framework Changelog ***

2026.nn.nn - version 6.1.3
* Fix - Move WeakMap initialization to PHP 8.2+ only, as there are some bugs with it in certain versions of PHP 8.0.x and 8.1.x.

2026.03.25 - version 6.1.2
* Fix - Unhandled WeakMap exceptions in Dynamic_Props.
Expand Down
38 changes: 21 additions & 17 deletions woocommerce/payment-gateway/Dynamic_Props.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* while maintaining backwards compatibility with PHP 7.4+.
*
* @package SkyVerge/WooCommerce/Payment-Gateway/Classes
* @since x.x.x
* @since 6.0.0
*/

namespace SkyVerge\WooCommerce\PluginFramework\v6_1_3\Payment_Gateway;
Expand All @@ -16,10 +16,10 @@
*
* This class provides a way to store dynamic properties on order objects without using
* dynamic properties (deprecated in PHP 8.2+) while maintaining backwards compatibility
* with PHP 7.4+. It uses WeakMap for PHP 8.0+ and falls back to dynamic properties
* for PHP 7.4+.
* with PHP 7.4+. It uses WeakMap for PHP 8.2+ and falls back to dynamic properties
* for PHP versions prior to 8.2 (for example, PHP 7.4, 8.0, and 8.1).
*
* @since x.x.x
* @since 6.0.0
*
* @example
* ```php
Expand All @@ -34,27 +34,27 @@
*/
class Dynamic_Props {
/**
* Storage container for dynamic properties using WeakMap in PHP 8.0+.
* Storage container for dynamic properties using WeakMap in PHP 8.2+.
*
* Uses WeakMap to store properties without memory leaks, as WeakMap allows garbage
* collection of its keys when they're no longer referenced elsewhere.
*
* @since x.x.x
* @since 6.0.0
* @var \WeakMap<object, \stdClass>|null
*/
private static ?\WeakMap $map = null; // phpcs:ignore PHPCompatibility.Classes.NewClasses.weakmapFound -- conditionally used for PHP 8.0+
private static ?\WeakMap $map = null; // phpcs:ignore PHPCompatibility.Classes.NewClasses.weakmapFound -- conditionally used for PHP 8.2+

/** @var bool|null Cached result for whether to use WeakMap storage. */
private static ?bool $use_weak_map = null;

/**
* Sets a property on the order object.
*
* Stores a dynamic property either using WeakMap (PHP 8.0+) or direct property
* Stores a dynamic property either using WeakMap (PHP 8.2+) or direct property
* access (PHP 7.4+). The storage method is automatically determined based on
* PHP version and WeakMap availability.
*
* @since x.x.x
* @since 6.0.0
*
* @param \WC_Order $order The order object to store data on.
* @param string $key The property key.
Expand Down Expand Up @@ -85,7 +85,7 @@ public static function set( \WC_Order &$order, string $key, $value ): void {
* Retrieves a stored dynamic property using the appropriate storage method
* based on PHP version. Supports nested property access.
*
* @since x.x.x
* @since 6.0.0
*
* @param \WC_Order $order The order object to retrieve data from.
* @param string $key The property key.
Expand Down Expand Up @@ -125,7 +125,7 @@ public static function get( \WC_Order $order, string $key, $nested_key = null, $
* Removes a stored dynamic property using the appropriate storage method
* based on PHP version.
*
* @since x.x.x
* @since 6.0.0
*
* @param \WC_Order $order The order object to unset data from.
* @param string $key The property key to remove.
Expand Down Expand Up @@ -153,7 +153,7 @@ protected static function use_dynamic_props_class(): bool {
/**
* Filters whether to use Dynamic_Props class for storing order data.
*
* @since x.x.x
* @since 6.0.0
*
* @var bool Whether to Dynamic_Props class for storing order data.
*/
Expand All @@ -165,15 +165,19 @@ protected static function use_dynamic_props_class(): bool {
/**
* Checks if WeakMap should be used based on PHP version.
*
* Determines whether to use WeakMap storage based on PHP version (8.0+)
* Determines whether to use WeakMap storage based on PHP version (8.2+)
* and WeakMap class availability. Result is cached for performance.
*
* @since x.x.x
* @NOTE: We specifically target PHP 8.2+ here, even though WeakMap is available in 8.0+, because there is at least one
* WeakMap bug in older versions of PHP (8.0.x and 8.1.x) that can trigger fatal errors. This is fully resolved in PHP 8.2+.
* @link https://github.com/php/php-src/pull/8995
*
* @since 6.0.0
* @return bool True if WeakMap should be used, false otherwise.
*/
private static function use_weak_map(): bool {
if ( null === self::$use_weak_map ) {
self::$use_weak_map = version_compare( PHP_VERSION, '8.0', '>=' ) && self::use_dynamic_props_class();
self::$use_weak_map = version_compare( PHP_VERSION, '8.2', '>=' ) && self::use_dynamic_props_class();
}

return self::$use_weak_map;
Expand All @@ -185,12 +189,12 @@ private static function use_weak_map(): bool {
* Ensures the WeakMap storage is initialized only once when needed.
* This lazy initialization helps with performance and memory usage.
*
* @since x.x.x
* @since 6.0.0
* @return void
*/
private static function init_weak_map(): void {
if ( null === self::$map ) {
// phpcs:ignore PHPCompatibility.Classes.NewClasses.weakmapFound -- conditionally used for PHP 8.0+
// phpcs:ignore PHPCompatibility.Classes.NewClasses.weakmapFound -- conditionally used for PHP 8.2+
self::$map = new \WeakMap();
}
}
Expand Down