Make WordPress Core

Opened 10 years ago

Closed 9 years ago

Last modified 5 years ago

#32526 closed defect (bug) (duplicate)

Tax_Query doesn't working in switch_to_blog()

Reported by: phill_brown's profile phill_brown Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.2.2
Component: Networks and Sites Keywords:
Focuses: multisite Cc:

Description (last modified by ocean90)

Scenario:

  • Site 1 has registered taxonomy called news_category. Site 2 hasn't.
  • Site 2 runs switch_to_blog(1);
  • Site 2 runs WP_Query with a tax_query parameter

eg

$news = new WP_Query([
    'post_type' => 'news',
    'tax_query' => [
        [
            'taxonomy' => 'news_category',
            'field' => 'slug',
            'terms' => 'wordpress',
        ]
    ]
]);

The above query returns 0 results because the tax_query portion errors and fails the WHERE clause. In this case, it's caused when the clean_query method fails a call to taxonomy_exists(). Taxonomy_exists is also baked into the logic of other subsequent functions in that method such as is_taxonomy_hierarchical and get_term_children.

This looks to be a far-reaching issue related to a ticket raised and closed years ago: #20541.

I've attached a patch which may resolve the issue specific to Tax_Query.

Attachments (1)

taxonomy.diff (503 bytes) - added by phill_brown 10 years ago.

Download all attachments as: .zip

Change History (4)

#1 @ocean90
10 years ago

  • Description modified (diff)

#2 @jeremyfelt
9 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

Thanks for the ticket and patch, @phill_brown. I don't think there's much we can do here. The attached patch solves a specific scenario, but would not make all tax queries work in a switched context.

The taxonomy is available in that it's stored in the database, but to properly use it as part of the query, any plugin registering that taxonomy should also be activated on the querying site.

At its core, this ticket is a duplicate of #20541 due to the taxonomy_exists() requirement in taxonomy queries.

#3 @ciantic
5 years ago

I would like to post my workaround here:

<?php 
// tax_query is not usable in switched blog context: 
// https://core.trac.wordpress.org/ticket/32526
switch_to_blog(123);
$taxonomy = "category";
$operator = "in";
$terms = ["news", "blog"];

$tax_query_where = function ($where, $query) use ($terms, $operator, $taxonomy) {
    global $wpdb;
    $terms_sql = implode(',', array_map(function($v) {
        return "'" . esc_sql($v) . "'";
    }, $terms));
    $tax_sql = "'" . esc_sql($taxonomy) . "'";

    $where .= "AND (taxonomy IN ($taxonomy) AND name $operator ($terms_sql))";
    return $where;
};
$tax_join = function ($join) {
    global $wpdb;
    $join .= " LEFT JOIN $wpdb->term_relationships as wtr ON ($wpdb->posts.ID = wtr.object_id) ";
    $join .= " LEFT JOIN $wpdb->term_taxonomy as wtt ON (wtr.term_taxonomy_id = wtt.term_taxonomy_id) ";
    $join .= " LEFT JOIN $wpdb->terms as wt ON(wtt.term_id = wt.term_id) ";
    return $join;
};
add_filter('posts_where', $tax_query_where, 10, 1);
add_filter("posts_join", $tax_join, 10, 1);

$q = new WP_Query(array(
    "post_type" => "post",
));

// ... do your thing ...

remove_filter('posts_where', $tax_query_where, 10, 1);
remove_filter('posts_join', $tax_join, 10, 1);
restore_current_blog();

barring any bugs (I did some editing before posting) it should work.

Version 0, edited 5 years ago by ciantic (next)
Note: See TracTickets for help on using tickets.