[wp-trac] [WordPress Trac] #30335: Splitting shared terms on term update breaks backward compatibility when using an old term_id
WordPress Trac
noreply at wordpress.org
Sat Nov 15 14:40:43 UTC 2014
#30335: Splitting shared terms on term update breaks backward compatibility when
using an old term_id
-----------------------------------+--------------------
Reporter: boonebgorges | Owner:
Type: defect (bug) | Status: new
Priority: high | Milestone: 4.1
Component: Taxonomy | Version: trunk
Severity: major | Resolution:
Keywords: has-patch 2nd-opinion | Focuses:
-----------------------------------+--------------------
Changes (by boonebgorges):
* keywords: needs-patch => has-patch 2nd-opinion
Comment:
[attachment:30335.3.patch] is a first pass at providing backward
compatibility for the use of the pre-split term_id in a number of cases.
The cases covered are `get_term()`, `WP_Tax_Query` (when 'field=term_id'),
and `get_terms()` (when using a param that accepts term IDs, like
'include' or 'parent'). In brief: when a term is split in
`_split_shared_term()`, the affected term_taxonomy_id is stored (in the
'_split_terms' option, keyed by the old term_id). In `get_term()`, if an
integer term_id is provided and no term is found in the cache or the DB by
that term, the split term store is checked as a fallback. In `get_terms()`
and `WP_Tax_Query::transform_query()`, a fallback query won't work, so we
parse the passed term_ids *before* running the query, and swap out old
term IDs with new ones, if found.
The implementation I chose for storing and fetching split term data is
designed for performance on large sites, where split terms are most likely
to occur. The only thing stored in the '_split_terms' option is
term_taxonomy_ids, both to keep the option as small as possible (so it
won't overload a cache block). `_get_split_term()` bails quickly if the
passed term_id does not have a match in this array. If it *does* find a
match, `get_term_by()` is run, which as of 4.1 is properly cached. So, on
a site with a persistent object cache, no additional database queries
should be triggered.
I guess I have a couple concerns/points for discussion:
* This system has a slight risk of false positives. If term 5 is shared
between terms in 'post_tag' and 'category', and then the category is split
to term_id=13, a later lookup `get_term( 5, 'category' )` will return term
13. It's possible that someone could choose to pass 5 to `get_term()` in
this way without intending to reference the old term_id, and getting back
term 13 would be a pretty odd surprise. The chances of this are very
small, but worth thinking about (would have to happen with a shared term
that's been split - rare to begin with - and where someone just happens to
query for a term with that ID, in which case they should be expecting bad
(empty) results anyway).
* I've chosen to provide silent fallback support. But maybe we should
throw a `_doing_it_wrong()`?
* How many cases does this actually cover? From some discussions with
mboynes and a few others who have built custom systems that cache
'term_id', I think it will cover quite a large percentage. If you have
written something that has cached term IDs in this way, your eyes on this
patch would be most appreciated.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/30335#comment:15>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list