Commit 3e2ea932815 for woocommerce
commit 3e2ea932815aa6d06e6d816c7e311d11b818f501
Author: Asim Sulehria <de.asimhabib@gmail.com>
Date: Sun Oct 25 07:30:23 2026 +0500
Fix fatal errors from unchecked null returns in cart, coupon, and download functions (#65374)
---------
Co-authored-by: Darren Ethier <darren@roughsmootheng.in>
diff --git a/plugins/woocommerce/changelog/65374-null-safety-guards b/plugins/woocommerce/changelog/65374-null-safety-guards
new file mode 100644
index 00000000000..deacaed96ae
--- /dev/null
+++ b/plugins/woocommerce/changelog/65374-null-safety-guards
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prevent fatal errors in the cart, coupons, and download permissions when a product, parent product, or category was deleted.
diff --git a/plugins/woocommerce/includes/class-wc-cart.php b/plugins/woocommerce/includes/class-wc-cart.php
index e846548bbc9..bff0e8d4dce 100644
--- a/plugins/woocommerce/includes/class-wc-cart.php
+++ b/plugins/woocommerce/includes/class-wc-cart.php
@@ -1232,6 +1232,10 @@ class WC_Cart extends WC_Legacy_Cart {
$missing_attributes = array();
$parent_data = wc_get_product( $product_data->get_parent_id() );
+ if ( ! $parent_data instanceof WC_Product ) {
+ throw new Exception( __( 'Sorry, this product cannot be added to the cart.', 'woocommerce' ) );
+ }
+
$variation_attributes = $product_data->get_variation_attributes();
// Filter out 'any' variations, which are empty, as they need to be explicitly specified while adding to cart.
$variation_attributes = array_filter( $variation_attributes, 'wc_array_filter_default_attributes' );
diff --git a/plugins/woocommerce/includes/class-wc-coupon.php b/plugins/woocommerce/includes/class-wc-coupon.php
index 153c1260670..0408645ce1c 100644
--- a/plugins/woocommerce/includes/class-wc-coupon.php
+++ b/plugins/woocommerce/includes/class-wc-coupon.php
@@ -1267,8 +1267,10 @@ class WC_Coupon extends WC_Legacy_Coupon {
if ( count( $intersect ) > 0 ) {
foreach ( $intersect as $cat_id ) {
- $cat = get_term( $cat_id, 'product_cat' );
- $categories[] = $cat->name;
+ $cat = get_term( $cat_id, 'product_cat' );
+ if ( $cat instanceof WP_Term ) {
+ $categories[] = $cat->name;
+ }
}
}
}
diff --git a/plugins/woocommerce/includes/wc-order-functions.php b/plugins/woocommerce/includes/wc-order-functions.php
index 84192d84177..3e0b5a6ace7 100644
--- a/plugins/woocommerce/includes/wc-order-functions.php
+++ b/plugins/woocommerce/includes/wc-order-functions.php
@@ -434,6 +434,9 @@ function wc_downloadable_file_permission( $download_id, $product, $order, $qty =
if ( is_numeric( $product ) ) {
$product = wc_get_product( $product );
}
+ if ( ! $product instanceof WC_Product ) {
+ return false;
+ }
$download = new WC_Customer_Download();
$download->set_download_id( $download_id );
$download->set_product_id( $product->get_id() );
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 56a1883b23b..1a9f9d68b36 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -10098,12 +10098,6 @@ parameters:
count: 1
path: includes/class-wc-cart.php
- -
- message: '#^Cannot call method get_attributes\(\) on WC_Product\|false\|null\.$#'
- identifier: method.nonObject
- count: 2
- path: includes/class-wc-cart.php
-
-
message: '#^Method WC_Cart\:\:check_cart_items\(\) has no return type specified\.$#'
identifier: missingType.return
@@ -10626,12 +10620,6 @@ parameters:
count: 1
path: includes/class-wc-coupon.php
- -
- message: '#^Cannot access property \$name on WP_Error\|WP_Term\|null\.$#'
- identifier: property.nonObject
- count: 1
- path: includes/class-wc-coupon.php
-
-
message: '#^Method WC_Coupon\:\:get_short_info\(\) should return string but returns string\|false\.$#'
identifier: return.type
@@ -33891,24 +33879,6 @@ parameters:
count: 1
path: includes/wc-order-functions.php
- -
- message: '#^Cannot call method get_download_expiry\(\) on WC_Product\|false\|null\.$#'
- identifier: method.nonObject
- count: 1
- path: includes/wc-order-functions.php
-
- -
- message: '#^Cannot call method get_download_limit\(\) on WC_Product\|false\|null\.$#'
- identifier: method.nonObject
- count: 2
- path: includes/wc-order-functions.php
-
- -
- message: '#^Cannot call method get_id\(\) on WC_Product\|false\|null\.$#'
- identifier: method.nonObject
- count: 1
- path: includes/wc-order-functions.php
-
-
message: '#^Cannot call method get_total\(\) on WC_Order\|WC_Order_Refund\|false\.$#'
identifier: method.nonObject