Forum Replies Created

Viewing 5 replies - 1 through 5 (of 5 total)
  • Same problem since upgrade to 6.7.3 on 23/11/2023 (yesterday).
    Solved by downgrading back to 6.7.2

    Thread Starter oppitz

    (@oppitz)

    Same symptom again since last update ( 9.5.4 )

    Thread Starter oppitz

    (@oppitz)

    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.
    Thread Starter oppitz

    (@oppitz)

    Thank you for fixing in version 9.3.3

    Thread Starter oppitz

    (@oppitz)

    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 3

    I 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.xml

    Feed 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.xml

    Feed 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.xml

    I 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)){
    With

    	if(!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.

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