问题
I have 'hide out of stock' checked in the settings, however when using the layered navigation widget to filter results by shoe size, it is returning products which have that size listed as an attribute, but the size is out of stock. Is there a fix to this?
WordPress version 3.9.1, WooCommerce version 2.1.7
http://www.foten.se
回答1:
He means not showing the products in the filter results. If a user filters by size M, he wants to see available size M products in the results, not All products that used to have a size M but dont anymore...
This is something woocommerce has not solved in years! and something that anyone opening a woocommerce store should know. I am sure most of them wont use woocommerce because of this issue alone.
回答2:
I solve it by running the following script every night
$dir = dirname(__FILE__);
include_once($dir . '/../../../../wp-load.php');
$currentCount = 0;
$pageSize = 10;
global $wpdb;
$run = true;
while ($run) {
// select all variation of products with stock == 0
$sql = "SELECT * FROM `wpmf_postmeta` as pm
LEFT JOIN wpmf_posts as p on p.ID = pm.post_id
WHERE
meta_key = '_stock' and meta_value = 0
and p.post_parent <> 0 LIMIT $currentCount," . ($currentCount + $pageSize);
// var_dump($sql);die;
$res = $wpdb->get_results($sql, ARRAY_A);
if (!$res) { //|| $currentCount > 20
$run = false;
break;
}
foreach ($res as $r) {
$post_parent = $r['post_parent'];
$post_excerpt = $r['post_excerpt'];
$size = preg_replace('/[^0-9.]/', '', $post_excerpt);
// echo($post_parent . ", $size" . '<br>');
if ($size && $size != '') {
// find the term ID and delete it from parent product
$res_term = $wpdb->get_results("SELECT * FROM `wpmf_term_relationships` as tr
LEFT JOIN wpmf_terms as t on t.term_id = tr.term_taxonomy_id
where `object_id` = $post_parent and name = $size", ARRAY_A);
// var_dump($terms_rel);
if ($res_term) {
$query = "
DELETE FROM wpmf_term_relationships
WHERE term_taxonomy_id = " . $res_term[0]['term_id'] . "
AND object_id = " . $post_parent . "
";
$res_query = $wpdb->query(
$query);
echo($post_parent . ", $size, $res_query" . '<br>');
}
}
$currentCount++;
}
}
wp_cache_flush();
echo 'done! ' . $currentCount;
The problem this script fixes is: the sidebar filters the product by attribute
but the stock is manage by product variation (child post).
The DB doesn't have a way to link the 2 fields, therefore it is not possible to create a query that filters attributes that has a matching variation with stock == 0.
Therefore this script solve the problem by deleting products attributes that have stock == 0
here is a opposite script to set an attribute for a product with stock > 0 and a missing attr:
$dir = dirname(__FILE__);
include_once($dir . '/../../../../wp-load.php');
$currentCount = 0;
$pageSize = 10;
global $wpdb;
$run = true;
while ($run) {
// select all varaition of a prod with stock > 0
$sql = "SELECT * FROM `wpmf_postmeta` as pm
LEFT JOIN wpmf_posts as p on p.ID = pm.post_id
WHERE
meta_key = '_stock' and meta_value <> 0
and p.post_parent <> 0 LIMIT $currentCount," . ($currentCount + $pageSize);
// var_dump($sql);die;
$res = $wpdb->get_results($sql, ARRAY_A);
if (!$res) { //|| $currentCount > 20
$run = false;
break;
}
foreach ($res as $r) {
$post_parent = $r['post_parent'];
$post_excerpt = $r['post_excerpt'];
$size = preg_replace('/[^0-9.]/', '', $post_excerpt);
if ($size && $size != '') {
// find the relevant term
$res_parent = $wpdb->get_results("SELECT * FROM `wpmf_term_relationships` as tr
LEFT JOIN wpmf_terms as t on t.term_id = tr.term_taxonomy_id
where `object_id` = $post_parent and name = $size", ARRAY_A);
// var_dump($terms_rel);
// if term is missing, create it
if (!$res_parent) {
wp_set_object_terms($post_parent, $size, 'pa_size', true);
echo($post_parent . ", $size" . '<br>');
}
$currentCount++;
}
}
}
wp_cache_flush();
echo 'done! ' . $currentCount;
NOTE:
this is not a proper solution to the problem - a solution should be at the design level, i.e. finding a way to link the 2 fields with an SQL query, this solution is a temp by-pass until a real solution is available
I didn't fully tested this code, I will update the answer if necessary in the future
I'm not fully familiar with the DB structure of wordpress or woocommerce, and the result of this code might change depending on different plugins, using this code is at your own risk
回答3:
In WooCommerce, the default option is that, it shows all products that are in stock and out of stock on search results and the product category pages. This is a WooCommerce default functionality
Link regarding this: https://github.com/woothemes/woocommerce/issues/5840
Also, not showing these products on the contrary is a bad idea, as it is not as per the best SEO practices.
来源:https://stackoverflow.com/questions/24161207/how-to-prevent-out-of-stock-items-to-show-as-a-filter-option-in-the-sidebar-l