Skip to content

fix(wc-memberships): skip expiry filter for non-subscription memberships#4743

Open
adekbadek wants to merge 1 commit into
trunkfrom
hotfix/membership-expiry-non-subscription-guard
Open

fix(wc-memberships): skip expiry filter for non-subscription memberships#4743
adekbadek wants to merge 1 commit into
trunkfrom
hotfix/membership-expiry-non-subscription-guard

Conversation

@adekbadek
Copy link
Copy Markdown
Member

All Submissions:

Changes proposed in this Pull Request:

Membership_Expiry::prevent_membership_expiration() is hooked into wc_memberships_expire_user_membership, which fires for every user membership. The handler assumed every membership was a subscription-tied one (\WC_Memberships_Integration_Subscriptions_User_Membership) and called get_subscription_id() on it. For plain WC_Memberships_User_Membership objects (no linked subscription), that method does not exist, so the call throws Uncaught Error: Call to undefined method WC_Memberships_User_Membership::get_subscription_id().

This adds an early method_exists() guard that returns the incoming $cancel_membership value unchanged when the membership is not subscription-tied, so the filter is effectively a no-op for memberships it cannot reason about. The docblock type for $user_membership is also widened from the integration class to the base class to match reality.

How to test the changes in this Pull Request:

  1. With WC Memberships active but without WC Subscriptions (or with a manually-granted membership that has no linked subscription), expire that membership in the admin or via wp wc memberships .... Confirm no PHP fatal is logged.
  2. With WC Subscriptions active and a subscription-tied membership, cancel the underlying subscription. Confirm the existing behavior still works: if another active subscription for the same product exists, the membership is reassigned and not expired; otherwise it expires normally.
  3. Run the included unit test: composer test -- --filter test_passes_through_non_subscription_membership. It must pass; without the fix it errors with Call to undefined method ... ::get_subscription_id().
  4. Run the full plugin test suite to confirm no regressions: composer test.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

The wc_memberships_expire_user_membership filter fires for every user
membership, not just subscription-tied ones. The handler assumed a
\WC_Memberships_Integration_Subscriptions_User_Membership and called
get_subscription_id() on it; plain WC_Memberships_User_Membership
objects don't have that method, so the call threw an Uncaught Error.

Bail out early via method_exists() and widen the docblock type to the
base class.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a fatal error in Membership_Expiry::prevent_membership_expiration() when the wc_memberships_expire_user_membership filter fires for non-subscription-tied memberships, which don't expose get_subscription_id().

Changes:

  • Adds a method_exists() guard to early-return when the membership object lacks get_subscription_id().
  • Widens the docblock type of $user_membership from the Subscriptions integration class to the base class.
  • Adds a unit test that reproduces the original fatal and verifies pass-through behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
includes/plugins/wc-memberships/class-membership-expiry.php Guards against non-subscription memberships and updates docblock.
tests/unit-tests/plugins/wc-memberships/membership-expiry.php New unit test verifying the filter passes through for non-subscription memberships.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 6.40.0-hotfix-membership-expiry-non-subscription-guard.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@adekbadek adekbadek marked this pull request as ready for review May 19, 2026 08:46
@adekbadek adekbadek requested a review from a team as a code owner May 19, 2026 08:46
@adekbadek adekbadek added the [Status] Needs Review The issue or pull request needs to be reviewed label May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Needs Review The issue or pull request needs to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants