Skip to content

Instantly share code, notes, and snippets.

@andyg2
Created March 30, 2023 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyg2/f857b9383f1ce4e240787bc10525c60b to your computer and use it in GitHub Desktop.
Save andyg2/f857b9383f1ce4e240787bc10525c60b to your computer and use it in GitHub Desktop.
Limit WooCommerce Sold Products Display Quantity
<?php
/*
* Plugin Name: Limit Sold Products
* Description: Limits the number of sold out products that show up on the front end of your WooCommerce store
* Author: Andy Gee
* Author URI: https://dgte.pro
* Version: 1.0
* Plugin Slug: dgtepro-limit-sold-products
*/
if (!defined('ABSPATH')) {
die("Nope.");
}
// Add settings to WooCommerce settings page
add_filter('woocommerce_get_settings_products', 'limit_sold_products_settings', 10, 1);
function limit_sold_products_settings($settings) {
if (isset($_GET['section']) && $_GET['section'] == 'advanced') {
$settings[] = array(
'name' => __('Limit Sold Products', 'woocommerce'),
'desc' => __('Limit the number of sold out products that show up on the front end of your WooCommerce store', 'woocommerce'),
'id' => 'limit_sold_products_settings',
'type' => 'title',
'desc_tip' => true,
);
$settings[] = array(
'name' => __('Enable', 'woocommerce'),
'id' => 'limit_sold_products_enable',
'type' => 'checkbox',
);
$settings[] = array(
'name' => __('Percentage', 'woocommerce'),
'id' => 'limit_sold_products_percentage',
'type' => 'number',
'min' => 0,
'max' => 100,
'step' => 1,
'custom_attributes' => array(
'style' => 'width: 50px;',
),
);
$settings[] = array(
'type' => 'sectionend',
'id' => 'limit_sold_products_settings',
);
}
return $settings;
}
// Add settings link to plugin page
add_filter('plugin_action_links', 'my_plugin_settings_link', 10, 2);
function my_plugin_settings_link($links, $file) {
// Check if the current plugin is yours
if ($file == 'dgtepro-limit-sold-products/dgtepro-limit-sold-products.php') {
// Add the settings link
$settings_link = '<a href="' . admin_url('admin.php?page=wc-settings&tab=products&section=advanced') . '">' . __('Settings', 'dgtepro-limit-sold-products') . '</a>';
array_push($links, $settings_link);
}
return $links;
}
function limit_sold_out_products_quantity($q) {
if (!is_admin() && !isset($q->query_vars['sold_out_limited']) && (isset($q->query_vars['product_cat']) || $q->get('post_type') == 'product') || is_page(wc_get_page_id('shop'))) {
// Get the plugin settings
$enabled = get_option('limit_sold_products_enable', 'no');
$percentage = get_option('limit_sold_products_percentage', '10');
if ($enabled == 'yes') {
$q->query_vars['sold_out_limited'] = true;
// Query all the in stock products based on current query
$in_stock_args = $q->query_vars;
$out_of_stock_args = $q->query_vars;
$in_stock_args['meta_query'][] = array(
'key' => '_stock_status',
'value' => 'instock',
'operator' => 'IN'
);
$in_stock_query = new WP_Query($in_stock_args);
$in_stock_posts = $in_stock_query->get_posts();
$in_stock_count = count($in_stock_posts);
// Query all the out of stock products based on current query
$out_of_stock_args = $q->query_vars;
$out_of_stock_args['meta_query'][] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'operator' => 'IN'
);
$out_of_stock_query = new WP_Query($out_of_stock_args);
$out_of_stock_posts = $out_of_stock_query->get_posts();
// Limit the number of out of sstock products to 10% of the in stock products count.
$limited_out_of_stock_posts = array_slice($out_of_stock_posts, 0, ceil($in_stock_count * ($percentage / 100)));
// Merge the limited_out_of_stock_posts and in_stock_posts products
$final_posts = array_merge($limited_out_of_stock_posts, $in_stock_posts);
// Modify the main query to get posts based on the IDs of the merged set of products
$q->set('post__in', wp_list_pluck($final_posts, 'ID'));
$q->set('orderby', 'post__in');
}
}
}
add_action('pre_get_posts', 'limit_sold_out_products_quantity', 999, 2);
// Add the settings page to the WooCommerce settings menu
function lsp_add_settings_page() {
add_filter('woocommerce_settings_tabs_array', 'lsp_add_settings_tab', 50);
add_action('woocommerce_settings_tabs_lsp_settings', 'lsp_settings_tab_content');
add_action('woocommerce_update_options_lsp_settings', 'lsp_save_settings');
}
add_action('admin_init', 'lsp_add_settings_page');
function lsp_add_settings_tab($settings_tabs) {
$settings_tabs['lsp_settings'] = __('Limit Sold Products', 'lsp');
return $settings_tabs;
}
function lsp_settings_tab_content() {
woocommerce_admin_fields(lsp_get_settings());
}
function lsp_save_settings() {
woocommerce_update_options(lsp_get_settings());
}
function lsp_get_settings() {
$settings = array(
'section_title' => array(
'name' => __('Limit Sold Products Settings', 'lsp'),
'type' => 'title',
'desc' => '',
'id' => 'lsp_settings_section_title'
),
'enabled' => array(
'name' => __('Enabled', 'lsp'),
'type' => 'checkbox',
'desc' => __('Check to enable limiting of sold products', 'lsp'),
'id' => 'lsp_enabled'
),
'percentage' => array(
'name' => __('Percentage', 'lsp'),
'type' => 'range',
'desc' => __('Select the percentage of sold out products to display (0-50)', 'lsp'),
'id' => 'lsp_percentage',
'css' => 'width: 50%',
'default' => '10',
'desc_tip' => true,
'attributes' => array(
'min' => '0',
'max' => '50',
'step' => '1',
)
),
'section_end' => array(
'type' => 'sectionend',
'id' => 'lsp_settings_section_end'
)
);
return apply_filters('lsp_settings', $settings);
}
@andyg2
Copy link
Author

andyg2 commented Mar 30, 2023

This added a settings page to WooCommerce > Settings > Products > Advanced. There's a checkbox to enable/disable the functionality and a percentage input field to limit the percentage of sold products that are displayed in categories and main shop page on the front end.

A settings of 10 (10%) will do the following on any category.

  • Fetch all in-stock products for the current query (category or shop).
  • Count the fetched products and calculate 10% of those from settings.
  • Fetch that count quantity of out-of-stock products for the current query.
  • Merge the IDs for those two lists of products.
  • Alter the original query to fetch products based on those IDs (to maintain original sorting, pagination etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment