Is there anyway I can sort by stock? Since it reads 'Stock x 30' it would be helpful if I could sort by high or low. Is there any code I can add to the functions.php to enable that feature?
easy enough... it can be accomplished with this code...
add_filter( 'manage_edit-product_sortable_columns', 'rei_product_sortable_columns' );
function rei_product_sortable_columns( $columns ) {
$custom = array(
'is_in_stock' => 'is_in_stock'
);
return wp_parse_args( $custom, $columns );
}
but this would just sort what the stock column has... example, 'in stock' or 'out of stock'
To have a custom sort, (for example, using the stock number), you may follow the instruction on this blog post.
Working version as of: Year 2022, WP 5.9.3, WC 6.4.1:
// make quantity column sortable
function rei_product_sortable_columns( $columns )
{
$custom = array(
'is_in_stock' => 'stock_disponible'
);
return wp_parse_args( $custom, $columns );
}
add_filter( 'manage_edit-product_sortable_columns', 'rei_product_sortable_columns' );
// only load on edit.php page
function my_edit_movie_load() {
add_filter( 'request', 'my_sort_movies' );
}
add_action( 'load-edit.php', 'my_edit_movie_load' );
// do the sorting
function my_sort_movies( $vars )
{
/* Check if we're viewing the 'product' post type. */
if ( isset( $vars['post_type'] ) && 'product' == $vars['post_type'] )
{
/* Check if 'orderby' is set to 'stock_disponible'. */
if ( isset( $vars['orderby'] ) && 'stock_disponible' == $vars['orderby'] )
{
/* Merge the query vars with our custom variables. */
$vars = array_merge(
$vars,
array(
'meta_key' => '_stock',
'orderby' => 'meta_value_num'
)
);
}
}
return $vars;
}
Related
I have a custom filter set up to filter items from my shop based on their width and length.
The filter should return all products that are greater or equal to the value entered.
This works to a point, and that point is that if the value entered into the filters is greater than any of the available products, it returns all of the products instead of none.
I need it to do this and display a useful message.
Please see code below:
//Remnants filter
function add_query_vars_filter( $vars ){
$vars[] = "rem_width";
$vars[] = "rem_length";
return $vars;
}
add_filter( 'query_vars', 'add_query_vars_filter' );
// The meta query in a function
function custom_meta_query( $meta_query ){
$rem_width = get_query_var('rem_width');
$rem_length = get_query_var('rem_length');
$meta_query[] = array( 'key'=>'remnant_width', 'value' => $rem_width, 'compare'=>'>=');
$meta_query[] = array( 'key'=>'remnant_length', 'value' => $rem_length, 'compare'=>'>=');
$meta_query['relation'] = 'AND';
return $meta_query;
}
// The main shop and archives meta query
add_filter( 'woocommerce_product_query_meta_query', 'custom_product_query_meta_query', 10, 2 );
function custom_product_query_meta_query( $meta_query, $query ) {
if( (! is_admin() ) && ((isset($_GET['rem_width'])) || (isset($_GET['rem_length']) ) ))
return custom_meta_query( $meta_query );
}
Thanks
I am making an e-commerce website using WooCommerce. With the help of this forum, I was able to code some useful snippets. However, I am stuck at a certain code now.
I have pieced together codes from various sections, but I am unable to get it to work.
What I want to do - create a custom hidden field programmatically for discount percent & then use the field to allow sorting by discount.
But it looks like the meta does not save in the backend.
When I sort by discount, all I get is this 'No products were found matching your selection.' even though there are some products on sale.
This is my code:
//add_action ('woocommerce_process_product_meta', 'mycode_product_save_discount');
add_action ('woocommerce_admin_process_product_object', 'mycode_product_save_discount');
function mycode_product_save_discount ($product)
{
$product = wc_get_product ($product);
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
if (!empty($sale_price))
{
$discount_percent = round (100 - ($sale_price / $regular_price * 100), 4);
$discount_percent = $_POST['_discount_percent'][$product];
//update_post_meta ($post_id, '_discount_percent', $discount_percent);
$product->update_meta_data ('discount_percent', $discount_percent);
$product->save();
}
}
add_filter ('woocommerce_get_catalog_ordering_args', 'mycode_add_discount_to_ordering_args');
function mycode_add_discount_to_ordering_args ($args)
{
$orderby_value = isset ($_GET['orderby']) ? wc_clean ($_GET['orderby']) : apply_filters ('woocommerce_default_catalog_orderby', get_option ('woocommerce_default_catalog_orderby'));
if (!is_post_type_archive ('product') && !is_shop() && isset($args['orderby']))
{
$orderby_value = $sort_args['orderby'];
}
if ('discount' == $orderby_value)
{
$args['orderby'] = 'meta_value_num';
$args['order'] = 'DESC';
$args['meta_key'] = '_discount_percent';
}
return $args;
}
add_filter ('woocommerce_default_catalog_orderby_options', 'mycode_add_discount_to_orderby');
add_filter ('woocommerce_catalog_orderby', 'mycode_add_discount_to_orderby');
function mycode_add_discount_to_orderby ($sortby)
{
$sortby['discount'] = 'Sort by discount';
return $sortby;
}
What do I need to change to make it work?
You are close, but your code contains some minor mistakes.
This should suffice:
/*** For debugging purposes, remove this action hook if everything works!! ***/
function action_woocommerce_product_options_general_product_data() {
// Text field
woocommerce_wp_text_input( array(
'id' => '_discount_percent',
'label' => __( 'Discount percent', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'For debugging purposes, remove this action hook if everything works', 'woocommerce' ),
'desc_tip' => true,
'custom_attributes' => array( 'readonly' => true ),
));
}
add_action( 'woocommerce_product_options_general_product_data', 'action_woocommerce_product_options_general_product_data', 10, 0 );
/*** From here on the code below is needed so that everything would work smoothly ***/
// Save value
function action_woocommerce_admin_process_product_object( $product ) {
// Getters
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
// NOT empty
if ( ! empty( $sale_price ) ) {
// Calculate
$discount_percent = round( 100 - ( $sale_price / $regular_price * 100 ), 4 );
// Update
$product->update_meta_data( '_discount_percent', $discount_percent );
}
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
// Ordering products based on the selected values
function filter_woocommerce_get_catalog_ordering_args( $args, $orderby, $order ) {
switch( $orderby ) {
case 'discount':
$args['orderby'] = 'meta_value';
$args['order'] = 'ASC';
$args['meta_key'] = '_discount_percent';
break;
}
return $args;
}
add_filter( 'woocommerce_get_catalog_ordering_args', 'filter_woocommerce_get_catalog_ordering_args', 10, 3 );
// Orderby setting
function filter_orderby( $orderby ) {
$orderby['discount'] = __( 'Sort by discount', 'woocommerce' );
return $orderby;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'filter_orderby', 10, 1 );
add_filter( 'woocommerce_catalog_orderby', 'filter_orderby', 10, 1 );
This shows the value after it has been saved. This is not actually necessary, but can be useful for debug purposes.
THis code is working but I need to include single product without a parent grouped product associated
add_action( 'woocommerce_product_query', 'remove_grouped_children' );
function remove_grouped_children( $q ) {
//get current loop query
$taxonomy_query = $q->get('tax_query') ;
//appends the grouped products condition
$taxonomy_query['relation'] = 'AND';
$taxonomy_query[] = array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => array('grouped','variable')
);
$q->set( 'tax_query', $taxonomy_query );
}
This a walk-around, but finally work.
function wr_convert_array_to_ids(){
$products = wr_get_grouped_product_children();
$post_ids = array();
foreach ($products as $product){
foreach ($product as $id){
array_push($post_ids,$id);
}
}
return $post_ids;
}
function wr_get_grouped_product_children(){
global $wpdb;
$products = $wpdb->get_results(
$wpdb->prepare("SELECT * FROM $wpdb->prefix" . "postmeta WHERE meta_key = %s", '_children'),ARRAY_A
);
$products_id = array();
foreach($products as $product){
array_push($products_id, unserialize($product['meta_value']));
}
return $products_id;
}
function wr_custom_get_posts( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
if ( $query->is_archive() || $query->is_shop()) {
$query->set( 'post__not_in', wr_convert_array_to_ids() );
}
}
add_action( 'pre_get_posts', 'wr_custom_get_posts', 1 );
Because the children of grouped products live in the post-meta table below the meta_key _children that is saved as a serialized array, the first thing is to get all the children, then save them in an array and call the 'pre_get_posts' action to exclude those identifiers.
my products have two important codes which are the EAN-13 and its model number. I wrote the EAN-13 in the SKU and the products model number in a custom field. The SKU is perfectly searchable but the data is not.
Is there any way to make a product custom field searchable from the back-end office?
Please help! Thanks in advance!
When I was searching for almost similar problem I've found solution here https://dominykasgel.com/extend-search-custom-post-types-wordpress-admin/, here's my code for functions.php in child theme:
function extend_admin_search( $query ) {
$custom_fields = array(
"_file_name",
);
if( ! is_admin() )
return;
$search_term = $query->query_vars['s'];
$query->query_vars['s'] = '';
$query->set('_meta_or_title', $search_term);
if ( $search_term != '' ) {
$meta_query = array( 'relation' => 'OR' );
foreach( $custom_fields as $custom_field ) {
array_push( $meta_query, array(
'key' => $custom_field,
'value' => $search_term,
'compare' => 'LIKE'
));
}
$query->set( 'meta_query', $meta_query );
};
}
add_action( 'pre_get_posts', 'extend_admin_search', 6, 2);
add_action( 'pre_get_posts', function( $q )
{
if( $title = $q->get( '_meta_or_title' ) )
{
add_filter( 'get_meta_sql', function( $sql ) use ( $title )
{
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modified WHERE
$sql['where'] = sprintf(
" AND ( %s OR %s ) ",
$wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
return $sql;
}, 12, 1);
}
}, 12, 1);
DISCLAIMER: it was used a few years ago, so I can't be sure if it works fine for now.
I am using the hook "pre_get_posts" to query only posts that have featured image in the front page:
add_action( 'pre_get_posts', 'my_pre_get_posts' );
function my_pre_get_posts( $q ){
if ( $q->is_home() // only target homepage
&& $q->is_main_query() // only target the main query
&& !is_admin() // target front end only
) {
$q->set( 'meta_key', array( '_thumbnail_id' ) );
}
}
It looks like this portion is being ignored.
$q->set( 'meta_key', array( '_thumbnail_id' ) );
Your help is appreciated.
You need to check whether '_thumbnail_id' meta_key exists or not. So let's modify your code like this.
add_action( 'pre_get_posts', 'my_pre_get_posts' );
function my_pre_get_posts( $q ){
if ( $q->is_home() // only target homepage
&& $q->is_main_query() // only target the main query
&& !is_admin() // target front end only
) {
$meta_query = array(
array(
'key'=>'_thumbnail_id',
'compare'=>'EXISTS',
),
);
$query->set('meta_query',$meta_query);
}
}