I am trying to create a coupon click counter.
I received the default number of clicks using the code
<?php $couponusers = get_field('coupon_users'); ?>
And I displayed the default number of clicks using the code,
<p><?php echo $couponusers ?></p>
Now, I want to increase the value of ‘coupon_users’ whenever a click is made. Any suggestions on how to do this?
The page I need help with: https://deals.onlinerockershub.com/bluehost-web-hosting/
Add this action to your functions.php
function coupon_callback() {
//
// Add here cookie check
//
if(is_page('1')){ // ID of "Thank you for coupon click" page
update_field('coupon_users',$couponusers); // or similar
}
return;
}
add_filter( 'wp', 'coupon_callback' );
Related
I have a WooCOmmerce Login Page which I am customizing at the moment, by default the login and registration page are in one page. I had seperated the login and registration pages into 2 seperate forms right now. Currently I would like to put a link for the seperated registration page right below the "Forgot Password" link.
But my output is as follows :
I would like for it to appear as follows:
Below is the action hook I am using for my login page.
add_action( 'woocommerce_after_customer_login_form', 'register_link' );
function register_link() {
?>
<div class="woocommerce-register-link">
<p><?php _e( 'Register a new account here' ); ?></p>
</div>
<?php
}
Any help would be much appreciated.
This can be done in multiple ways:
You can edit the template myaccount/form-login.php to insert your code in the right location.
you can use Javascript/jQuery to insert your code in the right location, without editing any template:
// The jQuery Ajax request
add_action( 'wp_footer', 'wc_separated_login_form_js' );
function wc_separated_login_form_js() {
// Only my account for unlogged users
if( ! is_user_logged_in() && is_account_page() &&
'yes' === get_option('woocommerce_enable_myaccount_registration') ):
// Your button html to insert
$html = sprintf(
'<p class="woocommerce-Registerlink register-link">%s</p>',
home_url('/registration/'), // <== Here set your registration link
__( 'Register a new account here')
);
// jQuery
?>
<script type="text/javascript">
jQuery( function($){
$('p.lost_password').after('<?php echo $html; ?>');
});
</script>
<?php
endif;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I have a hidden input field, which I want to fetch in my functions.php, but I keep getting NULL as a return value.
Here is my code:
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data_to_cart', 10, 2 );
function add_custom_field_data_to_cart($cart_item_data, $product_id, $variation_id) {
$cart_item_data['myHiddenInput'] = $_POST['myHiddenInput'];
return $cart_item_data;
}
Can someone maybe tell me why I get NULL ?
EDIT
The hidden input field is on my archive-products.php of my woocommerce-shop
<input type="hidden" name="myHiddenInput" value="">
The value gets set by using javascript
UPDATE
What I want to achive is, that I have an archive-products page where all my products are listed. Now, above my products I have a tab-menu with the next 5 days of the week. So I click the tab "Wednesday 19." the value of the hidden input gets the date of the active menu-tab:
<input type="hidden" name="chosenDate" value="2018-09-19">
Now I add a product to my cart. Then I click the menu-tab "Friday 21." - the value of the hidden filed gets updated -> I add a product to the cart.
Now when I go to my cart page - I want the products to have the dates listed when they will get delivered (the dates from the menu-tab when they were added)
as #LoicTheAztec Said
You can't pass anything custom from any archive page via ajax add to cart button as if you look to the source code of Ajax add to cart… There is no possible additional arguments or hooks. So you will need to build your own Ajax add to cart functionality, which is something huge and complicated. So your hooked function woocommerce_add_cart_item_data will have no effect
so the best logic is to use Javascript to achieve your goal and you can do it like the below solution:
First Lets add those value inside the add to cart button as an attribute instead of input tag.
for that we are going to us woocommerce_loop_add_to_cart_args hook as follow:
add_filter( 'woocommerce_loop_add_to_cart_args', 'change_item_price', 10, 2 );
function change_item_price( $args, $product ) {
$args['attributes'] = $args['attributes'] + [ 'data-chosen-date' => '2018-09-19' ];
return $args;
}
you can add as many attribute as you want and modify the value through your script and then store those value when the user click add to cart intro session storage and then in the cart page you can get those values and append them to cart table so for example:
add_action( 'wp_footer', 'script' );
function script() {
if ( is_shop() ) {?>
<script>
document.body.addEventListener('click', add_to_cart);
function add_to_cart(e) {
if (e.target.classList.contains('add_to_cart_button')) {
let val = e.target.getAttribute('data-chosen-date');
let product_id = e.target.getAttribute('data-product_id');
sessionStorage.setItem(product_id, val);
}
}
</script>
<?php
}
if ( is_cart() ) {
?>
<script>
var items = document.querySelectorAll("td");
items.forEach(function (item, index) {
if (item.classList.contains('product-remove')) {
var id = item.childNodes[1].getAttribute('data-product_id');
if (sessionStorage.getItem(id)) {
var textnode = document.createElement('p');
textnode.innerHTML = sessionStorage.getItem(id);
item.nextElementSibling.nextElementSibling.appendChild(textnode)
}
}
}); </script>
<?php
}
}
output :
The Date after the item link in the cart table has been retrieved from our storage session and each value we stored is maped with the product id as key in our storage session so we can have different value for each product.
I'm creating a custom woocommerce integrated theme for wordpress.
I have a blob on the top that displays the total number of items in the cart, I want to update this blob using Jquery (w/o reloading the page) I was able to increase the number of items by getting the current number in the blob and increasing it by +1 for each click, the problem is the add to cart has an option to select the number of items you want to add to the cart. So if I select 3 items and click the button the blob only increases by one.
I can create a way to get the number of items being added from the front-end but I think it's unnecessary. I want to be able to get the total number from PHP sessions using jquery so that on every click of add item or remove item I'll get the current number dynamically from the server.
What I have done so far is to create a reloadCart.php file that echos the cart total, here's the code
<?php
require('../../../wp-blog-header.php');
global $woocommerce;
echo $woocommerce->cart->get_cart_contents_count();
?>
When I visit this page it echos the current item totals, but I cant get this data from jquery, it's been sometime since I last used AJAX also I have not worked on web projects for a very long time, but with what I remember, the AJAX call that I'm making is right.
I have tried using the get() and post() functions of jquery as well as the normal ajax() function, but nothing seems to work. Can someone please help?
$(".ajax_add_to_cart").click(function () {
/*$("#bag-total").html(function () {
var bagTotal = parseInt($(this).html());
return ++bagTotal;
});*/
alert('clicked');
$.get("<?php echo get_template_directory_uri(); ?>/reloadCart.php", function(data){
alert("Data: " + data);
});
});
The lines that are commented are the ones that I was using previously, to add the cart total by getting the current cart number from the front-end.
Any help would be appreciated. Thanks in advance!
You should not use any reload to update the cart content count… Instead you should use the dedicated woocommerce_add_to_cart_fragments action hook that is Ajax powered.
1) The HTML to be refreshed: So first in your theme's header.php file you should need to embed the cart count in a specific html tag with a defined unique ID (or a class), for example something like:
$items_count = WC()->cart->get_cart_contents_count();
?>
<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>
<?php
or:
$items_count = WC()->cart->get_cart_contents_count();
echo '<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>';
2) The code:
add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_mini_cart_count');
function wc_refresh_mini_cart_count($fragments){
ob_start();
$items_count = WC()->cart->get_cart_contents_count();
?>
<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>
<?php
$fragments['#mini-cart-count'] = ob_get_clean();
return $fragments;
}
if you use a class in your html Tag, you will replace ['#mini-cart-count'] by ['.mini-cart-count']. This hook is also used to refresh the mini-cart content.
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Since few years global $woocommerce; + $woocommerce->cart is outdated and replaced by WC()->cart to access WooCommerce cart object.
If you need jQuery to force refresh that count, you can try wc_fragment_refresh or wc_fragments_refreshed delegated events, like:
$(document.body).trigger('wc_fragment_refresh');
or:
$(document.body).trigger('wc_fragments_refreshed');
For anyone who wants the proper ajax implementation, here is the way to go.
in functions.php
add_action('wp_ajax_cart_count_retriever', 'cart_count_retriever');
add_action('wp_ajax_nopriv_cart_count_retriever', 'cart_count_retriever');
function cart_count_retriever() {
global $wpdb;
echo WC()->cart->get_cart_contents_count();
wp_die();
}
in your script file (assuming you have enqued the script file and passed the ajax object into the script. you also need to put this block into a setInterval or in some other jquery action.
var data = {
'action': 'cart_count_retriever'
};
jQuery.post(ajax_object.ajax_url, data, function(response) {
alert('Got this from the server: ' + response);
});
In header.php or where you want to show count
<?php $items_count = WC()->cart->get_cart_contents_count();
echo $items_count; //use this function for print the value of cart items count
?>
I have not used woocommerce before but one pretty simple option when you say in your post:
When I visit this page it echos the current item totals, but I cant get this data from JQuery
...would be to use a user-sided JavaScript variable for the display, and then just call the PHP update methods for adding items to your cart using AJAX (which I do not show below because you have not provided that code).
<?php
//hardcoded value for $woocommerce->cart->get_cart_contents_count()
$woocommerce = 59;
?>
<button class="ajax_add_to_cart">Add to cart</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
//user sided variable for PHP value
var total = parseInt($(".totalCost").text());
$(".ajax_add_to_cart").click(function(){
total++; //add to cart
$(".totalCost").text(total); //update
});
});
</script>
<p class="totalCost">
<?php echo json_encode($woocommerce); ?>
</p>
You can copy and test this snippet on: http://phpfiddle.org/
Basically in the above code, I set the PHP value as a paragraph text on page load and then read that value into a JS variable to mess around with the data on the client side of the application and then I update the display text as needed.
function woocommerce_header_add_to_cart_fragment( $fragments ) {
$fragments['li.cart-open'] = '<li class="cart-open"><a href="javascript:void(0)" class="cart" title="Cart">
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96" class="svg-large"><switch><g><path d="M68 24v-4C68 8.954 59.046 0 48 0S28 8.954 28 20v4H12v60c0 6.63 5.37 12 12 12h48c6.63 0 12-5.37 12-12V24H68zm-32-4c0-6.627 5.373-12 12-12s12 5.373 12 12v4H36v-4zm40 64c0 2.21-1.79 4-4 4H24c-2.21 0-4-1.79-4-4V32h56v52z"/></g></switch></svg>
<i>'.WC()->cart->get_cart_contents_count().'</i>
</a></li>';
return $fragments;
}
Trying to achieve something that should be simple, but I've tried 3 approaches with multiple code variations and I just can't make it work. I'm trying to create a button that will appear in place of the "ADD TO CART" button on single product pages when the item is out of stock. Clicking the button will fire a popup contact form.
Is creating an add action in functions the right way to go, or should I replace the normal button with an if statement? I've tried both, so help with coding either would be greatly appreciated.
You can either hook into woocommerce_loop_add_to_cart_args using a filter in your functions.php or edit the template file directly by pulling it into your theme. Either way will require a bit of PHP.
If doing it in your functions.php, it would look something like this (untested but should send you down the right path):
<?php
add_filter( 'woocommerce_loop_add_to_cart_link', 'my_out_of_stock_button' );
function my_out_of_stock_button( $args ){
global $product;
if( $product && !$product->is_in_stock() ){
return 'Contact us';
}
return $args;
}
I don't know what your button code should actually look like or what other information you need to capture, but this is how you could override the "Add to Cart" button and replace it if out of stock.
UPDATE
LoicTheAztec brought up a great point - the filter provided only affects the button on the archive, category, tag overview pages - not the individual product pages. There are no hooks for the individual product page buttons BUT you can copy the templates to your theme and override them.
You'll want to look at the files in templates/single-product/add-to-cart. Use a similar if statement as above:
#simple.php
<?php if ( $product->is_in_stock() ) : ?>
// Standard WooCommerce code
<?php else: ?>
// Your button code
<?php endif; ?>
Just add below code in functions.php file of your enabled theme reference
add_action('woocommerce_after_shop_loop_item', 'themelocation_change_outofstock_to_contact_us', 1);
// for shop page
function themelocation_change_outofstock_to_contact_us() {
global $product;
if (!$product->is_in_stock()) {
remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart');
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart');
//change the link to your contact us page
echo ' Contact Us ';
}
}
// for single page
add_filter('woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability($availability, $_product) {
// Change In Stock Text
if ($_product->is_in_stock()) {
$availability['availability'] = __('Available!', 'woocommerce');
}
// Change Out of Stock Text
if (!$_product->is_in_stock()) {
$availability['availability'] = __(' Contact Us ', 'woocommerce');
}
return $availability;
}
I was looking for a way to show a contact button on bespoke products and
#ahwychkchih solution works great. One issue I had though is that schema markup will show as out of stock for those products which is not the case for beskpoke products is just they can't be purchased straight away so I've added this to force in_stock markup for my products. I'm aware that this solution would affect all products so you can always add a product id filter if needed
// Force In Stock schema markup
function fix_my_product_offers_schema ($markup_offer, $product) {
if (!$product->is_in_stock()) {
$markup_offer['availability'] = 'https://schema.org/InStock';
}
return $markup_offer;
}
add_filter('woocommerce_structured_data_product_offer', 'fix_my_product_offers_schema', 1, 2);
What I want to do is really simple but I'm obviously not great and very new to PHP. I'm using woocommerce for my store and a woocommerce add on called "woocommerce scheduler" to set a start and end time specific products are for sale each day.
The way the scheduling program works is you set start and end times with 24hr clock example 10am (10:00) to 8pm (20:00) the product can be purchased anytime from 8am-10pm after 10pm the plugin "hides" the add to cart button ans displays a custom message such as "Currently Unavailable" and you can't purchase the item.
I ran into 2 problems one of which is solved
I wanted the plugin to show the start time the product would become available with the unavailable message basically it would say "unavailable until 8am"
So the solution to that problem was a plugin called Advanced Custom Fields
and creating a custom field that I can set on the product page and then I can display by putting this php code if the feild is empty on another product page it isn't displayed <?php if( get_field('product_time') ): ?>
<p>Available at <?php the_field('product_time'); ?></p>
<?php endif; ?>
into my single product page template file.
I got that working just fine. Now my second issue that I can't solve.
I want to hide the code that shows the time when the unavailable message is hidden because the product is in the hours where it is available for purchase. So how would I go about this?
I found the bit of code that pulls the unavailable message but it is a js. file so I cant put the php I have into that file.
wdm_validate.js
jQuery(document).ready(function(){
jQuery('.cart').html('<p class = "wdm_message3">'+wdm_message.wdm_expiration_message+' </p>');
});
this is the bit in the php file for the scheduler plugin that calls that js file
woocommerce_scheduler.php
if($wdm_start_date <= $d && $d<=$wdm_end_date && $str_start_time <=
$curtime && $curtime <= $str_end_time) {
}else{
//echo "<style>.cart{display:none;}</style>";
//echo "hello";
//exit;
wp_enqueue_script('wdm_expiration_message',plugins_url('js/wdm_validate.js',__FILE__),
array('jquery'));
$data = array(
'wdm_expiration_message' => get_option( 'woocommerce_custom_product_expiration',true )
);
wp_localize_script('wdm_expiration_message','wdm_message',$data);
}
In your custom code just add class to <p> tag and perform following:-
<?php if( get_field('product_time') ): ?>
<p class='wdm_available'>Available at <?php the_field('product_time'); ?></p>
<script>
jQuery(document).ready(function(){
//checking wdm_message3 i.e. expiration message exist or not
if(!jQuery('.wdm_message3').is(':visible')){
jQuery('.wdm_available').hide();
}
});
</script>
<?php endif; ?>
adding this code to my price.php template page in woocommerce got me exactly what I needed. The time is hidden when the product is available and shows when the item is not available for sale letting my customer know what time they can purchase it.
<?php if( get_field('product_time') ): ?>
<p class='wdm_available'>Unavailable Until <?php the_field('product_time'); ?></p>
<script>
jQuery(document).ready(function(){
// set a timeout function to get around brief delay in scheduler script
setTimeout(function(){
//check if scheduler message is NOT visible
if(!jQuery('.wdm_message3').is(':visible')) {
// if not, hide custom availabilty time message
jQuery('.wdm_available').hide();
}
}, 0);
});
</script>
<?php endif; ?>
There's no way for me to know the format of your custom field, but you should be able to run a comparison against the current time. As an idea:
$current_time = time();
$sale_time = get_field('product_time');
if( $sale_time && $sale_time < $current_time ): ?>
<p class='wdm_available'>Unavailable Until <?php the_field('product_time'); ?></p>
<?php endif; ?>