Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: force active membership if the user has active subs #3268

Merged
merged 7 commits into from
Aug 1, 2024

Conversation

dkoo
Copy link
Contributor

@dkoo dkoo commented Jul 23, 2024

All Submissions:

Changes proposed in this Pull Request:

This is a third attempt at addressing the problem described in #3060 and #3050, where if a user has more than one subscription and not all are active, any of the user's memberships tied to the subscriptions' products could be incorrectly expired at any time.

This implements two new checks at runtime:

  1. When checking the user membership's status
  2. When checking whether the user has access to a restricted post

The first should run only for memberships with non-active statuses, and only if the membership's plan is tied to subscription product ownership. If it is and the user does have an active subscription with the required subscription product(s), it will update the membership to active status and relink the membership to the active subscription.

The second check is a fallback of sorts at the point where the user is trying to view restricted content. It checks if the membership requires any subscription products and allows access as long as the user has an active subscription with one of those products. Since the membership updates from the first check could take longer than it takes for the restricted content to load in the browser, this second check should avoid a race condition the first time any affected users try to view restricted content, but maybe it's not needed since the first check should permanently fix the membership status.

The major piece that was missing from #3050 was WC_Memberships_User_Membership::unschedule_expiration_events()—without calling this, updating an expired membership to active will result in an infinite loop of active/expire actions that will severely impact site performance. If we call that method before updating the status to active, the check should run exactly once for any impacted memberships, so in theory this PR should have no negative effect on site performance.

How to test the changes in this Pull Request:

  1. Set up a membership plan that requires ownership of a subscription product(s) and set it to restrict content (e.g. of a post category).
  2. As a reader, purchase the required subscription and confirm that you can view the restricted content.
  3. As an admin, manually update the reader subscription to "Expired" status.
  4. As the reader, confirm that you can no longer view the restricted content.
  5. Still as the reader, purchase another subscription to the required product.
  6. On trunk, observe that you still can't view restricted content despite owning an active subscription with the required product.
  7. As an admin, observe that the reader's membership still shows "Expired" status and is tied to the reader's expired subscription, instead of the newer active one.
  8. Check out this branch and refresh the membership either in the admin or the restricted content as the reader.
  9. Confirm that the reader can now view restricted content, and that the membership is updated to "Active" status, relinked to the active subscription, and that it doesn't continually try to expire and reactivate itself in an infinite loop that eventually crashes your entire site.

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?

@dkoo dkoo added the [Status] Needs Review The issue or pull request needs to be reviewed label Jul 23, 2024
@dkoo dkoo self-assigned this Jul 23, 2024
@dkoo dkoo requested a review from a team as a code owner July 23, 2024 23:30
Copy link
Member

@adekbadek adekbadek left a comment

Choose a reason for hiding this comment

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

Works as described! There are two typos to fix in get_last_successful_order method.

The testing instructions mention comparing to the release branch. Should this PR be a hotfix?

@dkoo
Copy link
Contributor Author

dkoo commented Jul 31, 2024

The testing instructions mention comparing to the release branch. Should this PR be a hotfix?

It was originally a hotfix, but I walked that back since it's a pretty major change that warrants more careful QA, I think. I updated the testing instructions.

@dkoo dkoo requested a review from adekbadek July 31, 2024 15:52
@github-actions github-actions bot added [Status] Approved The pull request has been reviewed and is ready to merge and removed [Status] Needs Review The issue or pull request needs to be reviewed labels Aug 1, 2024
@dkoo dkoo merged commit aebe581 into trunk Aug 1, 2024
11 checks passed
@dkoo dkoo deleted the fix/expired-memberships-with-active-subs branch August 1, 2024 15:57
matticbot pushed a commit that referenced this pull request Aug 1, 2024
# [4.8.0-alpha.1](v4.7.0...v4.8.0-alpha.1) (2024-08-01)

### Bug Fixes

* force active membership if the user has active subs ([#3268](#3268)) ([aebe581](aebe581))
* **woocommerce:** prevent /shop redirect from author archives ([46db669](46db669))

### Features

* enhancements for the Non editing contributor role ([#3277](#3277)) ([e47e422](e47e422))
* **ga4:** filter custom params ([eda5553](eda5553))
* show deprecation warning for CM in Engagement wizard ([#3264](#3264)) ([0813369](0813369))
@matticbot
Copy link
Contributor

🎉 This PR is included in version 4.8.0-alpha.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

return $subscription;
}
}
$active_subscriptions = self::get_active_subscriptions_for_user( $user_id );
Copy link
Member

@miguelpeixe miguelpeixe Aug 1, 2024

Choose a reason for hiding this comment

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

This method returns an array of integers, which breaks the expected return of get_last_successful_order(). This causes the get_contact_from_customer() to throw a fatal error by trying to ->get_id() from the integer and breaks data event handlers that rely on that method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching! I'll have a look and push an "alpha hotfix" for it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

PR here: #3299

matticbot pushed a commit that referenced this pull request Aug 13, 2024
# [5.0.0](v4.7.0...v5.0.0) (2024-08-13)

### Bug Fixes

* **data-events:** ensure get_last_successful_order returns WC_Order ([222f58c](222f58c))
* **data-events:** ensure get_last_successful_order returns WC_Order ([#3299](#3299)) ([da21561](da21561))
* **data-events:** race condition between `order_completed` and `subscription_updated` ([#3314](#3314)) ([afbf2e8](afbf2e8))
* force active membership if the user has active subs ([#3268](#3268)) ([aebe581](aebe581))
* namespacing issue ([7b1506a](7b1506a))
* update dependencies to support `@wordpress/scripts` ([#3181](#3181)) ([0d35ac8](0d35ac8))
* **woocommerce:** prevent /shop redirect from author archives ([46db669](46db669))

### Features

* enhancements for the Non editing contributor role ([#3277](#3277)) ([e47e422](e47e422))
* **ga4:** filter custom params ([eda5553](eda5553))
* rename guest contributor role ([#3302](#3302)) ([76ac05e](76ac05e))
* rename guest contributor role ([#3302](#3302)) ([c7f6917](c7f6917))
* show deprecation warning for CM in Engagement wizard ([#3264](#3264)) ([0813369](0813369))

### BREAKING CHANGES

* Updates dependencies for compatibility with WordPress 6.6.*, but breaks JS in WordPress 6.5.* and below. If you need support for WP 6.5.*, please do not upgrade to this new major version.

* chore: refactor for updating dependencies in newspack-scripts

* chore: JS formatting fixes for eslint errors

* chore: update NPM scripts and other dependencies

* chore: fix jest unit tests

* chore: update dependencies in newspack-components

* fix: peer dependency conflicts with @wordp
ress/* packages

* chore: update newspack-components dependencies

* chore: proxy stylelint from newspack-scripts

* chore: remove unnecessary stylelint

* refactor: use proxy script for eslint and stylelint scripts

* chore: remove console.log

* chore: update newspack-scripts to NPM alpha version

* chore: update newspack-scripts to git branch

* chore: update newspack-scripts to alpha.3

* test: remove unneeded mocks

* deps: newspack-scripts@5.6.0-alpha.1

* chore: fix scripts

* fix: update newspack-scripts to v5.6.0-alpha.2

* fix: add newspack-revisions.js to webpack build for linting

* fix: update stylelint and format CSS for errors

* chore: clear TS check errors

* fix: start command

* fix: remove i18n script (Blocks only)

* temporarily revert stylelint autoformat to avoid merge conflicts

* chore: add .stylelintrc.js

* fix: reformat SCSS

* chore: update newspack-scripts to v5.6.0-alpha.4

* fix: add missing Prettier config files

* chore: update newspack-scripts to 5.6.0-alpha.5

* chore: update newspack-scripts to v5.6.0-alpha.7

* style: stylelint autofixes

* fix: add fix:js script; temporarily remove format:js

* fix: update newspack-scripts to v5.5.0-alpha.8 and restore format:js script

* chore: add NPM scripts for PHP

* refactor: move recaptcha JS to src directory

* fix: ignore dist and node_modules inside src/components, too

* fix: update Babel configs for components

* fix(components): output TS and JS, and publish new major version to NPM

* fix: do not delete node_modules after post-publish

* chore: bump newspack-scripts to v5.5.2
@matticbot
Copy link
Contributor

🎉 This PR is included in version 5.0.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
released on @alpha released [Status] Approved The pull request has been reviewed and is ready to merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants