Created
June 29, 2022 08:59
-
-
Save lucasstark/2f055ccc79d26e09c51308b3a1c2c5a4 to your computer and use it in GitHub Desktop.
Use Gravity Forms to set a WooCommerce cart item's weight.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Class ES_GFPA_CartItemWeight | |
* | |
* Allows for a product to use a set of Gravity Forms fields to set the cart item's weight | |
* | |
*/ | |
class ES_GFPA_CartItemWeight { | |
private static $instances; | |
/** | |
* @param int $form_id The ID of the form to register. | |
* @param array $fields The array of field ID's to register. | |
* @param bool $display Flag to show the original / new weight as part of the cart item data. | |
* | |
* @return void | |
*/ | |
public static function register( $form_id, $fields, $display ) { | |
if ( ! isset( self::$instances[ $form_id ] ) ) { | |
self::$instances[ $form_id ] = new ES_GFPA_CartItemWeight( $form_id, $fields, $display ); | |
} | |
} | |
protected $form_id; | |
protected $fields; | |
protected $display; | |
protected function __construct( $form_id, $fields, $display = false ) { | |
$this->form_id = $form_id; | |
$this->fields = $fields; | |
$this->display = $display; | |
//Add these filter after the Gravity Forms Product Addons, which is priority 10. | |
add_filter( 'woocommerce_add_cart_item', array( $this, 'add_cart_item' ), 11, 1 ); | |
add_filter( 'woocommerce_get_cart_item_from_session', array( | |
$this, | |
'get_cart_item_from_session' | |
), 11, 2 ); | |
if ( $this->display ) { | |
add_filter( 'woocommerce_get_item_data', [ $this, 'display_cart_item_weight' ], 11, 2 ); | |
} | |
add_action( 'woocommerce_before_calculate_totals', [ $this, 'set_custom_cart_item_weight' ], 25, 1 ); | |
} | |
public function add_cart_item( $cart_item ) { | |
//Adjust price if required based on the gravity form data | |
if ( isset( $cart_item['_gravity_form_lead'] ) && isset( $cart_item['_gravity_form_data'] ) ) { | |
$gravity_form_data = $cart_item['_gravity_form_data']; | |
$gravity_form_lead = $cart_item['_gravity_form_lead']; | |
//If this isn't our form just return the cart item. | |
if ( $this->form_id != $gravity_form_data['id'] ) { | |
return $cart_item; | |
} | |
//Store the original weight | |
$product = wc_get_product( $cart_item['data']->get_id() ); | |
// The default product weight | |
$cart_item['weight']['default'] = $product->get_weight(); | |
$form_meta = RGFormsModel::get_form_meta( $gravity_form_data['id'] ); | |
//Something wrong with the form, just return the cart item. | |
if ( empty( $form_meta ) ) { | |
return $cart_item; | |
} | |
$weight = 0; | |
foreach ( $this->fields as $field_id ) { | |
if ( isset( $gravity_form_lead[ $field_id ] ) ) { | |
$weight += floatval( $gravity_form_lead[ $field_id ] ); | |
} | |
} | |
// Set the new calculated weight | |
$cart_item['weight']['new'] = $weight; | |
$cart_item['data']->set_weight( $weight ); | |
} | |
return $cart_item; | |
} | |
/** | |
* When the item is being restored from the session, call the add_cart_item function to re-calculate the cart item price. | |
* | |
* @param $cart_item | |
* @param $values | |
* | |
* @return mixed | |
*/ | |
public function get_cart_item_from_session( $cart_item, $values ) { | |
if ( isset( $cart_item['_gravity_form_lead'] ) && isset( $cart_item['_gravity_form_data'] ) ) { | |
return $this->add_cart_item( $cart_item ); | |
} else { | |
return $cart_item; | |
} | |
} | |
public function display_cart_item_weight( $item_data, $cart_item ) { | |
if ( isset( $cart_item['weight'] ) ) { | |
// Display original weight | |
if ( isset( $cart_item['weight']['default'] ) ) { | |
$item_data[] = array( | |
'key' => __( 'Weight (original)', 'woocommerce' ), | |
'value' => wc_format_weight( $cart_item['weight']['default'] ), | |
); | |
} | |
// Display calculated weight | |
if ( isset( $cart_item['weight']['new'] ) ) { | |
$item_data[] = array( | |
'key' => __( 'Weight (new)', 'woocommerce' ), | |
'value' => wc_format_weight( $cart_item['weight']['new'] ), | |
); | |
} | |
} | |
return $item_data; | |
} | |
public function set_custom_cart_item_weight( $cart ) { | |
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { | |
return; | |
} | |
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) { | |
return; | |
} | |
foreach ( $cart->get_cart() as $cart_item ) { | |
if ( isset( $cart_item['weight']['new'] ) ) { | |
$cart_item['data']->set_weight( $cart_item['weight']['new'] ); | |
} | |
} | |
} | |
} | |
//TODO: Change this registration line to your form id, and then the field id(s) from the form that equate to the weight. | |
// Change the last parameter to false to prevent the display of the original / new weight in the cart item data. | |
ES_GFPA_CartItemWeight::register( 10, array( 8 ), true ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment