I have a full website that I've built already. I have now installed Wordpress in a subdirectory (/shop) and I'm using WooCommerce to power the sale of products.
In the top menu bar while in the shop page I have a cart icon showing the number of products in the cart.
I would like that when the user clicks back into the non-Wordpress pages of the site to continue showing the number of items in the cart. Can someone point me in the right direction? I have tried to include the main class-woocommerce.php class but it's not working.
Here's what I have been using to test in my index.php file:
include 'shop/wp-content/plugins/woocommerce/includes/class-woocommerce.php';
global $woocommerce;
var_dump($woocommerce->cart);
EDIT:
I have now included wp-load.php instead of the class-woocommerce.php and when I dump the WooCommerce cart I can see it but it's completely empty, ie has 0 items even though I had items placed in the cart.
Update:
This could be done also setting a custom cookie or better using javascript session storage this way:
add_action('wp_footer', 'custom_cart_item_count_script');
function custom_cart_item_count_script(){
if( WC()->cart->is_empty() )
$cart_count = 0;
else
$cart_count = WC()->cart->get_cart_contents_count();
if(isset($cart_count)){
?>
<script type="text/javascript">
jQuery(function($){
var cartCount = <?php echo $cart_count; ?>,
csName = 'CARTCOUNT',
csStorage = sessionStorage.getItem(csName);
if(csStorage == null || csStorage == 'undefined'){
sessionStorage.setItem(csName, cartCount);
console.log(sessionStorage.getItem(csName));
}
});
</script>
<?php
}
}
This code goes in function.php file of your active child theme (or active theme).
Tested and works.
On your non Wordpress pages:
You will need to get this browser session storage value. so you will add something like the following in your non Wordpress pages:
?>
<script type="text/javascript">
jQuery(function($){
var caName = 'CARTCOUNT',
caStorage = sessionStorage.getItem(caName);
if(caStorage == null || caStorage == 'undefined')
$('span.cart-count').html('0');
else
$('span.cart-count').html(caStorage);
console.log('css-read: '+caStorage);
});
</script>
<p>Cart count: <span class="cart-count"></span></p>
<?php
Tested and works:
Related
I'm creating a WooCommerce store with variable products only. When creating new products I always need to manually change the Product Data to Variable Product. When you have hundreds of products, this is becoming kind of a pain :)
I've searched around the Internet but wasn't able to find anything...
<php?
// Code here
?>
I'm looking for a PHP snippet to set Variable Product as default when creating new products, any ideas?
Updated - The following code will select "variable" by default on the product type selector in backend for new product pages:
add_action( 'admin_footer', 'product_type_selector_filter_callback' );
function product_type_selector_filter_callback() {
global $pagenow, $post_type;
if( $pagenow === 'post-new.php' && $post_type === 'product' ) :
?>
<script>
jQuery(function($){
$('select#product-type').val('variable').change();
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
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;
}
What I am trying: Show the Variation Description of the Child of a Variable Product on single product page in the product tab description area.
In WooCommerce and variable products the parent has the description which is stored in wp_posts->post_content and every child has an additional _variation_description field. On the frontent the description of the parent is always visible and the _variation_description of the Child is showing as a variation is selected. It gets updated with js and is displayed before the add to cart button together with the price of the variation.
The description is called in description.php with the code
the_content();
which outputs the parent products post_content db field.
The variation description is called in variation.php with the code
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
</script>
As I understand this works with wp.template and I also checked the info on Javascript Reference wp.template
The js is in add-to-cart-variation.js and the template is built with
template = wp.template( 'variation-template' );
Then the data can be updated which I do not really understand in detail. What I understand is that all the js calls are in the form,
form.$singleVariation.html( $template_html );
so then I realized why I couldn't just copy the code from variation.php and paste it to description.php because there it would be outside the form tag.
On the other hand the data for SKU is not called from within the form, it is called through .product_meta so if I put a div with class="product_meta" I can call the sku and have it updated with js from anywhere. For example I can put this code into description.php
<div class="product_meta">
<?php if ( wc_product_sku_enabled() && ( $product->get_sku() || $product->is_type( 'variable' ) ) ) : ?>
<?php if ( $sku = $product->get_sku() ) : ?>
<span class="sku_wrapper"><?php esc_html_e( 'SKU:', 'woocommerce' ); ?>
<span class="sku" itemprop="sku"><?php echo $sku; ?></span></span>
<?php endif; ?>
<?php endif; ?>
</div>
and it works fine.
So here I am stuck. I just want to have the variation description displayed dynamically in the description.php and I thought if I understand how the wp.template works in add-to-cart-variation.js I could figure it out. But I can't. I do not exactly understand how the content is being updated in the variation form and what the difference is to the data in SKU.
Maybe there is a totally simple and easy solution for what I want, and maybe my approach is too complicated. I would be very glad for any Ideas or hints or just pointing in the right direction.
This can be done with some jQuery code, where we will copy the variation description to the variable product description tab. But first you need to make some very small changes on some templates.
Here is the official docs related to: Template structure & Overriding templates via a theme
The templates changes and the necessary code:
On single-product/tabs/description.php template file, you will replace the line:
<?php the_content(); ?>
by the following line (We just add a surrounding html <div> tag with a selector class):
<div class="product-post-content"><?php the_content(); ?></div>
On single-product/add-to-cart/variation.php template file, you will replace the line:
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
by the following line (we just hide the variation description):
<div class="woocommerce-variation-description" style="display:none;">{{{ data.variation.variation_description }}}</div>
Now the jQuery (commented) code (on single product pages for variable products only):
add_action( 'wp_footer', 'move_variation_description' );
function move_variation_description(){
global $product;
// Only on single product pages for variable products
if ( ! ( is_product() && $product->is_type('variable') ) ) return;
// jQuery code
?>
<script type="text/javascript">
jQuery(function($){
a = '.woocommerce-variation-description', b = a+' p', c = 'input.variation_id',
d = '#tab-description .product-post-content', de = $(d).html();
// On load, adding a mandatory very small delay
setTimeout(function(){
// variation ID selected by default
if( '' != $(c).val() && $(a).text() != '' )
$(d).html($(a).html());
}, 300);
// On live event (attribute select fields change)
$('table.variations select').on( 'blur', function(){
// variation ID is selected
if( '' != $(c).val() && $(a).text() != '' ){
$(d).html($(a).html()); // We copy the variation description
}
// No variation ID selected
else {
$(d).html($(a).html()); // We set back the variable product description
}
console.log($('input.variation_id').val()); // TEST: Selected variation ID … To be removed
});
});
</script>
<?php
}
This code goes on function.php file of your active child theme (or active theme).
Tested and works.
Other related threads:
Replace the Variable Price range by the chosen variation price in WooCommerce 3
Get the selected product variation ID in WooCommerce variable products single pages
Variable product selectors: Getting the live selected values
I need to hide the shop and products in the header (shop page).
Add class shoppage in menu link from admin panel. add below the code in header.php
<?php
if(is_shop()){
echo "<style>.shoppage{display:none !important}</style>";
}
?>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
var url = $(location).attr('href'),
parts = url.split("/"),
last_part = parts[parts.length-2];
if(last_part == 'shop')
{
$('#menu-item-15').hide();
}
});
</script>
Add this into your theme's footer.php and replace the #menu-item-15 with your shop menu's id you can check the menu id with Firebug please check image http://prntscr.com/flxk27
In WooCommerce, My Category Listing page and product listing page are rendered from archieve-product.php ( By Default) . How to check if page is_shop() in functions.php? As is_shop function does not work in functions.php. I simply want to remove my sidebar from Category listing page not from product listing page.
When placed inside a hook, is_shop will work in functions.php
add_action( 'template_redirect', 'custom_template_redirect' );
function custom_template_redirect() {
if( is_shop() ) :
// code logic here
endif;
}
Here is a list of all WooCommerce conditionals
You can write a condition into "archive-product.php" for category page like,
$cate = get_queried_object();
if(is_product_category() && $cate->parent != 0 ){
// Write code here
//include sidebar here
}
By using this code this will check the page for product_category and also check for a parent.
call it using WordPress Hook pre get posts
add_action('pre_get_posts','nameTheFunction');
function nameTheFunction(){
if(is_shop()){
// your code here
}
}// function end here
Read more about pre get posts Hook
https://developer.wordpress.org/reference/hooks/pre_get_posts/
You can use function_exists
if( function_exists("is_shop") ) {
// call it or do something else
}
else {
// load it from somewhere
}
Official docs: https://secure.php.net/function_exists