“Out of stock” fixer

If you have excluded “out of stock” products and you still see them in the search results, probably you have something wrong with relationships in your database. It may occur e.g. after using importing tools etc.

Since Woocommerce 3.0 the visibility of the products is now handled by the “product_visibility” custom taxonomy. Some importing scripts may ignore this change and this raises issues.

Solution

To fix database relationships, you have to fire the following PHP script. Run this script only once!

// Fire this code only once!!! Remove this code after fixing product visibility
add_action('admin_footer', function(){
	global $wpdb;

	$wpdb->hide_errors();
	$term_id = wc_get_product_visibility_term_ids()['outofstock'];

    // STEP 1 | Wipe all current relationships related to outofstock
	$wpdb->delete( $wpdb->term_relationships,
		array(
			'term_taxonomy_id' => $term_id
		),
		array(
			'%d'
		)
	);

    // STEP 2 | Get all products with stock status "outofstock"
	$ids = wc_get_products(
		array(
			'status'       => array( 'publish' ),
			'limit'        => - 1,
			'stock_status' => 'outofstock',
			'return'       => 'ids'
		)
	);

    // STEP 3 | Hide these products by adding correct term relationships
	if ( ! empty( $ids ) && is_array( $ids ) ) {
		$wpdb->query( 'START TRANSACTION' );
		for ( $i = 0; $i < count( $ids ); $i ++ ) {
			$wpdb->insert( $wpdb->term_relationships,
				array( 'object_id' => $ids[ $i ], 'term_taxonomy_id' => $term_id, 'term_order' => 0 ),
				array( '%d', '%d', '%d' )
			);
			if ( $i % 100 == 0 ) {
				$wpdb->query( 'COMMIT' );
				$wpdb->query( 'START TRANSACTION' );
			}
		}
		$wpdb->query( 'COMMIT' );
	}

});

After running this script, go to WooCommerce -> FiboSearch -> Indexer (tab) and rebuild the search index.

How to fire this script?

By child-theme using functions.php file

Open the functions.php in your Child Theme and add the code at the. Refresh the Admin dashboard to call the script and remove this code from the functions.php file.

By Code Snippets plugin

Install the Code Snippets plugin and apply this code as a snippet. Refresh the Admin dashboard to call the script and remove this snippet.