Add support for filtering and paging to the cart provider

Created on 2 September 2025, about 1 month ago

Problem/Motivation

The cart provider currently loads all carts for the current or given user. This happens internally at the loadCartData method even if you request just one cart. This might be kind of OK for the majority of single-domain application where the user might have just one cart.

For bigger applications though, this is very inefficient. Not only are the cart entities loaded, but doing so cart refresh may be triggered and this means a bunch of other things are done - loads all of its order items, recalculates prices, promotions etc.

Not only is this unnecessary, but here are some examples where this is problematic: for multi-domain applications where each user will have different carts on different domains, the system loads and refreshes all carts for all domains even though the frontend will only render those for the current domain. B2B applications might allow business customers and dealers to create many carts, some in the orders of dozens. This causes excessive use of resources, especially for decoupled frontends where serialization of all those carts cause resource spikes and failures.

Proposed resolution

  • Provide filtering and paging options so that the caller can load only the carts needed.
  • Separate the code for authenticated and anonymous users so that relevant optimizations can be made.

Anonymous users is very unlikely to have multiple carts, loading the carts can be safely done for them. Optimizing them - if the need arises - would require a solution starting at the cart session. There is, however, no need to load the carts for authenticated users; the eligibility and other checks are already embedded in the entity query itself.

API changes

  • The current API is extended, but not broken.
  • The loadCartData method is changed; not a public API, but third parties that extend it will need to be updated.
  • An extra argument is added to the constructor.
    • Data model changes

      Internal changes only:

      • Since the complexity increased, I used a cache backend to statically cache the results instead of using a class property. This change is not necessary, but useful.
      • All filtering is now done within loadCartData; there is therefore no need to cache the order type and store ID for each cart, we only cache the cart IDs.
Feature request
Status

Active

Version

2.0

Component

Cart

Created by

🇵🇪Peru krystalcode

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @krystalcode
  • 🇵🇪Peru krystalcode

    Adding a patch for Commerce 2.33, I'll create an MR against the latest 2.x version soon.

  • 🇵🇪Peru krystalcode

    Remaining tasks as of now.

    • Get feedback from maintainers to ensure they're in agreement with the approach.
    • Add NULL handling and deprecation notice for the extra argument in the constructor.

    Some more comments.

    • I'm more in favor of unit tests, but since I know other like kernel or functional tests more those could be added/updated.
    • Unit test are added this way so that classes extending the cart provider, for example, to alter the query, can easily add their own unit tests so that all checks are run with the changes without having to repeat all this code. Not sure if there's a better way.
    • The tests could be refactored to reduce code repetition, but I think it would make code less understandable. For tests, I think there should be quick visibility on what exactly the test checks for without having to go through levels of inheritance and other tricks.
    • We do lose the ability or add or remove the cache item for a specific cart when created or finalized - we have to clear all caches for the user. But I think that's more than compensated by the other performance advantages e.g. not loading cart entities at all for authenticated users - unless requested, limiting the number of carts requested and loaded etc.
  • 🇵🇪Peru krystalcode

    Moving to Needs Review to get some initial feedback from module maintainers.

  • Pipeline finished with Failed
    about 1 month ago
    Total: 890s
    #588472
  • 🇵🇪Peru krystalcode

    Re-uploading patch from #5 with some changes removed because they were moved to a separate issue.

  • 🇮🇱Israel jsacksick

    Thank you for your contribution, however please note that all new feature requests should go against 3.x.
    TBH, this is a big MR to review and we have currently bigger priorities so I can't really promise we'll be able to review/commit these changes anytime soon.

    In general, breaking down the issue into multiple is always a good idea as it makes our job easier when it comes to reviewing the changes and simply even consider merging those.

    In the meantime there is a query tag that can be implemented in your own project, and could also consider swapping the CartProvider.

  • Pipeline finished with Failed
    26 days ago
    Total: 648s
    #595670
Production build 0.71.5 2024