oppitz
Forum Replies Created
-
Same problem since upgrade to 6.7.3 on 23/11/2023 (yesterday).
Solved by downgrading back to 6.7.2Same symptom again since last update ( 9.5.4 )
Some further analysis revealed that there was still a problem related to the sku and id search part. So I modified the code to be also compatible with that part. I also used ‘fields’ => ‘ids’ to lighten the working array. As a consequence, wcfm_unique_obj_list() had to be replaced by array_unique().
$args = array( 'fields' => 'ids', 'posts_per_page' => -1, 'offset' => 0, 'category' => '', 'category_name' => '', 'orderby' => 'date', 'order' => 'DESC', 'include' => '', 'exclude' => '', 'meta_key' => '', 'meta_value' => '', 'post_type' => 'product', 'post_mime_type' => '', 'post_parent' => '', //'author' => get_current_user_id(), 'post_status' => array('draft', 'pending', 'publish', 'private', 'scheduled' ), 'suppress_filters' => 0 ); $for_count_args = $args; if( isset( $_POST['search'] ) && !empty( $_POST['search']['value'] )) { $args['s'] = $_POST['search']['value']; } if( isset($_POST['product_status']) && !empty($_POST['product_status']) && ( $_POST['product_status'] != 'any' ) ) $args['post_status'] = sanitize_text_field( $_POST['product_status'] ); if( isset($_POST['product_type']) && !empty($_POST['product_type']) ) { if ( 'downloadable' == $_POST['product_type'] ) { $args['meta_value'] = 'yes'; $args['meta_key'] = '_downloadable'; } elseif ( 'virtual' == $_POST['product_type'] ) { $args['meta_value'] = 'yes'; $args['meta_key'] = '_virtual'; } elseif ( 'variable' == $_POST['product_type'] || 'simple' == $_POST['product_type'] ) { $args['tax_query'][] = array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => array(wc_clean($_POST['product_type'])), 'operator' => 'IN' ); } else { $args['tax_query'][] = array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => array(wc_clean($_POST['product_type'])), 'operator' => 'IN' ); } } if( isset($_POST['product_cat']) && !empty($_POST['product_cat']) ) { $args['tax_query'][] = array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => array(wc_clean($_POST['product_cat'])), 'operator' => 'IN' ); } if( isset($_POST['product_taxonomy']) && !empty($_POST['product_taxonomy']) && is_array( $_POST['product_taxonomy'] ) ) { foreach( $_POST['product_taxonomy'] as $custom_taxonomy => $taxonomy_id ) { if( $taxonomy_id ) { $args['tax_query'][] = array( 'taxonomy' => $custom_taxonomy, 'field' => 'term_id', 'terms' => array($taxonomy_id), 'operator' => 'IN' ); } } } // Vendor Filter if( isset($_POST['product_vendor']) && !empty($_POST['product_vendor']) ) { $is_marketplace = wcfm_is_marketplace(); if( $is_marketplace ) { if( !wcfm_is_vendor() ) { if( $is_marketplace == 'wcpvendors' ) { $args['tax_query'][] = array( 'taxonomy' => WC_PRODUCT_VENDORS_TAXONOMY, 'field' => 'term_id', 'terms' => wc_clean($_POST['product_vendor']), ); } elseif( $is_marketplace == 'wcvendors' ) { $args['author'] = $_POST['product_vendor']; } elseif( $is_marketplace == 'wcmarketplace' ) { $vendor_term = absint( get_user_meta( wc_clean($_POST['product_vendor']), '_vendor_term_id', true ) ); $args['tax_query'][] = array( 'taxonomy' => 'dc_vendor_shop', 'field' => 'term_id', 'terms' => $vendor_term, ); } elseif( $is_marketplace == 'dokan' ) { $args['author'] = wc_clean($_POST['product_vendor']); } elseif( $is_marketplace == 'wcfmmarketplace' ) { $args['author'] = wc_clean($_POST['product_vendor']); } } } } // Order by SKU if( isset( $_POST['order'] ) && isset( $_POST['order'][0] ) && isset( $_POST['order'][0]['column'] ) && ( $_POST['order'][0]['column'] == 3 ) ) { $args['meta_key'] = '_sku'; $args['orderby'] = 'meta_value'; $args['order'] = wc_clean($_POST['order'][0]['dir']); } // Order by Price if( isset( $_POST['order'] ) && isset( $_POST['order'][0] ) && isset( $_POST['order'][0]['column'] ) && ( $_POST['order'][0]['column'] == 6 ) ) { $args['meta_key'] = '_price'; $args['orderby'] = 'meta_value_num'; $args['order'] = wc_clean($_POST['order'][0]['dir']); } // Order by View Count if( isset( $_POST['order'] ) && isset( $_POST['order'][0] ) && isset( $_POST['order'][0]['column'] ) && ( $_POST['order'][0]['column'] == 9 ) ) { $args['meta_key'] = '_wcfm_product_views'; $args['orderby'] = 'meta_value_num'; $args['order'] = wc_clean($_POST['order'][0]['dir']); } // Order by Date if( isset( $_POST['order'] ) && isset( $_POST['order'][0] ) && isset( $_POST['order'][0]['column'] ) && ( $_POST['order'][0]['column'] == 10 ) ) { $args['orderby'] = 'date'; $args['order'] = wc_clean($_POST['order'][0]['dir']); } $args = apply_filters( 'wcfm_products_args', $args ); $wcfm_products_array = get_posts( $args ); // Get all the filtered products $filtered_pro_count = count( $wcfm_products_array ); // Count of filtered products $current_user_id = apply_filters( 'wcfm_current_vendor_id', get_current_user_id() ); if( !wcfm_is_vendor() ) $current_user_id = 0; if( isset($_POST['product_status']) && !empty($_POST['product_status']) && ( $_POST['product_status'] != 'any' ) ) { $pro_count = wcfm_get_user_posts_count( $current_user_id, 'product', wc_clean($_POST['product_status']) ); } else { $pro_count = wcfm_get_user_posts_count( $current_user_id, 'product', 'publish' ); $pro_count += wcfm_get_user_posts_count( $current_user_id, 'product', 'pending' ); $pro_count += wcfm_get_user_posts_count( $current_user_id, 'product', 'draft' ); $pro_count += wcfm_get_user_posts_count( $current_user_id, 'product', 'private' ); } if( isset( $_POST['search'] ) && !empty( $_POST['search']['value'] )) { unset( $args['s'] ); $search_ids = array(); $terms = explode( ',', wc_clean($_POST['search']['value']) ); foreach ( $terms as $term ) { if ( is_numeric( $term ) ) { $search_ids[] = $term; } // Attempt to get a SKU $sku_to_id = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_parent FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id WHERE meta_key='_sku' AND meta_value LIKE %s;", '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%' ) ); $sku_to_id = array_merge( wp_list_pluck( $sku_to_id, 'ID' ), wp_list_pluck( $sku_to_id, 'post_parent' ) ); if ( ( $sku_to_id != 0 ) && sizeof( $sku_to_id ) > 0 ) { $search_ids = array_merge( $search_ids, $sku_to_id ); } } if( !empty( $search_ids ) ) { if( ( !is_array( $args['include'] ) && $args['include'] == '' ) || ( is_array($args['include']) && empty( $args['include'] ) ) ) { $args['include'] = $search_ids; } elseif( is_array($args['include']) && !empty( $args['include'] ) ) { $args['include'] = array_merge( $args['include'], $search_ids ); } $wcfm_sku_search_products_array = get_posts( $args ); if( count( $wcfm_sku_search_products_array ) > 0 ) { $wcfm_products_array = array_merge( $wcfm_products_array, $wcfm_sku_search_products_array ); $wcfm_products_array = array_unique( $wcfm_products_array ); // wcfm_unique_obj_list( $wcfm_products_array ); $filtered_pro_count = count( $wcfm_products_array ); } } } $wcfm_products_array = array_slice( $wcfm_products_array, $offset, $length ); $args['fields'] = ''; $args['include'] = $wcfm_products_array; $wcfm_products_array = get_posts( $args ); // Generate Products JSON
- This reply was modified 4 years, 1 month ago by oppitz.
Thank you for fixing in version 9.3.3
Hi,
Thanks for your fast answer,
First of all, allow me to wish you an happy new year!
I don’t use “include only” filter, imho, there’s always an “exclude” filter that can be used in place of an “include only” filter, but that’s another story.
I guess i didn’t explain clearly the situation, that’s why i’ve setup a demo website especially for you on purpose to demonstrate the “unexpected behaviour” i’m talking about.
It is a brand new wordpress install with only some basics plugins, woocommerce, acf, file manager pro and Product Feed PRO installed.
You can find it there: https://fabtest.byethost8.com/wordpress/shop/I send you the credentials by email on [email protected] along with the file patched as suggested hereunder.
Feel free to login and make any test you want in that temporary woocommerce website.Then I created 3 categories and 9 products as follows:
Product 9 – In stock – €29,00 – Category 1
Product 8 – Out of stock – €19,00 – Category 1
Product 7 – In stock – €9,00 – Category 1
Product 6 – In stock – €12,00 – Category 2
Product 5 – Out of stock – €8,00 – Category 2
Product 4 – In stock – €4,00 – Category 2
Product 3 – In stock – €20,00 – Category 3
Product 2 – Out of stock – €15,00 – Category 3
Product 1 – In stock – €10,00 – Category 3I also created with ACF one custom “text” field for products named “An attribute”.
Then i edited only product 9 and set that custom attribute to “a value” value leaving all other products untouched.
Now let’s define some products feeds:
Feed 1 is a standard “google shopping” feed with only 1 exclude rule on “category 2” which returns the expected 6 products:
https://fabtest.byethost8.com/wordpress/wp-content/uploads/woo-product-feed-pro/xml/olsivZ7OsxrppiAE7eGqz0AZlvbioLQX.xmlFeed 2 is a copy of feed 1 with another filter added to exclude “out of stock” products which returns the expected 4 products:
https://fabtest.byethost8.com/wordpress/wp-content/uploads/woo-product-feed-pro/xml/XanlDqOoBIajzh6NGZnW3PsHmFIO1iEl.xmlFeed three is a copy of feed 2 with another filter added to exclude products with custom field “An attribute” equal to “a value”.
This third feed should return a list of 3 products but returns a list of 8 products!
All the previously exluded products were re-included!
That’s quite unexpected i think, you can see it there:
https://fabtest.byethost8.com/wordpress/wp-content/uploads/woo-product-feed-pro/xml/sYdHDkTDZVxQ034RzFGtLEAG9zTo7jaL.xmlI analysed the algorithm and found out that it was coming from the function woocommerce_sea_filters in woo-product-feed-pro/classes/class-get-products.php on line 4893 (in current version 9.3.2)
When a rule is applied to a product that doesn’t have an existing postmeta used as condition, the instruction on line 4909 sends to a piece of code that causes the “unexpected behaviour“.
Instead of that, i suggest, in that situation, to consider that the missing postmeta is “empty” and add it so to the productdata array.
And also remove the code frome line 5398 to 5425 as it is then not used any more.So my suggestion to correct this issue is to replace line 4909
if(array_key_exists($pr_array['attribute'], $product_data)){
Withif(!array_key_exists($pr_array['attribute'], $product_data)) { $product_data[$pr_array['attribute']] = ""; // Sets an empty postmeta value in place of a missing one. }
And remove lines 5398 to 5425 (including first and last closing brackets)
} else { // A empty rule has been set on an attribute that is not in a product anyhow. Still, remove this product from the feed if($pr_array['condition'] == "empty"){ if($pr_array['than'] == "exclude"){ $allowed = 0; } else { $allowed = 1; } } elseif($pr_array['condition'] == "="){ if($pr_array['than'] == "exclude"){ $allowed = 1; } else { $allowed = 0; } } elseif($pr_array['condition'] == "contains"){ if($pr_array['than'] == "exclude"){ $allowed = 1; } else { $allowed = 0; } } else { if($pr_array['than'] == "exclude"){ $allowed = 0; } else { $allowed = 1; } } }
Yours faithfully.