#55837 closed defect (bug) (fixed)
WP_Term_Query cache problem
Reported by: | denishua | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | 6.0.1 | Priority: | normal |
Severity: | normal | Version: | 6.0 |
Component: | Taxonomy | Keywords: | has-patch has-unit-tests fixed-major |
Focuses: | Cc: |
Description
when use child_of parameter in WP_Term_Query,
it return the right result first time,
it return all terms the second times when hit cache.
my test code:
wp_list_categories("child_of=2&depth=1&hide_empty=0");
Change History (35)
#2
@
2 years ago
- Component changed from General to Taxonomy
Hi there,
I also noticed this issue. Here is my mu-plugin to see the difference between cached and non-cached data:
<?php namespace NefisYemekTarifleri\TERM_CACHE_TEST; function init() { $last_changed = microtime(); wp_cache_set( 'last_changed', $last_changed, 'terms' ); $args = array( 'taxonomy' => 'category', 'child_of' => 2219, // some category id. ); $terms = get_terms( $args ); $terms = wp_list_pluck( $terms, 'name' ); $terms2 = get_terms( $args ); $terms2 = wp_list_pluck( $terms2, 'name' ); echo count( $terms ); var_dump( $terms ); echo '<hr />'; echo count( $terms2 ); var_dump( $terms2 ); //die(); } add_action( 'init', __NAMESPACE__ . '\\init' );
#3
@
2 years ago
- Keywords needs-patch needs-unit-tests added
- Milestone changed from Awaiting Review to 6.0.1
Thanks for your report @denishua, I am able to reproduce have confirmed the bug was introduced in WordPress 6.0. I've placed this on the 6.0.1 milestone for review.
@spacedmonkey do you have any bandwidth to look in to this? I'll be on leave next week, returning June 6 2022, so won't be available for any code review you may require.
This ticket was mentioned in PR #2756 on WordPress/wordpress-develop by spacedmonkey.
2 years ago
#4
- Keywords has-patch added; needs-patch removed
Trac ticket: https://core.trac.wordpress.org/ticket/55837
#5
follow-up:
↓ 10
@
2 years ago
Thanks for the ping @peterwilsoncc !
I have put together a patch. This does a number of things.
- Fixes the core issue, that was highlighted here.
- Removes confusing and unneeded code.
- Improves the cache value, so it now only stores an array of ids, in all but two caches ( count and object with ids ).
This will also improve memory usage on every page, which is another side benefit.
Once someone has proved that this fixes the issue, I will add some unit tests.
#9
@
2 years ago
If it's of use to anyone, we were hitting some issues with this and @spencercameron threw this together as a temporary fix until it's resolved in 6.0.1 and it seems to mitigate the issue in our testing on one site so far -- (we're working on rolling it out to a few others and vetting it there as well to confirm more broadly)
https://gist.github.com/pippercameron/3294971e9c0810ba491a68278d0ceb10
Full disclaimers! Test it first in a dev environment! No warranties, but may help mitigate the issue.
There may be future revisions on it, but didn't want to sit on it if it can help anyone else.
#10
in reply to:
↑ 5
@
2 years ago
I think is better to cache terms immediately when get from db.
<?php $terms = $wpdb->get_results( $this->request );
otherwise if
$args['pad_counts']
is true and
$args['number']
is set, the pad_counts of term will be different.
Replying to spacedmonkey:
Thanks for the ping @peterwilsoncc !
I have put together a patch. This does a number of things.
- Fixes the core issue, that was highlighted here.
- Removes confusing and unneeded code.
- Improves the cache value, so it now only stores an array of ids, in all but two caches ( count and object with ids ).
This will also improve memory usage on every page, which is another side benefit.
Once someone has proved that this fixes the issue, I will add some unit tests.
#11
follow-up:
↓ 14
@
2 years ago
- Keywords has-unit-tests added; needs-unit-tests removed
@denishua I have a patch that will fix both issues. Any chance you could test my PR?
#14
in reply to:
↑ 11
@
2 years ago
- Resolution set to worksforme
- Status changed from assigned to closed
Replying to spacedmonkey:
@denishua I have a patch that will fix both issues. Any chance you could test my PR?
thanks @spacedmonkey
i applied your patch to my live website and the categories are back up and running again. before that, my code
$args = [ 'taxonomy' => 'product_cat', 'title_li' => '', 'exclude' => [123, 456], 'orderby' => 'menu_order', 'echo' => false, ]; echo '<ul class="collection-list">' . wp_list_categories($args) . '</ul>';
returned: no categories
(i updated to wp 6.0 yesterday, before i had 5.9.3 running and the product_cats were working fine)
#15
@
2 years ago
- Resolution worksforme deleted
- Status changed from closed to reopened
Ticket will be closed when patch committed to trunk and/or target version.
spacedmonkey commented on PR #2756:
2 years ago
#16
@peterwilsoncc
The biggest change here, is that before there were two variables, $term_objects and $terms. These variables basically did the same thing but depending on what params were passed, would result in different values. This PR, ensure that if pad_counts
or child_of
are passed, that the correct value is returned. It also makes the code a lot easier to read, by removing two variables. It also improves cache value, by only caching an array of ids, if other properties are not needed.
spacedmonkey commented on PR #2756:
2 years ago
#17
@peterwilsoncc
The biggest change here, is that before there were two variables, $term_objects and $terms. These variables basically did the same thing but depending on what params were passed, would result in different values. This PR, ensure that if pad_counts
or child_of
are passed, that the correct value is returned. It also makes the code a lot easier to read, by removing two variables. It also improves cache value, by only caching an array of ids, if other properties are not needed.
spacedmonkey commented on PR #2756:
2 years ago
#18
@peterwilsoncc
The biggest change here, is that before there were two variables, $term_objects and $terms. These variables basically did the same thing but depending on what params were passed, would result in different values. This PR, ensure that if pad_counts
or child_of
are passed, that the correct value is returned. It also makes the code a lot easier to read, by removing two variables. It also improves cache value, by only caching an array of ids, if other properties are not needed.
#22
follow-up:
↓ 24
@
2 years ago
- Keywords commit removed
The commit [53496] is now in trunk. This needs to backported to 6.0 branch. Any recommendations on how to do this @SergeyBiryukov @desrosj @peterwilsoncc ?
spacedmonkey commented on PR #2756:
2 years ago
#23
#24
in reply to:
↑ 22
@
2 years ago
- Keywords fixed-major added
- Resolution fixed deleted
- Status changed from closed to reopened
Replying to spacedmonkey:
This needs to backported to 6.0 branch. Any recommendations on how to do this?
Reopening for backporting to the 6.0 branch.
The Backporting Commits handbook article might be helpful :)
#25
@
2 years ago
- Owner changed from spacedmonkey to SergeyBiryukov
- Status changed from reopened to assigned
Reassigned for backporting.
#26
@
2 years ago
I am running into similar caching issues with WP_Term_Query
on 6.0, specifically when using the exclude_tree
argument to filter the results. It works fine for the first run, but then all the subsequent runs of the same query return no results, and basically makes some functions unusable. Does this patch already fix the issue with the exclude_tree
parameter too? or do I need to create a new bug report?
#27
@
2 years ago
We have 3 cases around the terms caching introduced in WP6.0, mainly when it's about bigger queries (seems like) on big WooCommerce shops. On daily basis, the subcategories on category pages (of shop page) are disappearing. Mostly on shops that use parent and subcategories, but only check the subcategorie when they add products. So, therefore it seems like the "parent" category is empty, apparently of the way the new caching works (on term id).
A manual recount terms (a setting in WooCommerce) must be done, daily since a few weeks.
Been investigating it for weeks. Finally found this ticket. Hopefully the solution will be rolled out quickly. Thanks!
This ticket was mentioned in Slack in #core by sergey. View the logs.
2 years ago
#32
@
2 years ago
I was puzzled a bit by the $wp_db_version
version bump. It looks like the intention was to clear the cache, and I see the wp_cache_flush()
call in update_core()
, but unless I'm missing something, it runs regardless of the $wp_db_version
value, followed by some more code, none of which depends on $wp_db_version
. So I'm curious why the version bump is needed :)
If the DB version is bumped, wp_cache_flush()
runs again in wp_upgrade()
after schema upgrade, but since there's no actual schema upgrade here, it seems that for the purpose of the ticket, this second call would be redundant, as the one in update_core()
should be enough.
In a discussion with @peterwilsoncc it was determined that $wp_db_version
should still be bumped for the upgrade_600()
routine to run, as it was missed in [53011]. In that case, if it's not necessary for the cache clearing here, might be a good idea to do the bump separately, for clarity.
Related: comment:16:ticket:55890
#33
@
2 years ago
I realised why I thought this needed the DB version bump.
While update_core()
does flush the cache for sites using the WP Admin upgrader, it's not run for sites using a more advanced deployment: composer, version control or similar.
As sites running a persistent cache are more likely to use such a configuration, including the cache flush on this ticket will be helpful.
I'll add a see reference to the other ticket when backporting.
I think the WP_Term_Query get_terms method only handle $term_objects, but forgot $terms variable when deal with child_of parameter.
the fast way fix the problem is move line 891 before line 890