• Resolved Phenix

    (@proshop)


    Hello

    We have implemented some custom code so that when the user selects an attribute term on the front-end, it also checks for other terms we have mapped via an array too.

    For example, the query below is the query which is generated now as a result of our code. You can see it checks for multiple terms 1225 and 413 in wp_term_relationships.term_taxonomy_id.

    1225 is the term they selected on the front-end, and 413 is mapped to it via our code.

    The bit we’re really struggling with though is the bit which says ‘WHERE term_id in (1225)’. We want this to update to WHERE term_id in (1225,413)’ – but there’s nothing we can do to hook into to amend this.

    Does anyone have any recommendations of which filters/hook to use to amend this as everything we’ve tried doesn’t work. The only part we can seem to change is the bit which is already changed , which is this bit “wp_term_relationships.term_taxonomy_id IN (1225) OR wp_term_relationships.term_taxonomy_id IN (413)”

    Thanks

    Our Current Query:

           SELECT SQL_CALC_FOUND_ROWS wp_posts.*
    FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (1225)
    OR
    wp_term_relationships.term_taxonomy_id IN (413)
    )   AND ((wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'wfob-disabled' OR wp_posts.post_status = 'wfocu-disabled' OR wp_posts.post_status = 'open' OR wp_posts.post_status = 'closed' 
        OR wp_posts.post_status = 'private'))) AND (
                             wp_posts.ID IN ( SELECT product_or_parent_id FROM (
                            SELECT product_or_parent_id
                            FROM wp_wc_product_attributes_lookup lt
                            WHERE term_id in (1225)
                             AND in_stock = 1
                        ) temp ))
            GROUP BY wp_posts.ID
            ORDER BY wp_posts.post_date DESC, wp_posts.ID DESC
            LIMIT 0, 20;

    What we want it to be (very minor change in term_id section)

         SELECT SQL_CALC_FOUND_ROWS wp_posts.*
    FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (1225)
    OR
    wp_term_relationships.term_taxonomy_id IN (413)
    )   AND ((wp_posts.post_type = 'product' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'wfob-disabled' OR wp_posts.post_status = 'wfocu-disabled' OR wp_posts.post_status = 'open' OR wp_posts.post_status = 'closed' 
        OR wp_posts.post_status = 'private'))) AND (
                             wp_posts.ID IN ( SELECT product_or_parent_id FROM (
                            SELECT product_or_parent_id
                            FROM wp_wc_product_attributes_lookup lt
                            WHERE term_id in (1225,413)
                             AND in_stock = 1
                        ) temp ))
            GROUP BY wp_posts.ID
            ORDER BY wp_posts.post_date DESC, wp_posts.ID DESC
            LIMIT 0, 20;
Viewing 8 replies - 1 through 8 (of 8 total)
  • Moderator bcworkz

    (@bcworkz)

    What code are you using to get such a query?

    Here’s an example using WP_Query class:

    $args = array(
      'post_type' => 'post',
      'tax_query' => array(
        array(
          'taxonomy' => 'category',
          'field' => 'term_id',
          'terms' => array( 49, 46,),
          'operator' => 'IN',
        ),
      ),
    );
    $query = new WP_Query( $args );
    
    print_r($query->request);

    While this example is for posts with certain category term IDs, it’ll provide the desired IN syntax for other post types and taxonomies, just edit as desired.

    Thread Starter Phenix

    (@proshop)

    Hello, thanks for the response. I’m essentially picking up the filter which is being selected on the front-end, then in an array I’ve mapped some terms to the one which is being selected. In the example I used above, 1225 is the parent term and 413 is mapped to 1225 in an array which I’m picking up.

    For some reason, however I try to amend the query, it only ever amends the wp_term_relationships.term_taxonomy_id part and not the ‘WHERE term_id in (1225)’ bit.

    The query is set up to be an OR. It first picks up the query for the parent term and then it does a foreach across each child term mapped to the parent term and picks up the relevant term and taxonomy to look in for that term. All of this appears to be working fine. It’s just the term_id part I can’t figure out. Everything I look at suggests what I’m doing is correct, and other approaches i’ve tried lead me to the same result.

    This is my code:

    
        // Create a tax query to search in the selected attribute and its child attributes
        $tax_query = array(
            'relation' => 'OR',
        );
    
        // Add the selected parent attribute
        $tax_query[] = array(
            'taxonomy' => $filter_parameters[$selected_filter],
            'field' => 'slug',
            'terms' => $selected_term,
        );
    
        // Check if the selected attribute has child mappings
     if (isset($child_mappings[$selected_filter])) {
         foreach ($child_mappings[$selected_filter] as $sub_child_taxonomy) {
             foreach ($child_term_mappings[$selected_filter][$selected_term] as $child_term) {
                 // Add the sub-child attributes to the tax query
                 $tax_query[] = array(
                     'taxonomy' => 'pa_' . $sub_child_taxonomy,
                     'field' => 'slug',
                     'terms' => $child_term,
                 );
             }
         }
     }
    
     $query->set('tax_query', $tax_query);

    Thanks

    Thread Starter Phenix

    (@proshop)

    As an example, using Query Monitor the tax_query generated is;

    Array ( [relation] => OR [0] => Array ( [taxonomy] => pa_dexterity [field] => slug [terms] => right-handed ) [1] => Array ( [taxonomy] => pa_hand [field] => slug [terms] => right-handed )

    However i’m still not getting the correct products in my product results

    Moderator bcworkz

    (@bcworkz)

    I suggest adding 'operator' => 'IN', to each inner tax_query array. The ‘terms’ key value should be an array, even if it’s an array of one element.

    I’ve not tested using term slugs, but using term IDs I get a query in part like:

    wp_term_relationships.term_taxonomy_id IN (46,49) 
      OR 
    wp_term_relationships.term_taxonomy_id IN (6,37)

    Two different clauses because the tax_query had two different taxonomies. In theory all of the IDs could be combined into one list, but WP_Query cannot manage that on its own. It’s of little consequence since the returned query results would be the same either way.

    If adding the “IN” operator doesn’t work for you, try providing term IDs instead of slugs.

    Thread Starter Phenix

    (@proshop)

    Hello – thanks for getting back to me.

    I have been able to correctly adjust the “wp_term_relationships.term_taxonomy_id IN” part of the query. It is the term_id part below which only appears to pick up one value (1225 in my example).

    I need ‘WHERE term_id in (1225)’ to become ‘WHERE term_id in (1225,413)’ or ‘WHERE (term_id in (1225) or term_id in (413)).

    Any change I make to the tax_query only seems to amend the “wp_term_relationships.term_taxonomy_id IN” part of the query…

    It’s how the term_id is being set which I need to figure out/override

    Moderator bcworkz

    (@bcworkz)

    term_id in the secondary query? (the second SELECT product_or_parent_id query) I’m not sure where that’s coming from. Setting tax_query in the form shown in your earlier reply should yield SQL like that shown in my last reply. There are no secondary queries using tax_query like this. The only other part of the WHERE clause relates to post status.

    Thread Starter Phenix

    (@proshop)

    Hello – thanks again for getting back to me.

    Understand, thanks. I can get the tax_query to behave like I need to its just the SELECT product_or_parent_id part which I can’t.

    Do you have any ideas of how I can track this down? I’ve been trying lots of different ways but nothing seems to work.

    One thing I did consider is using str replace to find the term_id in (1225) and replace it with term_id in (1225,413) but I guess this is quite dangerous?

    Moderator bcworkz

    (@bcworkz)

    I don’t think I’d call using str_replace() “dangerous”, but it’s an inherently weak solution. Probably what you meant by “dangerous”? For me, dangerous would be introducing a security flaw, but using code that could possibly fail to work isn’t dangerous in the same sense. For example, if an extra space were added to the SQL and str_replace() wasn’t set up to accommodate it.

    Of course it’d be better to use the right parameters to get the SQL you want, but if that solution is not forth coming, then str_replace() could serve at least as a stop-gap solution. It’d still be a good idea to seek a better solution, but in the interim at least you have some kind of solution even if not ideal.

Viewing 8 replies - 1 through 8 (of 8 total)

The topic ‘Filter by Attribute – Query Change’ is closed to new replies.