Skip to content

Instantly share code, notes, and snippets.

@Preciousomonze
Last active September 18, 2020 00:26
Show Gist options
  • Save Preciousomonze/1d3ed78904bd670365562d91dc9f1fd3 to your computer and use it in GitHub Desktop.
Save Preciousomonze/1d3ed78904bd670365562d91dc9f1fd3 to your computer and use it in GitHub Desktop.
Programmatically Remove other products when a particular product(s) is being added to cart, also add a force sell product(s) attached to it. More info here: https://woocommercecommunity.slack.com/archives/C1K9K3UD9/p1599861910188600
<?php
// This was added, cause the envrionment with WooCommerce and WooCommerce Subscription acted weird 🥴.
$pekky_callback_func_name = 'pekky_2_remove_cart_item_before_add_to_cart';
add_filter( 'woocommerce_add_to_cart_validation', $pekky_callback_func_name, 20, 3 );
// Works, different method, faster 😎
function pekky_2_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
// Sample values: array( 23,45,43 );
$stand_alone_products = [660];//array( 25221, 29237 ); //stand alone products
$other_products = [226];//array( 28745, 28746, 28747, 28748 ); // friendly products that can stay in the cart with others
/**
* Products attached to the standalone products
* These should be added to cart when a standalone product is in the cart.
* patterns [{standalone_product_id} => array({force_sells_ids})]
*/
$force_sells_products = array(
'660'=>[225,229],//'29237' => array( 25556 ),
'25221' => array( 29234, 29444 ),
); //products attached to one of the stand alone products
// Add only level 2 or level three program to the cart.
if ( in_array( $product_id, $stand_alone_products ) ) {
// echo "<br>Standalone<br><br>";
_pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products );
}
// Allow other products to be in cart together.
else if ( in_array( $product_id, $other_products ) ) {
// Make sure stand alone products aren't in the cart.
foreach ( $stand_alone_products as $p_id ) {
// Is this standalone product in the cart?
if ( in_array( $p_id, array_column( WC()->cart->get_cart(), 'product_id' ) ) ) {
// echo "<br>Otherrrrrr producccts<br><br>";
// Product is there, remove.
_pekky_sort_stand_alone_products( $p_id, $stand_alone_products, $force_sells_products, false );
}
}
// WC()->cart->add_to_cart( $product_id );
}
return $passed;
}
/**
* Sorts the stand alone products
*
* @param int $product_id
* @oaram array $stand_alone_products
* @param array $force_sells_products Products attached to the standalone products
* These should be added to cart/removed when their standalone product is in the cart/removed.
* Patterns [{standalone_product_id} => array({force_sells_ids})]
* @param bool $add_to_cart (optional) true, add to cart, if false, removes, default is true.
* @return bool false if empty field, true otherwise
*/
function _pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products, $add_to_cart = true ){
if ( empty( $product_id ) || ( empty( $stand_alone_products ) || !is_array( $stand_alone_products ) )
|| ( empty( $force_sells_products ) || !is_array( $force_sells_products ) ) ){
return false;
}
//var_dump("yhhhhh<br><br>");
$wc_cart = WC()->cart;
$cart_func = 'remove_cart_item';
if ( $add_to_cart ) {
$cart_func = 'add_to_cart';
// empty cart.
$wc_cart->empty_cart();
}
$p_id = ( $add_to_cart ? $product_id : $wc_cart->generate_cart_id( $product_id ) );
// var_dump("<br><br>".$cart_func);
// var_dump("<br>product_id:".$product_id."<br>");
// var_dump( "<br>function executed: ");
if( ! $add_to_cart ){
$wc_cart->{"{$cart_func}"}( $p_id );
}
// get list of standalone product id
$product_force_sells_list = $force_sells_products[$product_id];
//var_dump($product_force_sells_list);
if( empty( $product_force_sells_list ) ){
// wrong list
return false;
}
// Also add the force_sells product to cart/remove
foreach ( $product_force_sells_list as $_id ) {
// var_dump("<br>Force_sales product id: " .$_id);
$p_id = ( $add_to_cart ? $_id : $wc_cart->generate_cart_id( $_id ) );
// var_dump("<br> function_exec:");
$wc_cart->{"{$cart_func}"}( $p_id );
//reset quantity to 1
if( $add_to_cart ) {
$cart_item_key = $wc_cart->generate_cart_id( $p_id );
$wc_cart->set_quantity( $cart_item_key, 1 ); // Change quantity
}
}
return true;
}
<?php
/**
* 2 functions which do the same thing in different ways
* 1 tends to run faster than the other (method 2)
* There's also a function just to monitor runtime spead between the 2 funcs, check properly.
*
* Should be added in your theme's functions.php file or anywhere you put code snippet :)
* Enjoy at your risk.
*/
$pekky_callback_func_name = 'pekky_speed_remove_cart_item_before_add_to_cart';
add_filter( 'woocommerce_add_to_cart_validation', $pekky_callback_func_name, 20, 3 );
// Monitor runtime speed for first and second method., this should not be used in a live site 🙃.
function pekky_speed_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
$_p_runtime = 0;
echo "<br>time for 1st function";
// Monitoring speed runtime the local way :)
$before = microtime( true );
pekky_1_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity );
$after = microtime( true );
$_p_runtime = ( $after - $before );
$first_func = $_p_runtime;
echo "<br>End of 1st function<br>";
echo "\nTime frame: " . ( $_p_runtime );
#############################################
echo "<br><br>Time of 2nd function";
// Monitoring speed runtime the local way :)
$before = microtime( true );
pekky_2_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity );
$after = microtime( true );
$_p_runtime = ( $after - $before );
$second_func = $_p_runtime;
echo "<br>End of 2nd function<br>";
echo "\nTime frame: " . ( $_p_runtime );
echo "<br><br>";
############################
if ( $first_func > $second_func ) {
echo "First is higher by: " . ( $first_func - $second_func );
}
else if ( $second_func > $first_func ) {
echo "Second is higher by: " . ( $second_func - $first_func );
}
else {
echo "both the same";
}
exit;
}
// First method.
function pekky_1_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
// Sample values: array( 23,45,43 );
$stand_alone_products = array( 25221, 29237 ); //stand alone products
$other_products = array( 28745, 28746, 28747, 28748 ); // friendly products that can stay in the cart with others
/**
* Products attached to the standalone products
* These should be added to cart when a standalone product is in the cart.
* patterns [{standalone_product_id} => array({force_sells_ids})]
*/
$force_sells_products = array(
'29237' => array( 25556 ),
'25221' => array( 29234, 29444 ),
); //products attached to one of the stand alone products
// Add only level 2 or level three program to the cart.
if ( in_array( $product_id, $stand_alone_products ) ) {
_pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products );
}
// Allow other products to be in cart together.
else if ( in_array( $product_id, $other_products ) ) {
// Make sure stand alone products aren't in the cart.
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Is the current product part of stand alone?
if ( in_array( $cart_item['product_id'], $stand_alone_products ) ){
// Yup, stand alone, remove from cart!
// echo "<br>caughtttttttt<br>";
_pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products, false );
}
}
WC()->cart->add_to_cart( $product_id );
}
return $passed;
}
// Works, different method, faster 😎
function pekky_2_remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
// Sample values: array( 23,45,43 );
$stand_alone_products = array( 25221, 29237 ); //stand alone products
$other_products = array( 28745, 28746, 28747, 28748 ); // friendly products that can stay in the cart with others
/**
* Products attached to the standalone products
* These should be added to cart when a standalone product is in the cart.
* patterns [{standalone_product_id} => array({force_sells_ids})]
*/
$force_sells_products = array(
'29237' => array( 25556 ),
'25221' => array( 29234, 29444 ),
); //products attached to one of the stand alone products
// Add only level 2 or level three program to the cart.
if ( in_array( $product_id, $stand_alone_products ) ) {
// echo "<br>Standalone<br><br>";
_pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products );
}
// Allow other products to be in cart together.
else if ( in_array( $product_id, $other_products ) ) {
// Make sure stand alone products aren't in the cart.
foreach ( $stand_alone_products as $p_id ) {
// Is this standalone product in the cart?
if ( in_array( $p_id, array_column( WC()->cart->get_cart(), 'product_id' ) ) ) {
// echo "<br>Otherrrrrr producccts<br><br>";
// Product is there, remove.
_pekky_sort_stand_alone_products( $p_id, $stand_alone_products, $force_sells_products, false );
}
}
WC()->cart->add_to_cart( $product_id );
}
return $passed;
}
/**
* Sorts the stand alone products
*
* @param int $product_id
* @oaram array $stand_alone_products
* @param array $force_sells_products Products attached to the standalone products
* These should be added to cart/removed when their standalone product is in the cart/removed.
* Patterns [{standalone_product_id} => array({force_sells_ids})]
* @param bool $add_to_cart (optional) true, add to cart, if false, removes, default is true.
* @return bool false if empty field, true otherwise
*/
function _pekky_sort_stand_alone_products( $product_id, $stand_alone_products, $force_sells_products, $add_to_cart = true ){
if ( empty( $product_id ) || ( empty( $stand_alone_products ) || !is_array( $stand_alone_products ) )
|| ( empty( $force_sells_products ) || !is_array( $force_sells_products ) ) ){
return false;
}
//var_dump("yhhhhh<br><br>");
$wc_cart = WC()->cart;
$cart_func = 'remove_cart_item';
if ( $add_to_cart ) {
$cart_func = 'add_to_cart';
// empty cart.
$wc_cart->empty_cart();
}
$p_id = ( $add_to_cart ? $product_id : $wc_cart->generate_cart_id( $product_id ) );
// var_dump("<br><br>".$cart_func);
// var_dump("<br>product_id:".$product_id."<br>");
// var_dump( "<br>function executed: ");
$wc_cart->{"{$cart_func}"}( $p_id );
// get list of standalone product id
$product_force_sells_list = $force_sells_products[$product_id];
//var_dump($product_force_sells_list);
if( empty( $product_force_sells_list ) ){
// wrong list
return false;
}
// Also add the force_sells product to cart/remove
foreach ( $product_force_sells_list as $_id ) {
// var_dump("<br>Force_sales product id: " .$_id);
$p_id = ( $add_to_cart ? $_id : $wc_cart->generate_cart_id( $_id ) );
// var_dump("<br> function_exec:");
$wc_cart->{"{$cart_func}"}( $p_id );
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment