Need "Sale To Date" On Woo Commerce Category Page

I want to add the "sale to date" on my on-sale category page for each product.  I have put together this function but it doesn't seem to be getting any values so please tell me what is wrong.  My Woo Commerce version is 3.4.4

add_filter( 'get_date_on_sale_to', 'custom_price_html', 100, 2 );
function custom_price_html( $price, $product )
{
    global $post;
    $sales_price_to = get_post_meta($post->ID, $data['date_on_sale_to'], true);
    if(is_product_category( 'on-sale' ) && ($sales_price_to != ""))
    {
        $sales_price_date_to = date("j M y", $sales_price_to);
        return str_replace( '</ins>', ' </ins> <b>(Offer till '.$sales_price_date_to.')</b>', $price );
    }
    else
    {
        return apply_filters( 'woocommerce_get_price', $price );
    }
}

Open in new window

sharingsunshineAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
Your code on line 5 is not correct:
$sales_price_to = get_post_meta($post->ID, $data['date_on_sale_to'], true);

Open in new window


The $data array seems to be added in error (it is not defined) and the function "get_post_meta" expects a STRING value as the 2nd argument. Therefore, change the above line of code to:
$sales_price_to = get_post_meta($post->ID, 'date_on_sale_to', true);

Open in new window


This assumes that you have a custom field with the name:
date_on_sale_to
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
Let me know if this works. If it does not work, I will show you how to troubleshoot in order to find the incorrect code.
0
sharingsunshineAuthor Commented:
that didn't work and it isn't a custom field.  Please see screenshot

https://gyazo.com/88d817384008aa2938e04b6cb5594bbe
0
Build an E-Commerce Site with Angular 5

Learn how to build an E-Commerce site with Angular 5, a JavaScript framework used by developers to build web, desktop, and mobile applications.

sharingsunshineAuthor Commented:
I found this code but it won't output on the category page even trying to change the hook.

This will show the code on the single page
add_filter( 'woocommerce_get_price_html', 'custom_price_html', 100, 2 );
function custom_price_html( $price, $product )
{
    global $post;
    $sales_price_to = get_post_meta($post->ID, '_sale_price_dates_to', true);
    if(is_single() && $sales_price_to != "")
    {
        $sales_price_date_to = date("j M y", $sales_price_to);
        return str_replace( '</ins>', ' </ins> <b>(Offer till '.$sales_price_date_to.')</b>', $price );
    }
    else
    {
        return apply_filters( 'woocommerce_get_price', $price );
    }
}

Open in new window

I need it to output on the category page and the single page.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
Hello,

You say "This will show the code on the single page" and that is because you have the following code on line 6:

 if(is_single() && $sales_price_to != "")

Open in new window


You need to remove the is_single() condition from your if statement. So Just change that line of code to:

 if($sales_price_to != "")

Open in new window

0
sharingsunshineAuthor Commented:
Thanks for your help.  However, when I make that change I get this error:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function custom_price_html(), 1 passed in C:\xampp\apps\wordpress\htdocs\wp-includes\class-wp-hook.php on line 286 and exactly 2 expected in C:\xampp\apps\wordpress\htdocs\wp-content\themes\flatsome-child\functions.php:5 Stack trace: #0 C:\xampp\apps\wordpress\htdocs\wp-includes\class-wp-hook.php(286): custom_price_html('') #1 C:\xampp\apps\wordpress\htdocs\wp-includes\class-wp-hook.php(310): WP_Hook->apply_filters('', Array) #2 C:\xampp\apps\wordpress\htdocs\wp-includes\plugin.php(453): WP_Hook->do_action(Array) #3 C:\xampp\apps\wordpress\htdocs\wp-content\themes\flatsome\woocommerce\content-product.php(87): do_action('woocommerce_aft...') #4 C:\xampp\apps\wordpress\htdocs\wp-includes\template.php(690): require('C:\\xampp\\apps\\w...') #5 C:\xampp\apps\wordpress\htdocs\wp-content\plugins\woocommerce\includes\wc-core-functions.php(179): load_template('C:\\xampp\\apps\\w...', false) #6 C:\xampp\apps\wordpress\htdocs\wp-content\themes\flatsome\woocommerce\layout in C:\xampp\apps\wordpress\htdocs\wp-content\themes\flatsome-child\functions.php on line 5

Open in new window


Here is my code that I have in functions.php in the child theme.

<?php
// Add custom Theme Functions here
//add_filter( 'woocommerce_get_price_html', 'custom_price_html', 100, 2 );
add_filter( 'woocommerce_after_shop_loop_item', 'custom_price_html', 100, 2 );
function custom_price_html( $price, $product )
{
    global $post;
    $sales_price_to = get_post_meta($post->ID, '_sale_price_dates_to', true);
    //if(is_single() && $sales_price_to != "")
	if($sales_price_to != "")
	
    {
        $sales_price_date_to = date("m/d/y", $sales_price_to);
        return str_replace( '</ins>', ' </ins> <b>(Expires '.$sales_price_date_to.')</b>', $price );
    }
    else
    {
        return apply_filters( 'woocommerce_get_price', $price );
    }
}

Open in new window

0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
Your error "Too few arguments to function custom_price_html(), 1 passed" means you have this line of code somewhere:
custom_price_html(myprice)

The error message tells you this is happening in C:\xampp\apps\wordpress\htdocs\wp-includes\class-wp-hook.php on line 286

This is wrong because your function requires two arguments:
custom_price_html(myprice, myproduct)

You can fix this by redefining your function OR by setting DEFAULT VALUES. At the moment your function is not referencing $product so it would be best practice to remove this from your function declaration.

Therefore change this line of code:
function custom_price_html( $price, $product )

Open in new window


to the following declaration with one parameter:
function custom_price_html( $price)

Open in new window


If that gives you a similar error message, try using this declaration with two parameters using default values:
function custom_price_html( $price=0, $product=0)

Open in new window


If you need to use default values that means somewhere  in your code is calling the function with one parameter and somewhere else in your code it is calling the function with two parameters so your code is inconsistent. It would be best to make everything consistent... but default values will fix the error.
0
sharingsunshineAuthor Commented:
I made the changes as you suggested and the error goes away but it doesn't put the date on the category page like I need.  Looking over the Woo Commerce classes it seems it would be better to use the Product class I just don't know how to access what is needed.

https://gyazo.com/8d9121236447cb6ca5ba6b4a1009c521
This seems to be a more direct approach to get the date for each product.

this seems to be more information - https://gyazo.com/f7c113bbe539d82d68e6b46d804c2707

I really want to learn how to grab this data like I did using your sql function for the QV.  So, if you can get me going that way I would appreciate it.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
You say "but it doesn't put the date on the category page like I need". Please can you explain?

For example, what is the current output? Is it the wrong date, a number, bad formatting or something else?

I can help you with an SQL statement but using the built in function get_post_meta is usually the most efficient way to go.
0
sharingsunshineAuthor Commented:
I'm sorry not to be more specific.  It actually doesn't have any output on the category page.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
The first task in debugging would be to make sure you are able to actually output something to the page.

can you remove all your code and replace with this just to make sure the output is visible:

<?php
add_filter( 'woocommerce_after_shop_loop_item', 'custom_price_html', 100, 2 );
function custom_price_html( $price=0, $product=0)
{
     return "hello! output is working with product ".$product." and price ".$price;
}

Open in new window


You need to check that "hello! the output is working" appears where you want it (i.e. on your product page AND your category page). If this is working fine, then we can move on with confidence that all we need to do is acquire the correct "sale to date" for you.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
I edited my comment above to include the $price and $product in the output. Please reply here to let me know what the output is. For example, if the output is "hello! output is working with product 0 and price 0" then the parameters are missing in your function calls.
0
sharingsunshineAuthor Commented:
Using your edited content, nothing is showing on the category or the single product page.  I also commented out every function in functions.php to test it too.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
This shows the problem is not with getting the date. Rather, the problem is with the output of your function.

Please can you confirm that you only commented out your functions in functions.php? If you also commented out other functions used by your theme, that can cause it to stop working.
0
sharingsunshineAuthor Commented:
my theme doesn't have anything in it but custom functions.  Here is my code:

<?php
// Add custom Theme Functions here
//add_filter( 'woocommerce_get_price_html', 'custom_price_html', 100, 2 );
//add_filter( 'woocommerce_after_shop_loop_item', 'custom_price_html', 100, 2 );
//function custom_price_html( $price, $product )
/*function custom_price_html( $price)
{
    global $post;
    $sales_price_to = get_post_meta($post->ID, '_sale_price_dates_to', true);
    //if(is_single() && $sales_price_to != "")
	if($sales_price_to != "")
	
	
    {
        $sales_price_date_to = date("m/d/y", $sales_price_to);
        return str_replace( '</ins>', ' </ins> <b>(Expires '.$sales_price_date_to.')</b>', $price );
    }
    else
    {
        return apply_filters( 'woocommerce_get_price', $price );
    }
}

add_action ('woocommerce_before_order_notes', 'member_note', 10); 
function member_note (){
$code = <<< EOT
<button style= "background-color:green; color:white;" onclick="myFunctionMember()">MEMBERSHIP</button>
<script>
function myFunctionMember() {
    document.getElementById("order_comments").innerHTML = "I want membership";
}
</script>
EOT;
echo $code;
}

add_action ('woocommerce_review_order_after_cart_contents', 'display_item_qv', 10);



function display_item_qv () {

        if ( ! is_ajax() ) {


        global $wpdb;

        //$wpdb->show_errors = TRUE;
//$wpdb->suppress_errors = FALSE;

        $val = 0;

        foreach( WC()->cart->get_cart() as $cart_item ) {

   $product_in_cart = $cart_item['product_id'];


$item_qv = $wpdb->get_row("

SELECT DISTINCT
    p.id AS 'Product ID',
    p.post_title AS 'Product Name',
    t.name AS 'QV'
FROM
        wp_posts AS p
INNER JOIN
    wp_term_relationships AS tr ON p.id = tr.object_id
INNER JOIN
        wp_term_taxonomy AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
INNER JOIN
    wp_terms AS t ON t.term_id = tt.term_id
WHERE
        tt.taxonomy='pa_qv'
AND
        p.post_type = 'product'

AND id=$product_in_cart", ARRAY_N);



$val += $item_qv[2] * $cart_item['quantity'];
        //echo $item_qv[2];
        //echo "<pre>";
        //print_r($item_qv);
        //echo "</pre>";

        }
//echo "The total is ". $val;

include_once "qv_contest.php";

        //print_r($item}
}

}
*/

add_filter( 'woocommerce_after_shop_loop_item', 'custom_price_html', 100, 2 );
function custom_price_html( $price=0, $product=0)
{
     return "hello! output is working with product ".$product." and price ".$price;
}

Open in new window

0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
great. okay, please delete the 5 lines I gave you and replace with this. let me know if you get an output:

function custom_price_html()
{
     echo "hello! output is working";
}
add_action('woocommerce_after_shop_loop_item','custom_price_html',10,0);

Open in new window

0
sharingsunshineAuthor Commented:
I get output on every product in the category and nothing on the single page.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
excellent. that is what the function is supposed to do because you are hooking into "woocommerce_after_shop_loop_item"

The "loop_item" is referring to the products that are listed (looped) in your category page so this will never show on your single page. I will take a look and see if we can now find a more suitable hook from the list:
https://docs.woocommerce.com/wc-apidocs/hook-docs.html
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
got it! delete the code I gave you last time and replace with this:

function custom_price_html_single()
{
     echo "<h3>### OUTPUT FOR SINGLE PRODUCT ###</h3>";
}
add_action('woocommerce_after_single_product_summary','custom_price_html_single',10,0);

function custom_price_html_category()
{
     echo "<h3>### OUTPUT FOR CATEGORY PRODUCT ###</h3>";
}
add_action('woocommerce_after_shop_loop_item','custom_price_html_category',10,0);

Open in new window

0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
if you are happy with the location of each output on both the category page and the single product page, all that is left to do is change the lines of code starting "echo ...." to show the end of sale date instead of our debug text
0
sharingsunshineAuthor Commented:
it's not showing on the single product page but it is the category page.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
are you sure? because this is very basic code that should always work and I even have it running in my test site right now. It may be lower down the page on your single product page. try scrolling down or try doing a search for  ### OUTPUT in your source code as maybe the font is white on white. In other words, it may be difficult to find or even invisible due to font colour but it should be there.
0
sharingsunshineAuthor Commented:
You are correct, it was much further down.  As far as changing it, that is where I get hung up.  Looking at this code

$sales_price_date_to = date("j M y", $sales_price_to);
        return str_replace( '</ins>', ' </ins> <b>(Offer till '.$sales_price_date_to.')</b>', $price );

Open in new window


It is used to output the date but this comes up blank because I need to access a class to get this answer don't I?
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
here is everything you need:

function custom_price_html_single()
{	
	global $post;
	$sales_price_to = get_post_meta($post->ID, '_sale_price_dates_to', true);
	if(strlen($sales_price_to)>0){
		$sales_price_to_date = date("j M y",$sales_price_to);
    	echo "<h3>SALE ENDS: ".$sales_price_to_date."</h3>";
	}else{
		echo "<h3>NOT ON SALE</h3>";
	}
}
add_action('woocommerce_after_single_product_summary','custom_price_html_single',10,0);

function custom_price_html_category()
{
	global $post;
	$sales_price_to = get_post_meta($post->ID, '_sale_price_dates_to', true);
	if(strlen($sales_price_to)>0){
		$sales_price_to_date = date("j M y",$sales_price_to);
    	echo "<h3>SALE ENDS: ".$sales_price_to_date."</h3>";
	}else{
		echo "<h3>NOT ON SALE</h3>";
	}
}
add_action('woocommerce_after_shop_loop_item','custom_price_html_category',10,0);

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sharingsunshineAuthor Commented:
That is perfect. Thanks so much.
0
Adrian ThompsonConsultant for Website Development and Online MarketingCommented:
Glad to help! Have a nice day
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.