Skip to content

Instantly share code, notes, and snippets.

@UltimateWoo
Created December 28, 2014 19:38
Show Gist options
  • Save UltimateWoo/ef753b04dca4fd626afd to your computer and use it in GitHub Desktop.
Save UltimateWoo/ef753b04dca4fd626afd to your computer and use it in GitHub Desktop.
WooCommerce Conditional Upsells
<?php
/*
Plugin Name: WooCommerce Conditional Upsells
Plugin URI: http://www.ultimatewoo.com/woocommerce-conditional-upsells
Description: This is a fork of another Gist that we have put into plugin format. Define a list of Upsell products and a list of Required products. Upsells will be shown as an option to add to cart when all required products are currently in cart. They'll also be removed when a required product is removed.
Version: 1.0
Author: UltimateWoo
Author URI: http://www.ultimatewoo.com/
Source: https://gist.github.com/EngageWP/9a3e30d9dc164ebce458
*/
/*
* Replace the following ID lists with your own
* Keep the IDs comma separated and within the single quotes
*
* REQUIRED_PRODUCT_IDS takes IDs of the products required to be in the cart
* before the Upsells can be added
*
* UPSELL_PRODUCT_IDS takes IDs of the products considered to be Upsells
*/
define( 'REQUIRED_PRODUCT_IDS', '70, 37, 53, 19' );
define( 'UPSELL_PRODUCT_IDS', '73, 50' );
class WC_Conditional_Upsells {
private $required;
private $required_items_count;
private $upsells;
private $upsells_count;
private $cart;
private $message;
public function __construct() {
$this->cart = array(); // Cart contents
$this->required = explode( ',', trim( REQUIRED_PRODUCT_IDS ) ); // Products required to purchase upsell(s)
$this->upsells = explode( ',', trim( UPSELL_PRODUCT_IDS ) ); // Upsell(s) that can be purchased when all required products are in cart
$this->required_items_count = count( $this->required ); // Number of required products
$this->upsells_count = count( $this->upsells ); // Number of upsell products
add_action( 'init', array( $this, 'list_cart_items' ) );
add_action( 'template_redirect', array( $this, 'empty_cart' ) );
add_action( 'woocommerce_before_cart', array( $this, 'show_upsell' ) );
}
/*
* Stores the cart items
*/
public function list_cart_items() {
global $woocommerce;
$in_cart = $woocommerce->cart->get_cart();
foreach ( $in_cart as $cart_item ) {
$cart_items[] = array(
'id' => $cart_item['product_id'],
'qty' => $cart_item['quantity']
);
}
if ( !empty( $cart_items ) )
$this->cart = $cart_items;
}
/*
* Show add-to-cart links for each Upsell NOT in the cart
* Displays upsells only when all requierd items are in cart
*/
public function show_upsell() {
global $woocommerce;
$upsells = $this->upsells;
$cart_items = $this->cart;
$add_to_cart_url = trailingslashit( $woocommerce->cart->get_cart_url() ) . '?add-to-cart=';
$running_count = 0;
$required = $this->required;
//* Assemble cart product IDs into a simple array
foreach ( $cart_items as $key => $value ) {
$current_ids[] = $value['id'];
}
foreach ( $required as $id ) {
if ( in_array( $id, $current_ids ) ) {
$running_count++;
}
}
//* If all the required items are in the cart and there are upsells
if ( $running_count == $this->required_items_count && !empty( $upsells ) ) {
echo '<div class="upsell">';
echo '<ul>';
foreach ( $upsells as $upsell ) {
if ( !in_array( $upsell, $current_ids ) ) {
echo '<li><a href="' . $add_to_cart_url . $upsell . '">Add ' . get_the_title( $upsell ) . ' to cart</a></li>';
}
}
echo '</ul>';
echo '</div>';
}
}
/*
* If all the required items are NOT in the cart and there are upsells in the cart
* then empty the cart and re-add the items minus the required item that was removed and the upsell(s)
*/
public function empty_cart() {
global $woocommerce;
$upsells = $this->upsells;
$cart_items = $this->cart;
$required = $this->required;
//* Count to see if required products are in cart
$required_items_in_cart = 0;
//* Count to see if upsells are in cart
$upsells_in_cart = 0;
//* Assemble cart product IDs into a simple array
foreach ( $cart_items as $key => $value ) {
$current_ids[] = $value['id'];
}
foreach ( $required as $id ) {
if ( !empty( $current_ids ) && in_array( $id, $current_ids ) ) {
$required_items_in_cart++;
}
}
foreach ( $upsells as $upsell ) {
if ( !empty( $current_ids ) && in_array( $upsell, $current_ids ) ) {
$upsells_in_cart++;
}
}
if ( ( $required_items_in_cart < $this->required_items_count ) && $upsells_in_cart > 0 ) {
//* Get a fresh copy of the cart
$in_cart = $woocommerce->cart->get_cart();
foreach ( $in_cart as $cart_item ) {
$current_ids_refreshed[] = array(
'id' => $cart_item['product_id'],
'qty' => $cart_item['quantity']
);
}
//* Reset $cart_items to store the fresh cart array
$cart_items = $current_ids_refreshed;
//* Empty the cart
$woocommerce->cart->empty_cart();
//* Loop through the new $cart_items
foreach ( $cart_items as $cart_item ) {
$id = $cart_item['id']; // ID of each item in cart
$qty = $cart_item['qty']; // Quantity of each item in cart
// re-add items the items that are not upsells
if ( !in_array( $id, $upsells ) ) {
$woocommerce->cart->add_to_cart( $id, $qty );
} else {
$not_readded[] = $id;
}
}
$list_items = '';
foreach ( $not_readded as $key => $value ) {
$list_items .= '<li><a href="' . get_permalink( $value ) . '">' . get_the_title( $value ) . '</a></li>';
}
$message = '<p>The following items were removed from your cart because they are not available based on your cart\'s contents:</p>';
$message .= '<ul>' . $list_items . '</ul>';
$this->message = $message;
if ( !empty( $not_readded ) ) {
add_action( 'woocommerce_before_cart', array( $this, 'rv_wc_print_notices' ) );
}
}
}
public function rv_wc_print_notices() {
wc_print_notice( $this->message, 'notice' );
}
}
if ( !is_admin() )
new WC_Conditional_Upsells;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment