WooCommerce Price Overriding in Cart Dynamically - wordpress

Let me explain clearly i have created one table in database with columns( bed_type, dimensions*thickness, price, ).refer image by default single is selected with dimension and thickness as shown in image now user can select select any bed type,dimension and thickness so according to that price will change I am sending ajax request to database if condition matched then i am getting price in this paragraph
<p class='prices' id='demo' style='margin-left:22%;'></p>
now i want to pass the calculated price in cart how can i achieve this. I am trying this task from last week but not getting any result. please guide me
Ajax for Bed Type
function price()
{
var current_id=this.id;
var dimension = document.getElementById(current_id).value; // dimension
var thickness = document.getElementById("thickness").value;
var res = dimension.concat('x'+thickness);
jQuery.ajax({
url: "/Mattressbox/price",
data: {price: res},
type: "POST",
success:function(data){
$("#result").html(data);
},
error:function (){}
});
}
price.php code
global $wpdb;
if(isset($_POST['price']))
{
$price_value = $_POST["price"];
$result = $wpdb->prepare("SELECT price FROM wp_single WHERE size='".$price_value ."'",$id,null);
$row = $wpdb->get_row($result);
$price = $row->price;
if($price > 0)
{
echo '<script>';
echo 'var name = ' . json_encode($price) . ';';
echo 'document.getElementById("demo").innerHTML ="₨ " + name;';
echo '</script>';
}
else
{
//echo "failed";
}
}
in this paragraph i am getting dynamic price using ajax
<p class='prices' id='demo' style='margin-left:22%;'></p>
now i am trying to pass this paragraph in place of custom price like this
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = "<p class='prices' id='demo' style='margin-left:22%;'></p>"; // This will be your custom price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom;
}
}
only static price is going in cart but this is not working please suggest something...thank you..

Related

Showing "Out of Stock" text next to variation in Woocommerce product with multuiple variations

I have been looking EVERYWHERE and I cannot seem to find a solution to a very simple problem. I have a Woocommerce store and I want to show to the user a message "Out of stock" next to the variation if it is out of stock. I do not want it grayed out, I want the user to be able to select it so they can view the price if they wish. Most snippets I find online only works when they product has ONE variation but I need it to work for at least two. My website sells mobile devices so for example:
If a user selects the storage as 64GB then the color list updates showing which colors are out of stock in 64GB. If all colors are out of stock then next to 64GB it shows "Out of stock" also.
If the color is selected first, then the storage - the color list is then updated with what is out of stock.
Can anyone help me out here? Going insane trying to get this working. The below code works to gray out out of stock products in the exact way I mentioned above (it works for multiple products) but I can't figure out how to modify it for the use case mentioned above.
add_filter( 'woocommerce_variation_is_active', 'grey_out_variations_when_out_of_stock', 10, 2 );
function grey_out_variations_when_out_of_stock( $grey_out, $variation ){
if ( ! $variation->is_in_stock() ){
return false;
}else{
print_r($option_class);
return $term_name . ' - Out of Stock';;
}
}
You can check the availability of a product variation only if all but one of the attributes have been selected, not before.
All the necessary data is present on the product page and therefore you can use a jQuery script to process it.
In the variation form there is the data-product_variations attribute which contains an array with all the details of the product variations (variation id, stock status, attributes it uses, etc ...).
You can then make a comparison between the selected attributes and possible product variations.
The idea is this:
Check that there is more than one attribute (dropdown) on the product page
If all attributes (dropdowns) have been selected except one, get the attribute slug and the attribute value of the selected options
It compares them with the attributes that each single variation uses and, if the selected attributes are the same, gets the stock status of the last attribute to be selected
Adds the text "Out of stock" to each option whose product variation is not in stock. To do this it will use the woocommerce_update_variation_values event which fires after updating the options via Ajax (otherwise the changes will be overwritten)
The following code will work for 2 or more attributes (dropdowns) in
the variable product page.
// add the text "Out of stock" to each option of the last unselected attribute dropdown
add_action( 'wp_footer', 'add_out_of_stock_text_to_the_last_unselected_attribute_dropdown' );
function add_out_of_stock_text_to_the_last_unselected_attribute_dropdown() {
?>
<script type="text/javascript">
// initializes a global variable that will contain the attribute values to be updated ("Out of stock")
let globalAttributesToUpdate;
jQuery(function($){
// check if only one attribute is missing to be selected
function isLastAttribute(){
// if there is only one dropdown it returns false
if ( $('form.variations_form select').length == 1 ) {
return false;
}
// counts all selected attributes (excluding "Choose an option")
let count = 0;
$('form.variations_form select').each(function(){
if ( $(this).find(':selected').val() ) {
count++;
}
});
// if an attribute has not yet been selected, it returns true
if ( $('form.variations_form select').length - count == 1 ) {
return true;
} else {
return false;
}
}
$('form.variations_form select').change(function() {
if ( isLastAttribute() ) {
// clear the global variable every time
globalAttributesToUpdate = [];
let attrToFind = {}; // contains an object with slug and value of the selected attributes
let attrToSet; // contains the slug of the attribute not yet selected
$('form.variations_form select').each(function(index,object){
if ( $(this).find(":selected").val() ) {
attrToFind[$(this).data('attribute_name')] = $(this).find(":selected").val();
} else {
attrToSet = $(this).data('attribute_name');
}
});
// gets the value of the "data-product_variations" attribute of the variations form
let variationData = $('form.variations_form').data("product_variations");
$(variationData).each(function(index,object) {
let attrVariation = object.attributes;
let attrVariationLenght = Object.keys(attrVariation).length;
let found = 0;
let toSet;
let valueToSet;
// check all possible combinations of attributes (for single variation)
// based on the selected attributes
$.each( attrVariation, function( attr, value ) {
if ( attr in attrToFind && attrToFind[attr] == value ) {
found++;
} else {
// if the variation is out of stock it gets slug and value to add the text "Out of stock"
if ( object.is_in_stock == false ) {
toSet = attr;
valueToSet = value;
}
}
});
// if only one attribute is missing
if ( attrVariationLenght - found == 1 ) {
if ( toSet == attrToSet ) {
let obj = {};
obj[toSet] = valueToSet;
globalAttributesToUpdate.push(obj);
}
}
});
}
});
// inserts the text "Out of stock" after updating the variations
// based on the "globalAttributesToUpdate" global variable
$('body').on('woocommerce_update_variation_values', function(){
if ( globalAttributesToUpdate !== undefined && globalAttributesToUpdate.length ) {
$.each( globalAttributesToUpdate, function( key, attribute ) {
$.each( attribute, function( attrName, attrValue ) {
$('select[name='+attrName+'] > option[value="'+attrValue+'"]').append( " (Out of stock)" );
});
});
}
});
});
</script>
<?php
}
The code has been tested and works. Add it to your active theme's functions.php.
RESULT
RELATED ANSWERS
How to add variation stock status to Woocommerce product variation dropdown
Show stock status next to each attribute value in WooCommerce variable products
Display variation stock status on single dropdown variable products in Wocommerce 3
add_filter('woocommerce_variation_option_name', 'display_price_in_variation_option_name');
function display_price_in_variation_option_name($term)
{
global $wpdb, $product;
$result = $wpdb->get_col("SELECT slug FROM {$wpdb->prefix}terms WHERE name = '$term'");
$term_slug = (!empty($result)) ? $result[0] : $term;
$query = "SELECT postmeta.post_id AS product_id
FROM {$wpdb->prefix}postmeta AS postmeta
LEFT JOIN {$wpdb->prefix}posts AS products ON ( products.ID = postmeta.post_id )
WHERE postmeta.meta_key LIKE 'attribute_%'
AND postmeta.meta_value = '$term_slug'
AND products.post_parent = $product->id";
$variation_id = $wpdb->get_col($query);
$parent = wp_get_post_parent_id($variation_id[0]);
if ($parent > 0) {
$_product = new WC_Product_Variation($variation_id[0]);
$_currency = get_woocommerce_currency_symbol();
$stock = $_product->is_in_stock() ? 'instock' : 'out of stock';
return $term . ' (' . $_product->get_price() . ' ' . $_currency . ') - ' . $stock;
}
return $term;
}

Display default and selected variation price from a woocommerce variable product

I've been looking over Stack for an answer but can't find one (even when reading this and this)
Here my trouble: i would like to display (or at least get the variable) of the default and selected price of a woocommerce variable product.
System: Wordpress 5,6 + woocommerce
With a single product, my code is working well and i obtain a display like this:
Display for a single product with weight and price rewritten on right after quantity selector
And code is the following:
global $woocommerce;
$productxyz = new WC_Product( get_the_ID() );
$priceproduct = $productxyz->get_regular_price();
$poidsproduct = $productxyz->get_weight();
// CODE FOR THE + AND - QUANTITY
var $ = jQuery;
$(document).ready(function(){
$('.decrement').click(function () {
$moninput = $(this).nextAll('input#Qte');
if( Number($moninput.val()) > $moninput.attr("min") ){
$moninput.val(Number($moninput.val()) - 1);
}else{
$moninput.val($moninput.attr("min"));
}
Update_Price();
event.preventDefault();
})
$('.increment').click(function () {
$moninput = $(this).nextAll('input#Qte');
$moninput.val(Number($moninput.val()) + 1);
Update_Price();
event.preventDefault();
})
$('#btn-cady').click(function () {
$('[name="add-to-cart"]').click();
event.preventDefault();
})
// CODE FOR THE TEXT DISPLAYED ON THE RIGHT OF THE QUANTITY SELECTOR
function Update_Price(){
if($('input#Qte').attr('price') > 0){
$total = parseFloat($('input#Qte').val()) * $('input#Qte').attr('price');
$qtyactuelle = parseFloat($('input#Qte').val());
$('input[name="quantity"]').val($('input#Qte').val());
console.log($total);
if( $qtyactuelle < 2){
$('.Qtotal h4').html("<font color='#401816'>pack soit " +($('input#Qte').attr('weight')*parseFloat($('input#Qte').val()))+"g |</font> "+parseFloat($total).toFixed(2)+" €");
}
if($qtyactuelle > 1){
$('.Qtotal h4').html("<font color='#401816'>packs soit " +($('input#Qte').attr('weight')*parseFloat($('input#Qte').val()))+"g |</font> "+parseFloat($total).toFixed(2)+" €");
}
}
}
Update_Price();
});
But for a variation product... i feel so ashamed to show my result because when it's displaying well, function is not working. And when functions are working, display is very terrible
Code result for variation product
I tried to use get_available_variations() and also the following foreach but...
foreach( $product->get_available_variations() as $variation ){
$found = true;
// Loop through variation attributes
foreach( $variation['attributes'] as $key => $value ){
$taxonomy = str_replace( 'attribute_', '', $key );
// Searching for a matching variation as default
if( isset($default_attributes[$taxonomy]) && $default_attributes[$taxonomy] != $value ){
$found = false;
break;
}
}
// If we get the default variation
if( $found ) {
$default_variaton = $variation;
break;
}
Has anyone an idea of how to developp it? I'm feeling speechless.
In advance, thanks a lot!!!
On WooCommerce variable product pages, product variation data is stored in the data-product_variations attribute of the multi-select <form class="variation_form"> element. The variation data is stored in JSON format which you can then decode using the JSON.parse() method. There is no need to output this data yourself via PHP as WooCommerce already does it for you.
The JSON stored in the data-product_variations attribute includes the following price related properties:
display_price
regular_price
sale_price
With a little bit of jQuery/JS, you can easily output or mutate the default or selected variation pricing with the above properties.
Good Luck!

Creating a custom plugin to add a discount to woocommerce products

I currently have a wordpress site setup using woocommerce and gravity forms plugins. I am selling bike wheels and on my product page I use gravity forms to display different customization options. the options are different if they select one wheel or two wheels.
What I'm trying to achieve
I want to add a 5% discount if two wheels are selected and 10% if four+ are selected. This discount is applied to the product as it is added to the cart.
I am attempting to create a custom plugin that uses javascript to get the value from the gravity forms input, and hooks into woocommerce to edit the total price before adding it to the cart.
What I have so far
custom.js
jQuery(document).ready(function () {
jQuery('.cart').submit(function () {
var noOfWheels = jQuery(".rdoWheel input[type='radio']:checked").val();
console.log(noOfWheels)
var data = {
action: 'my_discount',
wheels: noOfWheels
};
jQuery.ajax({
type: 'POST',
url: discountAjax.ajax_url,
data: data,
success: function (data) {
//do nothing
},
});
return false;
});
});
discount.php
add_action('wp_enqueue_scripts', 'load_script');
function load_script() {
wp_enqueue_script('discount', plugin_dir_url( __FILE__ ) . 'custom/custom.js', array( 'jquery' ) );
wp_localize_script('discount', 'discountAjax', array('ajaxurl' => admin_url('admin-ajax.php')));
}
add_action('wp_ajax_woocommerce_discount', 'calculate', 10);
add_action('wp_ajax_nopriv_woocommerce_discount', 'calculate', 10);
function calculate() {
if (isset($_POST['wheels'])) {
global $woocommerce;
$wheels = $_POST['wheels'];
if ($wheels === "1") {
$val = 0;
} elseif ($wheels === "2"){
$val = 10;
}
session_start();
$_SESSION['val'] = $val;
}
}
add_action('woocommerce_before_calculate_totals', 'add_discount');
function add_discount( $cart_object) {
#session_start();
if (isset($_SESSION['val'])) {
$wheels = $_SESSION['val'];
foreach ( $cart_object->cart_contents as $key => $value ) {
$c_price = $value['data']->price;
$discountAmount = $c_price * $wheels/100;
$value['data']->price = $value['data']->price - $discountAmount;
}
//for testing purpose
echo $_SESSION['val'];
echo 'completed';
unset($_SESSION['val']);
}
}
whats happening
It seems the woocommerce function is not firing at all. when i check with firebug I see my ajax request go through okay then nothing else. If i remove everything except for the add_discount function then it goes through and applies the discount. I cant seem to get it to work with javascript/ajax.

Wordpress Excerpt with allowable tags is not working?

I am trying to create the simple excerpt plugin in Wordpress. I Googled a lot the allowable tag is not working, can anyone give me a suggestion how to do this?
class fpexcerpt {
function __construct() {
require_once('inc/template.php');
if(isset($_POST['reset'])) {
add_action('admin_init',array($this,'fpexcerptrestore'));
}
}
function fpexcerptdefault() {
add_option('fpexcerptcount',55);
add_option('fpexcerptmore','[...]');
}
function fpexcerptrestore() {
delete_option('fpexcerpttag');
delete_option('fpexcerptcount');
delete_option('fpexcerptmore');
fpexcerpt::fpexcerptdefault();
}
function fpexcerptadmin() {
add_submenu_page('options-general.php','Fantastic Excerpt', 'Fantastic Excerpt', 'manage_options','fpexcerptadmin', 'fpexcerptadmin_menu');
}
function fpexcerptupdate() {
register_setting('fpexcpt','fpexcerpttag');
register_setting('fpexcpt','fpexcerptcount');
register_setting('fpexcpt','fpexcerptmore');
}
function improved_trim_excerpt($text) {
global $post;
if ( '' == $text ) {
$text = get_the_excerpt();
$text = apply_filters('the_excerpt',$text);
// $text = str_replace('\]\]\>', ']]>', $text);
$text = strip_tags($text, '<a>');
$excerpt_length = 80;
$words = explode(' ', $text, $excerpt_length + 1);
if (count($words)> $excerpt_length) {
array_pop($words);
array_push($words, '[...]');
$text = implode(' ', $words);
}
}
return $text;
}
}
$new = new fpexcerpt();
register_activation_hook(__FILE__,array('fpexcerpt','fpexcerptdefault'));
//remove_all_filters('wp_trim_excerpt');
//add_filter('get_the_excerpt', array('fpexcerpt','fpexcerptprocess'));
remove_filter('get_the_excerpt',array('fpexcerpt','wp_trim_excerpt'));
add_filter('get_the_excerpt', array('fpexcerpt','improved_trim_excerpt'));
add_action('admin_menu',array('fpexcerpt','fpexcerptadmin'));
add_action('admin_init',array('fpexcerpt','fpexcerptupdate'));
?>
EDIT:
The first image is show the excerpt content when i click the particular post its getting link but not in excerpt even if i add the excerpt plugin (mine)
Error: Maximum function nesting level of '100' reached, aborting! in E:\wamp\www\fp\wp-includes\cache.php on line 453
Based on the error you've reported above, I can surmise you're stuck in a recursive function call loop. In other words, a function you've written is ( at some point in the callstack ) calling itself ( or a function that calls it ). Picture an infinite loop, but with functions.
I can't determine where this is occurring since I can't see all of your code.

Wordpress jQuery How to reset pagination when a post is toggled?

Surely, someone must have an idea of how t get this to work...
My blog is currently set where I have a custom page that displays only posts in a given category. Each post has a toggle button. When the toggle button is pressed, the post hides (the ENTIRE div is hidden with title and all post content). This works as desired.
The page is also set to display 10 posts per page. If I have 11 posts, the 11th is pushed to page 2. This works as desired.
The problem is that when a post is toggled (let's say post 3), I am left with a total of 9 posts on this page, with post 11 remaining on page 2. What I want to have happen is that when post 3 is toggled, post 11 should carry onto page 1, with page 2 essentially disappearing (since there are no posts to display there).
For illustration purposes:
Page 1 displays Posts 1,2,3,4,5,6,7,8,9,10
Page 2 displays Posts 11...and so on.
If Post 3 is toggled:
Page 1 displays Posts 1,2,4,5,6,7,8,9,10,11
Page 2 disappears (unless there is a post 12,13, etc)
Would anyone know how to implement this?
page.php:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'category_name' => 'post',
'paged' => $paged,
'posts_per_page' => 10
);
query_posts($args);
while (have_posts()) : the_post();
?>
..........the posts are displayed.............
<?php endwhile; ?>
<script type="text/javascript">
var pager = new Imtech.Pager();
$(document).ready(function() {
pager.paragraphsPerPage = 5; // set amount elements per page
pager.pagingContainer = $('#paginate'); // set of main container
pager.paragraphs = $('div.z', pager.pagingContainer); // set of required containers
pager.showPage(1);
});
</script>
toggle.js
$(document).on("click", ".toggle", function(){
postID = $(this).attr('id').replace('toggle_', '');
// Declare variables
value = '0';
myajax();
return false;
});
function myajax(){
// Send values to database
$.ajax({
url: 'check.php',
//check.php receives the values sent to it and stores them in the database
type: 'POST',
data: 'postID=' + postID + '&value=' + value,
success: function(result) {
$('#post_' + postID).toggle();
}
});
}
pagination.js
var Imtech = {};
Imtech.Pager = function() {
this.paragraphsPerPage = 3;
this.currentPage = 1;
this.pagingControlsContainer = '#pagingControls';
this.pagingContainerPath = '#contained';
this.numPages = function() {
var numPages = 0;
if (this.paragraphs != null && this.paragraphsPerPage != null) {
numPages = Math.ceil(this.paragraphs.length / this.paragraphsPerPage);
}
return numPages;
};
this.showPage = function(page) {
this.currentPage = page;
var html = '';
this.paragraphs.slice((page-1) * this.paragraphsPerPage,
((page-1)*this.paragraphsPerPage) + this.paragraphsPerPage).each(function() {
html += '<div>' + $(this).html() + '</div>';
});
$(this.pagingContainerPath).html(html);
renderControls(this.pagingControlsContainer, this.currentPage, this.numPages());
}
var renderControls = function(container, currentPage, numPages) {
var pagingControls = 'Page: <ul>';
for (var i = 1; i <= numPages; i++) {
if (i != currentPage) {
pagingControls += '<li>' + i + '</li>';
} else {
pagingControls += '<li>' + i + '</li>';
}
}
pagingControls += '</ul>';
$(container).html(pagingControls);
}
}
So, any ideas?
My Answer would be to reload the current page with posts through ajax.
there is no problem with generating pagination through javascript and php
you have same behaviour for initial load and subsequent loads(when user hides a post)
you can make the pagination work with jquery pretty easy

Resources