这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@iamdharmesh
Copy link
Contributor

@iamdharmesh iamdharmesh commented Jul 25, 2025

Summary

This PR fixes deprecation warnings in PHP 8.2 caused by dynamic properties set on the WC_Order object. It introduces a Dynamic_Props class to handle dynamic properties using WeakMap for PHP 8.0 and above, while continuing to set dynamic properties directly on the $order object for PHP versions below 8.0.

Closes #781

Details

This PR introduces a new Dynamic_Props class to manage dynamic property storage for WooCommerce order objects. The changes ensure compatibility with PHP 8.2+, where dynamic properties are deprecated, while maintaining backwards compatibility with PHP 7.4+. The updates replace direct property access with the Dynamic_Props class in various payment gateway handlers and classes.

Key Changes

Introduction of the Dynamic_Props Class

  • Added a new Dynamic_Props class in woocommerce/payment-gateway/Dynamic_Props.php to handle dynamic property storage using WeakMap for PHP 8.0+ and fallback mechanisms for PHP 7.4+. This includes methods for setting, getting, and unsetting dynamic properties on order objects.

Updates to Various Classes

  • Updated several classes to use Dynamic_Props for handling payment-related properties, replacing direct object property access (e.g., payment->token, payment->account_number) with Dynamic_Props::get() and Dynamic_Props::set().

Note

I have evaluated different approaches from "Approach 4", keeping in mind that plugins using this framework should require minimal changes when upgrading to the new version. Based on that, I have proceeded with this approach. However, I’m open to discussing and implementing other approaches if you believe they offer advantages over this one.

Upgrade Guide

Upgrading to v6.0.0

This guide helps you upgrade your payment gateway plugin from v5.x.x to v6.0.0.

Dynamic Properties Management

Starting with v6.0.0, we've introduced a new way to handle dynamic properties on WooCommerce order objects to address PHP 8.2 deprecation warnings. This change is opt-in, meaning you can choose when to adopt the new approach.

Background

In PHP 8.2, setting dynamic properties on objects is deprecated. This affects how we store custom data on WooCommerce order objects. To future-proof our codebase, we've introduced a new Dynamic_Props class that provides a standardized way to handle these properties.

Opting In

By default, the framework continues to use the legacy approach (directly setting properties on order objects). To opt into the new approach:

add_filter( 'sv_wc_plugin_framework_use_dynamic_props_class', '__return_true' );

Required Changes

Once opted in, you'll need to update how you get and set dynamic properties on order objects. Here are the common properties that need updating:

Common Dynamic Properties

  • customer_id
  • payment
  • payment_total
  • description
  • capture
  • refund
  • unique_transaction_ref

Before (Legacy Approach)

// Setting properties
$order->customer_id = $customer_id;
$order->payment = $payment_object;
$order->payment_total = $total;
$order->custom_prop = $custom_prop;

// Getting properties
$customer_id = $order->customer_id;
$payment = $order->payment;
$total = $order->payment_total;
$custom_prop = $order->custom_prop;

After (New Approach)

use SkyVerge\WooCommerce\PluginFramework\v6_0_0\Helpers\OrderHelper;

// Setting properties using OrderHelper.
OrderHelper::set_customer_id( $order, $customer_id );
OrderHelper::set_payment( $order, $payment_object );
OrderHelper::set_payment_total( $order, $total );
OrderHelper::set_property( $order, $custom_prop );

// Getting properties using OrderHelper.
$customer_id = OrderHelper::get_customer_id( $order );
$payment = OrderHelper::get_payment( $order );
$total = OrderHelper::get_payment_total( $order );
$custom_prop = OrderHelper::get_property( $order, 'custom_prop' );

// Alternative: Using Dynamic_Props directly
use SkyVerge\WooCommerce\PluginFramework\v6_0_0\Payment_Gateway\Dynamic_Props;

Dynamic_Props::set( $order, 'customer_id', $customer_id );
Dynamic_Props::get( $order, 'customer_id' );

Example

Here's a complete example of migrating a payment processing method:

// Before
public function process_payment( $order ) {
    $order->customer_id = $this->get_customer_id();
    $order->payment = new stdClass();
    $order->payment->token = $token;
    $amount = $order->payment_total;
  
    // ...
 }

// After
public function process_payment( $order ) {
    OrderHelper::set_customer_id( $order, $this->get_customer_id() );
    $payment = new stdClass();
    $payment->token = $token;
    OrderHelper::set_payment( $order, $payment );
    $amount = OrderHelper::get_payment_total( $order );
    
    // ...
}

Compatibility Notes

  • This change is compatible with PHP 7.4 and above
  • For PHP versions below 8.0, the framework automatically falls back to the legacy approach even when opted in
  • The legacy approach will continue to work but will generate deprecation notices in PHP 8.2+

Additional Resources

UI Changes

N/A

QA

Setup

  1. Upgrade plugin framework to this PR branch in any actual payment gateway plugin or test plugin
  2. Install and activate it in WP

Steps

Run Following tests with PHP 8.2+ and PHP 7.4:

  1. Configure the Payment gateway plugin
  2. And test the following scenarios and verify that it works well without any issue
    • Place order with simple/variable product (without "Save payment method" checkbox checked)
    • Place order with simple/variable product with "Save payment method" checkbox checked
    • Place order with saved payment method
    • Add payment method to my account
    • Place order with "Authorization" enabled and collect charge later (Capture)
    • Refund order
    • Signup to Subscription
      • Process renewal
      • Early renewal
      • Change Payment method
    • Place order using pre-orders product (Upfront/upon release)
      • For upon release verify payment process without issue on release
  • Verify that, while running the tests listed above, no deprecation warnings reported for dynamic properties.
  • Code review

Before merge

  • I have confirmed these changes in each supported minor WooCommerce version

@iamdharmesh iamdharmesh changed the title [WIP] Fix PHP 8.2 deprecation warnings caused by dynamic properties on the $order object Fix PHP 8.2 deprecation warnings caused by dynamic properties on the $order object Jul 28, 2025
@iamdharmesh iamdharmesh marked this pull request as ready for review July 28, 2025 10:40
@agibson-godaddy
Copy link
Contributor

agibson-godaddy commented Aug 7, 2025

Hey sorry I haven't had a chance to get to this yet. Just noting that I did start testing it with Authorize.net, but unfortunately that particular code base is riddled with bits that require migrating to the new Dynamic_Props and I didn't have time to update everything to complete a test properly.

Just noting that due to what I was seeing, we will have to put this change in a major framework release, which is fine, but just making a note of it. Because we stop setting the props dynamically completely it breaks any integration that hasn't gone through all the updates.


Some minor feedback as I glance through what updates would be required: it would be nice to add a new helper method to the framework specifically to get the order payment. As in: some kind of OrderHelper::getPayment(WC_Order $order) -- this would then basically just return Dynamic_Props::get( $order, 'payment', null, new \stdClass() );.

But it would save some repetition and abstract things out a bit nicely for gateways.

@agibson-godaddy agibson-godaddy changed the base branch from master to release/6.0.0 August 7, 2025 20:15
@agibson-godaddy agibson-godaddy mentioned this pull request Aug 7, 2025
5 tasks
@agibson-godaddy
Copy link
Contributor

Having a list of properties that gateways need to update will be helpful for the upgrade guide:

On order object:

  • customer_id
  • payment
  • payment_total

@agibson-godaddy
Copy link
Contributor

Just thinking about this some more... I wonder if it's possible to make the new behaviour opt-in (for a while) in order to maintain backwards compatibility and remove the need to put this into a major release.

I'm thinking:

  • If the gateway hasn't opted in then we could use the old, deprecated method. (Perhaps still handle this in the DynamicProps class?)
    • We could also trigger a deprecation warning, or perhaps not yet but add it in the future.
  • If the gateway has opted in then we could use the new method.

@iamdharmesh
Copy link
Contributor Author

Hi @agibson-godaddy, Thanks for checking on this and sharing thoughts here.

Just thinking about this some more... I wonder if it's possible to make the new behaviour opt-in (for a while) in order to maintain backwards compatibility and remove the need to put this into a major release.

Yes, we can do this. In Dynamic_Props class we are using the backward compatible approach, means WeakMap approach only used when it is available otherwise it keep setting up props on order object directly. So, for opt-in based approach we can just add one more method there with filter to enable the new method. otherwise it will keep using the old approach.

Just noting that I did start testing it with Authorize.net, but unfortunately that particular code base is riddled with bits that require migrating to the new Dynamic_Props and I didn't have time to update everything to complete a test properly.

Yes, need to update the codebase to test this. I did updated the braintree codebase to test and validate this. However, once we make this opt-in based you will be able to test it directly.

it would be nice to add a new helper method to the framework specifically to get the order payment. As in: some kind of OrderHelper::getPayment(WC_Order $order) -- this would then basically just return Dynamic_Props::get( $order, 'payment', null, new \stdClass() );.

👍

I'm out next week, but I’ll try to make these changes once I get some time to work on them. Thanks!

@agibson-godaddy
Copy link
Contributor

Thanks @iamdharmesh !

Yes, need to update the codebase to test this. I did updated the braintree codebase to test and validate this. However, once we make this opt-in based you will be able to test it directly.

Just an update that I did finally get it updated enough to do some very light testing (regular transaction only) and it worked!

@iamdharmesh
Copy link
Contributor Author

Hi @agibson-godaddy 👋,

I’ve made this opt-in only, and developers now need to use a filter to opt in. I also added an OrderHelper class to simplify getting/setting common props and included an upgrade guide in the PR description. Could you please review this once?

Thanks!

@vikrampm1
Copy link

@agibson-godaddy following up here to see if you can help review the above. Thanks!

@agibson-godaddy
Copy link
Contributor

Sorry folks -- I'll get to it as soon as I can! Will try to take a look this week.

@agibson-godaddy
Copy link
Contributor

agibson-godaddy commented Sep 18, 2025

QA

  • Tested a gateway upgrading to this branch, without using the filter. Behaviour is as before.
  • Tested a gateway upgrading to this branch, with using the filter to opt-in.

@agibson-godaddy
Copy link
Contributor

I think this is all working nicely for me. Have you folks also tested this in your own integration(s)?

@iamdharmesh
Copy link
Contributor Author

Thanks @agibson-godaddy

Have you folks also tested this in your own integration(s)?

Yes, I have tested this with Braintree extension (with and without opt-in) and it's working fine.

Copy link
Contributor

@agibson-godaddy agibson-godaddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to merge this into the release branch, but we'll need to work on an upgrade guide before we can make the release official.

Thanks so much for your work on this @iamdharmesh ! It's hugely appreciated.

@agibson-godaddy agibson-godaddy merged commit 531f046 into godaddy-wordpress:release/6.0.0 Sep 19, 2025
5 checks passed
@iamdharmesh
Copy link
Contributor Author

Thanks for merging this @agibson-godaddy.

but we'll need to work on an upgrade guide before we can make the release official.

I’ve added a short version of the Upgrade Guide in PR description, but I’m happy to include more details, add any specific points you’d like, or update anything as needed.

@vikrampm1
Copy link

Hi @agibson-godaddy any ETA on when this will get released?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PHP 8.2 deprecation warnings due to dynamic properties on the Order

3 participants