Skip to content

fix(wishlist): stop recalculating item count on every request - #41152

Open
Eddcapone wants to merge 4 commits into
magento:2.4-developfrom
Eddcapone:fix/wishlist-section-count-stale-cache-check
Open

fix(wishlist): stop recalculating item count on every request#41152
Eddcapone wants to merge 4 commits into
magento:2.4-developfrom
Eddcapone:fix/wishlist-section-count-stale-cache-check

Conversation

@Eddcapone

@Eddcapone Eddcapone commented Aug 26, 2026

Copy link
Copy Markdown

Description (*)

Magento\Wishlist\Helper\Data::getItemCount() decides whether to recalculate the customer's wishlist item count based on four conditions. Three of them correctly compare a stored value against the current one. The third, hasDisplayOutOfStockProducts(), only checks whether a value was ever stored, not whether it changed.

calculate() unconditionally calls setDisplayOutOfStockProducts() every time it runs, which means that condition becomes permanently true for the rest of the customer session after the very first call to getItemCount(). From that point on, this single condition forces a full recalculation on every subsequent call, regardless of whether the wishlist display type, the out-of-stock display setting, or the actual wishlist contents changed. The caching this method is supposed to provide is effectively disabled for the rest of the session.

This fix removes the faulty existence check. The remaining value comparison ($currentDisplayOutOfStockProducts != $storedDisplayOutOfStockProducts) already covers "changed since last time", including the first-ever call, since !hasWishlistItemCount() already forces recalculation then regardless.

Impact in practice: every customer/section/load request that includes the wishlist section (e.g. triggered by the default header mini-wishlist link) pays the full cost of the wishlist collection query and item resolution again, on every single request, for the rest of the customer's session, instead of reusing the cached count.

Two things worth noting about correctness, since removing a condition always raises the question of whether it silently changes behavior:

  • Actual wishlist content changes (adding/removing an item) never went through these four conditions at all: Controller/Index/Add.php, Controller/Index/Remove.php and Model/ItemCarrier.php all call calculate() directly and unconditionally right after the action. The removed condition played no role there.
  • The remaining value comparison for the out-of-stock display setting is covered by its own dedicated unit test (see below), proving it alone still forces a recalculation when that setting changes, independent of the removed check.

Related Pull Requests

None.

Fixed Issues (if relevant)

  1. Fixes Wishlist section count is recalculated on every request because of a stale-cache check in Wishlist\Helper\Data::getItemCount() #41151

Manual testing scenarios (*)

  1. Log in as a customer and open any storefront page so the wishlist customer-data section is requested at least once (e.g. via the default header wishlist link).
  2. Without changing Stores > Configuration > Customers > Wishlist > General Options > Display Wishlist Summary or Stores > Configuration > Catalog > Inventory > Product Stock Options > Display Out of Stock Products, trigger the wishlist section again, e.g. by calling customer/section/load?sections=wishlist a second time, or by opening another page.
  3. Before the fix: the wishlist item count is recalculated from scratch on every such call (visible via the Magento profiler / dev/debug query log as a repeated wishlist item collection query, and as consistently elevated response time for that request). After the fix: the cached value from the customer session is reused, and no wishlist collection query runs again, as long as nothing relevant changed.
  4. Regression check: change Display Wishlist Summary or Display Out of Stock Products, or add/remove a wishlist item, and confirm the count still recalculates and reflects the change correctly, i.e. the cache is still invalidated when something actually changes.

Questions or comments

None.

Contribution checklist (*)

  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All new or changed code is covered with unit/integration tests (if applicable)
  • README.md files for modified modules are updated and included in the pull request if any README.md predefined sections require an update
  • All automated tests passed successfully (all builds are green)

hasDisplayOutOfStockProducts() only checked whether a session value
was ever set, not whether it changed, unlike its sibling condition
right below it. Since calculate() sets that value unconditionally,
this made the third condition permanently true after the first call,
defeating the caching getItemCount() is supposed to provide for the
rest of the customer session.

Fixes magento#41151
@m2-assistant

m2-assistant Bot commented Aug 26, 2026

Copy link
Copy Markdown

Hi @Eddcapone. Thank you for your contribution!
Here are some useful tips on how you can test your changes using Magento test environment.
❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names.

Allowed build names are:
  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here
ℹ️ Run only required test builds during development. Run all test builds before sending your pull request for review.


For more details, review the Code Contributions documentation.
Join Magento Community Engineering Slack and ask your questions in #github channel.

Adds a second unit test proving that removing the buggy
hasDisplayOutOfStockProducts() existence check did not weaken change
detection: with that check completely absent, a genuine change to the
out-of-stock display setting alone still forces calculate() to run
(verified via isLoggedIn()/setWishlistItemCount() expectations).

Also mocks Context::getEventManager(), which calculate() now reaches
for the first time in this test class.
@Eddcapone

Copy link
Copy Markdown
Author

@magento run all tests

Eduard Fekete and others added 2 commits August 31, 2026 12:02
The new scopeConfig/eventManager mocks needed to cover the stale
section-count cache check pushed DataTest to 16 properties, exceeding
PHPMD's TooManyFields threshold of 15. Suppress it the same way
WishlistTest already does for the same rule.
@Eddcapone

Copy link
Copy Markdown
Author

@magento run all tests

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.

Wishlist section count is recalculated on every request because of a stale-cache check in Wishlist\Helper\Data::getItemCount()

1 participant