upsells/cross sells

This commit is contained in:
Mike Jolley 2011-08-11 11:51:33 +01:00
parent 5e653d2821
commit 9d5d2cd975
8 changed files with 245 additions and 5 deletions

View File

@ -38,7 +38,8 @@ function woocommerce_product_data_box() {
<li class="pricing_tab"><a href="#pricing_product_data"><?php _e('Pricing', 'woothemes'); ?></a></li>
<?php if (get_option('woocommerce_manage_stock')=='yes') : ?><li class="inventory_tab"><a href="#inventory_product_data"><?php _e('Inventory', 'woothemes'); ?></a></li><?php endif; ?>
<li><a href="#woocommerce_attributes"><?php _e('Attributes', 'woothemes'); ?></a></li>
<li><a href="#upsell_product_data" title="<?php _e('Up-sells are products which you recommend instead of the currently viewed product, for example, products that are more profitable or better quality or more expensive.', 'woothemes'); ?>"><?php _e('Up-sells', 'woothemes'); ?></a></li>
<li><a href="#crosssell_product_data" title="<?php _e('Cross-sells are products which you promote in the cart, based on the current product.', 'woothemes'); ?>"><?php _e('Cross-sells', 'woothemes'); ?></a></li>
<?php do_action('product_write_panel_tabs'); ?>
</ul>
@ -354,6 +355,44 @@ function woocommerce_product_data_box() {
</select>
<div class="clear"></div>
</div>
<div id="upsell_product_data" class="panel woocommerce_options_panel">
<div class="multi_select_products_wrapper"><h4><?php _e('Products', 'woothemes'); ?></h4>
<ul class="multi_select_products multi_select_products_source">
<li class="product_search"><input type="search" rel="upsell_ids" name="product_search" id="product_search" placeholder="<?php _e('Search for product', 'woothemes'); ?>" /><div class="clear"></div></li>
</ul>
</div>
<div class="multi_select_products_wrapper"><h4><?php _e('Up-Sells', 'woothemes'); ?></h4><ul class="multi_select_products multi_select_products_target">
<?php
if (isset($data['upsell_ids']) && is_array($data['upsell_ids']) && sizeof($data['upsell_ids'])>0) :
$upsell_ids = $data['upsell_ids'];
else :
$upsell_ids = array(0);
endif;
woocommerce_product_selection_list_remove($upsell_ids, 'upsell_ids');
?>
</ul></div>
<div class="clear"></div>
</div>
<div id="crosssell_product_data" class="panel woocommerce_options_panel">
<div class="multi_select_products_wrapper"><h4><?php _e('Products', 'woothemes'); ?></h4>
<ul class="multi_select_products multi_select_products_source">
<li class="product_search"><input type="search" rel="crosssell_ids" name="product_search" id="product_search" placeholder="<?php _e('Search for product', 'woothemes'); ?>" /><div class="clear"></div></li>
</ul>
</div>
<div class="multi_select_products_wrapper"><h4><?php _e('Cross-Sells', 'woothemes'); ?></h4><ul class="multi_select_products multi_select_products_target">
<?php
if (isset($data['crosssell_ids']) && is_array($data['crosssell_ids']) && sizeof($data['crosssell_ids'])>0) :
$crosssell_ids = $data['crosssell_ids'];
else :
$crosssell_ids = array(0);
endif;
woocommerce_product_selection_list_remove($crosssell_ids, 'crosssell_ids');
?>
</ul></div>
<div class="clear"></div>
</div>
<?php do_action('product_write_panels'); ?>
@ -553,6 +592,28 @@ function woocommerce_process_product_meta( $post_id, $post ) {
endif;
endif;
// Upsells
if (isset($_POST['upsell_ids'])) :
$upsells = array();
$ids = $_POST['upsell_ids'];
foreach ($ids as $id) :
if ($id && $id>0) $upsells[] = $id;
endforeach;
$data['upsell_ids'] = $upsells;
endif;
// Cross sells
if (isset($_POST['crosssell_ids'])) :
$crosssells = array();
$ids = $_POST['crosssell_ids'];
foreach ($ids as $id) :
if ($id && $id>0) $crosssells[] = $id;
endforeach;
$data['crosssell_ids'] = $crosssells;
endif;
// Apply filters to data
$data = apply_filters( 'process_product_meta', $data, $post_id );
@ -566,4 +627,31 @@ function woocommerce_process_product_meta( $post_id, $post ) {
update_post_meta( $post_id, 'product_attributes', $attributes );
update_post_meta( $post_id, 'product_data', $data );
update_option('woocommerce_errors', $woocommerce_errors);
}
/**
* Outputs product list in selection boxes
**/
function woocommerce_product_selection_list_remove( $posts_to_display, $name ) {
global $thepostid;
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'numberposts' => -1,
'orderby' => 'title',
'order' => 'asc',
'include' => $posts_to_display,
);
$related_posts = get_posts($args);
$loop = 0;
if ($related_posts) : foreach ($related_posts as $related_post) :
if ($related_post->ID==$thepostid) continue;
$SKU = get_post_meta($related_post->ID, 'SKU', true);
?><li rel="<?php echo $related_post->ID; ?>"><button type="button" name="Remove" class="button remove" title="Remove">X</button><strong><?php echo $related_post->post_title; ?></strong> &ndash; #<?php echo $related_post->ID; ?> <?php if (isset($SKU) && $SKU) echo 'SKU: '.$SKU; ?><input type="hidden" name="<?php echo $name; ?>[]" value="<?php echo $related_post->ID; ?>" /></li><?php
endforeach; endif;
}

View File

@ -150,7 +150,8 @@ function woocommerce_write_panel_scripts() {
'meta_value' => __('Meta Value', 'woothemes'),
'plugin_url' => woocommerce::plugin_url(),
'ajax_url' => admin_url('admin-ajax.php'),
'add_order_item_nonce' => wp_create_nonce("add-order-item")
'add_order_item_nonce' => wp_create_nonce("add-order-item"),
'upsell_crosssell_search_products_nonce' => wp_create_nonce("search-products")
);
wp_localize_script( 'woocommerce-writepanel', 'params', $params );

View File

@ -172,6 +172,7 @@ div.multi_select_products_wrapper{float:left;padding:0 9px 9px;}
.multi_select_countries li label{display:block;}
.multi_select_countries li label input{margin:0 4px 0 0;}
.multi_select_products button{float:right;vertical-align:middle;}
.multi_select_products .product_search input{width:100%;}
#woocommerce-product-data a.dp-choose-date{float:left;width:16px;height:16px;padding:0;margin:4px 9px 0 3px;display:block;text-indent:-2000px;overflow:hidden;background:url(../images/calendar.png) no-repeat;}
#woocommerce-product-data a.dp-choose-date.dp-disabled{background-position:0 -20px;cursor:default;}
#woocommerce-product-data input.dp-applied{width:140px;float:left;}

View File

@ -888,6 +888,9 @@ div.multi_select_products_wrapper {
float: right;
vertical-align: middle;
}
.multi_select_products .product_search input {
width: 100%;
}
#woocommerce-product-data a.dp-choose-date {
float: left;

View File

@ -296,5 +296,47 @@ jQuery( function($){
row_indexes();
});
// Cross sells/Up sells
jQuery('.multi_select_products button').live('click', function(){
var wrapper = jQuery(this).parent().parent().parent().parent();
if (jQuery(this).parent().parent().is('.multi_select_products_target')) {
jQuery(this).parent().remove();
} else {
var target = jQuery('.multi_select_products_target', jQuery(wrapper));
var exists = jQuery('li[rel=' + jQuery(this).parent().attr('rel') + ']', target);
if (jQuery(exists).size()>0) return false;
jQuery(this).parent().clone().appendTo(target).find('button').html('X').parent().find('input').val( jQuery(this).parent().attr('rel') );
}
});
jQuery('.multi_select_products #product_search').bind('keyup click', function(){
jQuery('.multi_select_products_source li:not(.product_search)').remove();
var search = encodeURI( jQuery(this).val() );
var input = this;
var name = jQuery(this).attr('rel');
if (search.length<3) return;
var data = {
name: name,
search: search,
action: 'woocommerce_upsell_crosssell_search_products',
security: params.upsell_crosssell_search_products_nonce
};
jQuery.post( params.ajax_url, data, function( response ) {
jQuery('.multi_select_products_source li:not(.product_search)').remove();
jQuery(input).parent().parent().append( response );
} );
});
});

View File

@ -156,6 +156,59 @@ function woocommerce_add_order_item() {
}
/**
* Search for products for upsells/crosssells
*/
add_action('wp_ajax_woocommerce_upsell_crosssell_search_products', 'woocommerce_upsell_crosssell_search_products');
function woocommerce_upsell_crosssell_search_products() {
check_ajax_referer( 'search-products', 'security' );
$search = (string) urldecode(stripslashes(strip_tags($_POST['search'])));
$name = (string) urldecode(stripslashes(strip_tags($_POST['name'])));
if (empty($search)) die();
if (is_numeric($search)) :
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 20,
'post__in' => array(0, $search)
);
else :
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 20,
's' => $search
);
endif;
$posts = get_posts( $args );
if ($posts) : foreach ($posts as $post) :
$SKU = get_post_meta($post->ID, 'SKU', true);
?>
<li rel="<?php echo $post->ID; ?>"><button type="button" name="Add" class="button add" title="Add">&rarr;</button><strong><?php echo $post->post_title; ?></strong> &ndash; #<?php echo $post->ID; ?> <?php if (isset($SKU) && $SKU) echo 'SKU: '.$SKU; ?><input type="hidden" name="<?php echo $name; ?>[]" value="0" /></li>
<?php
endforeach; else :
?><li><?php _e('No products found', 'woocommerce'); ?></li><?php
endif;
die();
}
/**
* When default permalinks are enabled, redirect shop page to post type archive url

View File

@ -49,6 +49,9 @@ add_action( 'woocommerce_template_single_summary', 'woocommerce_template_single_
add_action( 'woocommerce_template_single_summary', 'woocommerce_template_single_meta', 40, 2);
add_action( 'woocommerce_template_single_summary', 'woocommerce_template_single_sharing', 50, 2);
/* After Single Products */
add_action('woocommerce_after_single_product', 'woocommerce_upsell_display');
/* Product Add to cart */
add_action( 'woocommerce_template_single_summary', 'woocommerce_template_single_add_to_cart', 30, 2 );
add_action( 'simple_add_to_cart', 'woocommerce_simple_add_to_cart' );
@ -79,6 +82,8 @@ add_action( 'before_checkout_form', 'woocommerce_checkout_login_form', 10 );
add_action( 'after_setup_theme', 'woocommerce_body_classes_check' );
function woocommerce_body_classes_check () {
if( has_filter( 'body_class', 'twentyeleven_body_classes' ) )
add_filter( 'body_class', 'woocommerce_body_classes' );
if( has_filter( 'body_class', 'twentyeleven_body_classes' ) ) add_filter( 'body_class', 'woocommerce_body_classes' );
}
/* Cart */
add_action('cart-collaterals', 'woocommerce_cross_sell_display');

View File

@ -787,7 +787,9 @@ if (!function_exists('woocommerce_breadcrumb')) {
}
}
/**
* Remove the singular class for woocommerce single product
**/
function woocommerce_body_classes ($classes) {
if( ! is_singular('product') ) return $classes;
@ -797,3 +799,48 @@ function woocommerce_body_classes ($classes) {
return $classes;
}
/**
* Display Up Sells
**/
function woocommerce_upsell_display() {
global $_product;
$upsells = $_product->get_upsells();
if (sizeof($upsells)>0) :
echo '<div class="upsells products"><h2>'.__('You may also like&hellip;', 'woothemes').'</h2><ul>';
$args = array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'posts_per_page' => 4,
'orderby' => 'rand',
'post__in' => $upsells
);
query_posts($args);
woocommerce_get_template_part( 'loop', 'shop' );
echo '</div>';
endif;
wp_reset_query();
}
/**
* Display Cross Sells
**/
function woothemes_cross_sell_display() {
global $columns;
$columns = 2;
$crosssells = woocommerce_cart::get_cross_sells();
if (sizeof($crosssells)>0) :
echo '<div class="cross-sells"><h2>'.__('You may be interested in&hellip;', 'woothemes').'</h2>';
$args = array(
'post_type' => 'product',
'ignore_sticky_posts' => 1,
'posts_per_page' => 2,
'orderby' => 'rand',
'post__in' => $crosssells
);
query_posts($args);
woocommerce_get_template_part( 'loop', 'shop' );
echo '</div>';
endif;
wp_reset_query();
}