Skip to content

Instantly share code, notes, and snippets.

@whatthefork
Created January 26, 2014 21:50
Show Gist options
  • Save whatthefork/8639914 to your computer and use it in GitHub Desktop.
Save whatthefork/8639914 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: woocommerce modal variationn
Plugin URI: #
Description: show modal window with product variations after clicking -add to cart-.
Version: 0.1
Author: Maks Buriy
Author URI: mailto:[email protected]
License: GPL2
*/
/**
* Check if WooCommerce is active
**/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
// Put your plugin code here
if (!is_admin()){
wp_register_script( 'wcv-add-to-cart-variation', get_bloginfo(url).'/wp-content/plugins/woocommerce-modal-variation/woocommerce-variation.js', array( 'jquery' ), null, false );
add_filter('variable_add_to_cart_text', 'woo_custom_cart_button_text');
wp_enqueue_script( 'wcv-add-to-cart-variation' );
}
function woo_custom_cart_button_text() {
return __('Add to cart', 'woocommerce');
}
/**
* Products Loop
**/
if (!function_exists('woocommerce_template_loop_add_to_cart') ) {
function woocommerce_template_loop_add_to_cart( $post, $_product ) {
// No price set - so no button
if( $_product->get_price() === '' && $_product->product_type!='variable') return;
if (!$_product->is_in_stock()) :
echo '<a href="'.get_permalink($post->ID).'" class="button">'.__('Read More', 'woocommerce').'</a>';
return;
endif;
?><a href="<?php if ($_product->product_type=='variable'){echo get_bloginfo('url').'/wp-admin/admin-ajax.php?ajax=true&action=wc_variable_add&prod_id='.$_product->id.'&post='.$post->ID; } else echo esc_url( $_product->add_to_cart_url() ); ?>" <?php if ($_product->product_type=='variable'){ echo 'rel="variable_ajax_add"';} else {echo 'rel="nofollow"'; } ?> data-product_id="<?php echo $_product->id; ?>" title="<?php echo get_the_title($post->ID); ?>" class="button add_to_cart_button product_type_<?php echo $_product->product_type; ?>"><?php
switch ($_product->product_type) :
case "variable" :
echo apply_filters('variable_add_to_cart_text', __('Select options', 'woocommerce'));
break;
case "grouped" :
echo apply_filters('grouped_add_to_cart_text', __('View options', 'woocommerce'));
break;
default :
echo apply_filters('add_to_cart_text', __('Add to cart', 'woocommerce'));
break;
endswitch;
?></a><?php
if ($_product->product_type=='variable') { $available_variations = $_product->get_available_variations();
echo '<script type="text/javascript">
var product_variations_'.$post->ID.' = '. json_encode( $available_variations ). '
</script>'; }
}
}
add_action('wp_ajax_wc_variable_add', 'ajax_show');
add_action('wp_ajax_nopriv_wc_variable_add', 'ajax_show');
/**
* AJAX add to cart
*
* @access public
* @return void
*/
function woocommerce_ajax_add_to_cart_variable() {
global $woocommerce;
check_ajax_referer( 'add-to-cart', 'security' );
$product_id = (int) apply_filters('woocommerce_add_to_cart_product_id', $_POST['product_id']);
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, 1);
$variation_id = (int) $_POST['variation_id'];
if (!intval($_POST['quantity'])) $quantity = 1; else $quantity = $_POST['quantity'];
if ($passed_validation && $woocommerce->cart->add_to_cart($product_id, $quantity,$variation_id)) :
// Return html fragments
$data = apply_filters('add_to_cart_fragments', array());
do_action( 'woocommerce_ajax_added_to_cart', $product_id);
else :
// If there was an error adding to the cart, redirect to the product page to show any errors
$data = array(
'error' => true,
'product_url' => get_permalink( $product_id )
);
$woocommerce->set_messages();
endif;
echo json_encode( $data );
die();
}
add_action('wp_ajax_woocommerce_add_to_cart_variable', 'woocommerce_ajax_add_to_cart_variable');
add_action('wp_ajax_nopriv_woocommerce_add_to_cart_variable', 'woocommerce_ajax_add_to_cart_variable');
function ajax_show(){
global $woocommerce;
$post = get_post(intval($_GET['post']));
$product = new WC_Product(intval($_GET['prod_id']));
$available_variations = $product->get_available_variations();
$attributes = $product->get_variation_attributes();
$selected_attributes = $product->get_variation_default_attributes();
ob_start();?>
<?php do_action('woocommerce_before_add_to_cart_form'); ?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo $post->ID; ?>">
<table class="variations" cellspacing="0">
<tbody>
<?php $loop = 0; foreach ( $attributes as $name => $options ) : $loop++; ?>
<tr>
<td class="label"><label for="<?php echo sanitize_title($name); ?>"><?php echo $woocommerce->attribute_label($name); ?></label></td>
<td class="value"><select id="<?php echo esc_attr( sanitize_title($name) ); ?>" name="attribute_<?php echo sanitize_title($name); ?>">
<option value=""><?php echo __('Choose an option', 'woocommerce') ?>&hellip;</option>
<?php
if ( is_array( $options ) ) {
if ( empty( $_POST ) )
$selected_value = ( isset( $selected_attributes[ sanitize_title( $name ) ] ) ) ? $selected_attributes[ sanitize_title( $name ) ] : '';
else
$selected_value = isset( $_POST[ 'attribute_' . sanitize_title( $name ) ] ) ? $_POST[ 'attribute_' . sanitize_title( $name ) ] : '';
// Get terms if this is a taxonomy - ordered
if ( taxonomy_exists( sanitize_title( $name ) ) ) {
$terms = get_terms( sanitize_title($name), array('menu_order' => 'ASC') );
foreach ( $terms as $term ) {
if ( ! in_array( $term->slug, $options ) ) {print_r($options); continue; }
echo '<option value="' . $term->slug . '" ' . selected( $selected_value, $term->slug, false ) . '>' . apply_filters( 'woocommerce_variation_option_name', $term->name ) . '</option>';
}
} else {
foreach ( $options as $option )
echo '<option value="' . $option . '" ' . selected( $selected_value, $option, false ) . '>' . apply_filters( 'woocommerce_variation_option_name', $option ) . '</option>';
}
}
?>
</select> <?php
if ( sizeof($attributes) == $loop )
echo '<a class="reset_variations" href="#reset">'.__('Clear selection', 'woocommerce').'</a>';
?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php do_action('woocommerce_before_add_to_cart_button'); ?>
<div class="single_variation_wrap" style="display:none;">
<div class="single_variation"></div>
<div class="variations_button">
<input type="hidden" name="variation_id" value="" />
<?php woocommerce_quantity_input(); ?>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo apply_filters('single_add_to_cart_text', __('Add to cart', 'woocommerce'), $product->product_type); ?></button>
</div>
</div>
<div><input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" /></div>
<?php do_action('woocommerce_after_add_to_cart_button'); ?>
</form>
<?php do_action('woocommerce_after_add_to_cart_form');
$content = ob_get_clean();
//return $content;
echo $content;
die();
} }
?>
jQuery(document).ready(function($){
$("a[rel^='variable_ajax_add']").prettyPhoto({
default_height: 200,
default_width: 450,
theme: 'facebook',
markup: '<div class="pp_pic_holder"> \
<div class="ppt">&nbsp;</div> \
<div class="pp_top"> \
<div class="pp_left"></div> \
<div class="pp_middle"></div> \
<div class="pp_right"></div> \
</div> \
<div class="pp_content_container"> \
<div class="pp_left"> \
<div class="pp_right"> \
<div class="pp_content"> \
<div class="pp_loaderIcon"></div> \
<div class="pp_fade"> \
<div id="pp_full_res"></div> \
<div class="pp_details"> \
<p class="pp_description"></p> \
<a class="pp_close" href="#">Закрыть</a> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
<div class="pp_bottom"> \
<div class="pp_left"></div> \
<div class="pp_middle"></div> \
<div class="pp_right"></div> \
</div> \
</div> \
<div class="pp_overlay"></div>',
changepicturecallback: function(){ wcv_inicialize(); },
callback: function(){jQuery('body').bind('added_to_cart', update_cart_dropdown);}
});
});
function wcv_inicialize() {
avia_select_unify('form.variations_form select:not(.checkout select)');
/**
* Variations form handling
*/
jQuery('form.variations_form')
.on( 'click', '.reset_variations', function( event ) {
jQuery(this).closest('form.variations_form').find('.variations select').val('').change();
return false;
} )
// Upon changing an option
.on( 'change', '.variations select', function( event ) {
$variation_form = jQuery(this).closest('form.variations_form');
$variation_form.find('input[name=variation_id]').val('').change();
$variation_form
.trigger( 'woocommerce_variation_select_change' )
.trigger( 'check_variations', [ '', false ] );
jQuery(this).blur();
if( jQuery().uniform && jQuery.isFunction( jQuery.uniform.update ) ) {
jQuery.uniform.update();
}
} )
// Upon gaining focus
.on( 'focusin', '.variations select', function( event ) {
$variation_form = jQuery(this).closest('form.variations_form');
$variation_form
.trigger( 'woocommerce_variation_select_focusin' )
.trigger( 'check_variations', [ jQuery(this).attr('name'), true ] );
} )
// Check variations
.on( 'check_variations', function( event, exclude, focus ) {
var all_set = true;
var any_set = false;
var showing_variation = false;
var current_settings = {};
var $variation_form = jQuery(this);
var $reset_variations = $variation_form.find('.reset_variations');
$variation_form.find('.variations select').each( function() {
if ( jQuery(this).val().length == 0 ) {
all_set = false;
} else {
any_set = true;
}
if ( exclude && jQuery(this).attr('name') == exclude ) {
all_set = false;
current_settings[jQuery(this).attr('name')] = '';
} else {
// Encode entities
value = jQuery(this).val()
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
// Add to settings array
current_settings[ jQuery(this).attr('name') ] = value;
}
});
var product_id = parseInt( $variation_form.attr( 'data-product_id' ) );
var all_variations = window[ "product_variations_" + product_id ];
// Fallback
if ( ! all_variations )
all_variations = window[ "product_variations" ];
var matching_variations = find_matching_variations( all_variations, current_settings );
if ( all_set ) {
var variation = matching_variations.pop();
if ( variation ) {
// Found - set ID
$variation_form
.find('input[name=variation_id]')
.val( variation.variation_id )
.change();
$variation_form.trigger( 'found_variation', [ variation ] );
} else {
// Nothing found - reset fields
$variation_form.find('.variations select').val('');
if ( ! focus )
$variation_form.trigger( 'reset_image' );
}
} else {
$variation_form.trigger( 'update_variation_values', [ matching_variations ] );
if ( ! focus )
$variation_form.trigger( 'reset_image' );
if ( ! exclude ) {
$variation_form.find('.single_variation_wrap').slideUp('200');
}
}
if ( any_set ) {
if ( $reset_variations.css('visibility') == 'hidden' )
$reset_variations.css('visibility','visible').hide().fadeIn();
} else {
$reset_variations.css('visibility','hidden');
}
} )
// Reset product image
.on( 'reset_image', function( event ) {
var $product = jQuery(this).closest( '.product' );
var $product_img = $product.find( 'div.images img:eq(0)' );
var $product_link = $product.find( 'div.images a.zoom:eq(0)' );
var o_src = $product_img.attr('data-o_src');
var o_title = $product_img.attr('data-o_title');
var o_href = $product_link.attr('data-o_href');
if ( o_src && o_href && o_title ) {
$product_img
.attr( 'src', o_src )
.attr( 'alt', o_title )
.attr( 'title', o_title );
$product_link
.attr( 'href', o_href );
}
} )
// Disable option fields that are unavaiable for current set of attributes
.on( 'update_variation_values', function( event, variations ) {
$variation_form = jQuery(this).closest('form.variations_form');
// Loop through selects and disable/enable options based on selections
$variation_form.find('.variations select').each(function( index, el ){
current_attr_select = jQuery(el);
// Disable all
current_attr_select.find('option:gt(0)').attr('disabled', 'disabled');
// Get name
var current_attr_name = current_attr_select.attr('name');
// Loop through variations
for ( num in variations ) {
var attributes = variations[ num ].attributes;
for ( attr_name in attributes ) {
var attr_val = attributes[ attr_name ];
if ( attr_name == current_attr_name ) {
if ( attr_val ) {
// Decode entities
attr_val = jQuery("<div/>").html( attr_val ).text();
// Add slashes
attr_val = attr_val.replace(/'/g, "\\'");
attr_val = attr_val.replace(/"/g, "\\\"");
// Compare the meercat
current_attr_select.find('option[value="' + attr_val + '"]').removeAttr('disabled');
} else {
current_attr_select.find('option').removeAttr('disabled');
}
}
}
}
});
// Custom event for when variations have been updated
$variation_form.trigger('woocommerce_update_variation_values');
} )
// Show single variation details (price, stock, image)
.on( 'found_variation', function( event, variation ) {
var $variation_form = jQuery(this);
var $product = jQuery(this).closest( '.product' );
var $product_img = $product.find( 'div.images img:eq(0)' );
var $product_link = $product.find( 'div.images a.zoom:eq(0)' );
var o_src = $product_img.attr('data-o_src');
var o_title = $product_img.attr('data-o_title');
var o_href = $product_link.attr('data-o_href');
var variation_image = variation.image_src;
var variation_link = variation.image_link;
var variation_title = variation.image_title;
$variation_form.find('.variations_button').show();
$variation_form.find('.single_variation').html( variation.price_html + variation.availability_html );
if ( ! o_src ) {
o_src = ( ! $product_img.attr('src') ) ? '' : $product_img.attr('src');
$product_img.attr('data-o_src', o_src );
}
if ( ! o_href ) {
o_href = ( ! $product_link.attr('href') ) ? '' : $product_link.attr('href');
$product_link.attr('data-o_href', o_href );
}
if ( ! o_title ) {
o_title = ( ! $product_img.attr('title') ) ? '' : $product_img.attr('title');
$product_img.attr('data-o_title', o_title );
}
if ( variation_image && variation_image.length > 1 ) {
$product_img
.attr( 'src', variation_image )
.attr( 'alt', variation_title )
.attr( 'title', variation_title );
$product_link
.attr( 'href', variation_link );
} else {
$product_img
.attr( 'src', o_src )
.attr( 'alt', o_title )
.attr( 'title', o_title );
$product_link
.attr( 'href', o_href );
}
var $single_variation_wrap = $variation_form.find('.single_variation_wrap');
if ( variation.sku )
$variation_form.find('.product_meta').find('.sku').text( variation.sku );
else
$variation_form.find('.product_meta').find('.sku').text('');
$single_variation_wrap.find('.quantity').show();
if ( ! variation.is_in_stock && ! variation.backorders_allowed ) {
$variation_form.find('.variations_button').hide();
}
if ( variation.min_qty )
$single_variation_wrap.find('input[name=quantity]').attr( 'data-min', variation.min_qty ).val( variation.min_qty );
else
$single_variation_wrap.find('input[name=quantity]').removeAttr('data-min');
if ( variation.max_qty )
$single_variation_wrap.find('input[name=quantity]').attr('data-max', variation.max_qty);
else
$single_variation_wrap.find('input[name=quantity]').removeAttr('data-max');
if ( variation.is_sold_individually == 'yes' ) {
$single_variation_wrap.find('input[name=quantity]').val('1');
$single_variation_wrap.find('.quantity').hide();
}
$single_variation_wrap.slideDown('200').trigger( 'show_variation', [ variation ] );
} )
/** Click add to cart button event **/
// Ajax add to cart
.on('click','.single_add_to_cart_button', function( event ) {
// AJAX add to cart request
var $thisbutton = jQuery(this);
if ($thisbutton.is('.button')) {
var $variation_form = jQuery(this).closest('form.variations_form');
var $product_id = parseInt( $variation_form.attr( 'data-product_id' ) );
if (!$product_id) return true;
$thisbutton.removeClass('added');
$thisbutton.addClass('loading');
var $vid = parseInt($variation_form.find('input[name=variation_id]').val());
var $quantity = parseInt($variation_form.find('input[name=quantity]').val());
//console.log($vid);
var data = {
action: 'woocommerce_add_to_cart_variable',
product_id: $product_id,
variation_id: $vid,
quantity: $quantity,
security: woocommerce_params.add_to_cart_nonce
};
// Trigger event
jQuery('body').trigger('adding_to_cart');
// Ajax action
jQuery.post( woocommerce_params.ajax_url, data, function(response) {
var this_page = window.location.toString();
this_page = this_page.replace( 'add-to-cart', 'added-to-cart' );
$thisbutton.removeClass('loading');
// Get response
data = jQuery.parseJSON( response );
if (data.error && data.product_url) {
window.location = data.product_url;
return;
}
fragments = data;
// Block fragments class
if (fragments) {
jQuery.each(fragments, function(key, value) {
jQuery(key).addClass('updating');
});
}
// Block widgets and fragments
jQuery('.widget_shopping_cart, .shop_table.cart, .updating, .cart_totals').fadeTo('400', '0.6').block({message: null, overlayCSS: {background: 'transparent url(' + woocommerce_params.ajax_loader_url + ') no-repeat center', opacity: 0.6 } } );
// Changes button classes
$thisbutton.addClass('added');
// Cart widget load
if (jQuery('.widget_shopping_cart').size()>0) {
jQuery('.widget_shopping_cart:eq(0)').load( this_page + ' .widget_shopping_cart:eq(0) > *', function() {
// Replace fragments
if (fragments) {
jQuery.each(fragments, function(key, value) {
jQuery(key).replaceWith(value);
});
}
// Unblock
jQuery('.widget_shopping_cart, .updating').stop(true).css('opacity', '1').unblock();
jQuery('body').trigger('cart_widget_refreshed');
} );
} else {
// Replace fragments
if (fragments) {
jQuery.each(fragments, function(key, value) {
jQuery(key).replaceWith(value);
});
}
// Unblock
jQuery('.widget_shopping_cart, .updating').stop(true).css('opacity', '1').unblock();
}
// Cart page elements
jQuery('.shop_table.cart').load( this_page + ' .shop_table.cart:eq(0) > *', function() {
jQuery("div.quantity:not(.buttons_added), td.quantity:not(.buttons_added)").addClass('buttons_added').append('<input type="button" value="+" id="add1" class="plus" />').prepend('<input type="button" value="-" id="minus1" class="minus" />');
jQuery('.shop_table.cart').stop(true).css('opacity', '1').unblock();
jQuery('body').trigger('cart_page_refreshed');
});
jQuery('.cart_totals').load( this_page + ' .cart_totals:eq(0) > *', function() {
jQuery('.cart_totals').stop(true).css('opacity', '1').unblock();
});
// Trigger event so themes can refresh other areas
jQuery('body').trigger('added_to_cart');
jQuery.prettyPhoto.close();
});
return false;
} else {
return true;
}
});
/**
* Initial states and loading
*/
jQuery('form.variations_form .variations select').change();
/**
* Helper functions for variations
*/
// Search for matching variations for given set of attributes
function find_matching_variations( product_variations, settings ) {
var matching = [];
for (var i = 0; i < product_variations.length; i++) {
var variation = product_variations[i];
var variation_id = variation.variation_id;
if ( variations_match( variation.attributes, settings ) ) {
matching.push(variation);
}
}
return matching;
}
// Check if two arrays of attributes match
function variations_match( attrs1, attrs2 ) {
var match = true;
for ( attr_name in attrs1 ) {
var val1 = attrs1[ attr_name ];
var val2 = attrs2[ attr_name ];
if ( val1 !== undefined && val2 !== undefined && val1.length != 0 && val2.length != 0 && val1 != val2 ) {
match = false;
}
}
return match;
}
}
@hemusyl
Copy link

hemusyl commented Jul 3, 2021

The code not working anymore. Do you update please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment