Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tallesairan/34f4a2db1abb4aa99a034de80b31d42f to your computer and use it in GitHub Desktop.
Save tallesairan/34f4a2db1abb4aa99a034de80b31d42f 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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment