File "class.calculate-rates.php"
Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/woocommerce-table-rate-shipping/inc/class.calculate-rates.php
File size: 30.95 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/*
* Table Rate Shipping Method Extender Class
*/
if ( ! defined( 'ABSPATH' ) )
exit;
// Check if WooCommerce is active
if ( class_exists( 'WooCommerce' ) ) {
if ( class_exists( 'BE_Table_Rate_Calculate' ) ) return;
class BE_Table_Rate_Calculate {
/*
* Shipping Package Information
*/
private $method;
/*
* Table Rates from Database
*/
private $table_rates;
/**
* Cloning is forbidden. Will deactivate prior 'instances' users are running
*
* @since 4.0
*/
public function __clone() {
_doing_it_wrong( __FUNCTION__, esc_html__( 'Cloning this class could cause catastrophic disasters!', 'be-table-ship' ), '4.0' );
}
/**
* Unserializing instances of this class is forbidden.
*
* @since 4.0
*/
public function __wakeup() {
_doing_it_wrong( __FUNCTION__, esc_html__( 'Unserializing is forbidden!', 'be-table-ship' ), '4.0' );
}
/**
* __construct function.
*
* @access public
* @return void
*/
function __construct( $method, $table_rates ) {
$this->method = $method;
$this->table_rates = $table_rates;
}
/**
* calculate_shipping function.
*
* @access public
* @param array $package (default: array())
* @return array
*/
function calculate_shipping( $package = array() ) {
global $betrs_shipping;
if( is_array( $package ) && ! empty( $package ) && isset( $package['contents'] ) ) {
// calculate cart statistics for processing table rates
$cart_data = array();
switch( $this->method->condition ) {
case 'per-order':
$cart_data = array( 'per-order' => $this->calculate_totals_order( $package['contents'] ) );
break;
case 'per-item':
$cart_data = $this->calculate_totals_item( $package['contents'] );
break;
case 'per-line-item':
$cart_data = $this->calculate_totals_item( $package['contents'], true );
break;
case 'per-class':
$cart_data = $this->calculate_totals_class( $package['contents'] );
break;
default:
$cart_data = apply_filters( 'betrs_calculate_method_totals', $cart_data, $this->method->condition, $package, $this->method );
break;
}
// send to calculator for processing
$contents_cost = 0;
if( ! empty( $cart_data ) ) {
$rates = array();
foreach( $cart_data as $key => $data ) {
$rates[ $key ] = $this->process_table_rates( $data );
$contents_cost += $data['subtotal'];
}
}
$shipping_options = $first_option = array();
// ensure that all rates cover all items in the cart
if( is_array( $rates ) && count( $rates ) > 0 ) {
$n = 0;
foreach( $rates as $key => $rate ) {
if( $n == 0 ) {
$option_ids = array_keys( $rate );
$n++;
continue;
}
$option_ids = array_intersect( $option_ids, array_keys( $rate ) );
}
// remove invalid options from $rates
foreach( $rates as $key => $rate ) {
$rates[$key] = array_intersect_key( $rate, array_flip( $option_ids ) );
}
}
// Adjust for single class only if necessary
if( $this->method->condition == 'per-class' ) {
switch( $this->method->single_class ) {
case 'priority':
$highest_key = $highest_priority = 0;
foreach( $rates as $class_key => $options ) {
$get_priority = get_term_meta( $class_key, 'priority', true );
if( $get_priority >= $highest_priority ) {
$highest_priority = $get_priority;
$highest_key = $class_key;
}
}
// add contents cost for subtotal shortcode
foreach( $rates[ $highest_key ] as $op_id => $op_val ) {
$rates[ $highest_key ][ $op_id ]['contents_cost'] = $cart_data[ $highest_key ]['subtotal'];
}
return $rates[ $highest_key ];
break;
case 'cost_high':
case 'cost_low':
$options_for_return = array();
$op_class = false;
foreach( $rates as $class_key => $options ) {
foreach( $options as $op_key => $option ) {
if( ! isset( $options_for_return[ $op_key] ) ) {
// initialize an option for this ID
$options_for_return[ $op_key ] = $option;
} else {
// determine if this is the option to be returned based on cost
if( $this->method->single_class == 'cost_low' ) {
if( $option['cost'] < $options_for_return[ $op_key ]['cost'] ) {
$options_for_return[ $op_key ] = $option;
$op_class = $class_key;
}
} else {
if( $option['cost'] > $options_for_return[ $op_key ]['cost'] ) {
$options_for_return[ $op_key ] = $option;
$op_class = $class_key;
}
}
}
}
}
// add contents cost for subtotal shortcode
foreach( $options_for_return as $op_id => $op_val ) {
$options_for_return[ $op_id ]['contents_cost'] = $cart_data[ $class_key ]['subtotal'];
}
return $options_for_return;
break;
case 'disabled':
break;
default:
return apply_filters( 'betrs_condition_single_class_' . $this->method->single_class, $rates );
break;
}
}
// compile for return (combine Per Item and Per Class data to one price)
$shipping_options = array();
foreach( $rates as $key => $rate ) {
foreach( $rate as $op_key => $op ) {
if( ! isset( $shipping_options[ $op_key ] ) ) {
$shipping_options[ $op_key ] = $op;
$shipping_options[ $op_key ]['contents_cost'] = $contents_cost;
// Set title to Method Title when left empty
if( $shipping_options[ $op_key ]['label'] == '' )
$shipping_options[ $op_key ]['label'] = $this->method->method_title;
// setup option's default description
$shipping_options[ $op_key ]['description'] = ( isset( $op['description_op'] ) ) ? wp_kses( $op['description_op'], $betrs_shipping->allowedtags ) : "";
} else {
$shipping_options[ $op_key ]['cost'] += $op['cost'];
$shipping_options[ $op_key ]['row_id'] = $op['row_id'];
}
// update description if given
if( ! empty( $op['description'] ) ) {
if( $op['combine_desc'] === 'on' ) {
$shipping_options[ $op_key ]['description'] = $shipping_options[ $op_key ]['description'] . ' ' . $op['description'];
} else {
$shipping_options[ $op_key ]['description'] = $op['description'];
}
}
}
}
return apply_filters( 'betrs_calculated_shipping_options', $shipping_options, $rates );
}
}
/**
* calculate order totals (Per Order).
*
* @access public
* @param array $package (default: array())
* @return array
*/
function calculate_totals_order( $items ) {
// setup initialized variables
$subtotal = $quantity = $weight = $height = $width = $length = $area = $volume = 0;
$products = $shipping_classes = $categories = $status = array();
// cycle through cart items
foreach( $items as $item_ar ) {
// only count the ones that apply to shipping
if( isset( $item_ar['data'] ) && $item_ar['data']->needs_shipping() ) {
$item = $item_ar['data'];
// manage measurement calculations
$t_height = (float) apply_filters( 'betrs_calculated_item-height', $item->get_height(), $item_ar );
$t_width = (float) apply_filters( 'betrs_calculated_item-width', $item->get_width(), $item_ar );
$t_length = (float) apply_filters( 'betrs_calculated_item-length', $item->get_length(), $item_ar );
$t_area = array_filter( array( $t_height, $t_width ) );
$t_area = ( empty( $t_area ) ) ? 0 : array_product( $t_area );
$t_volume = array_filter( array( $t_height, $t_width, $t_length ) );
$t_volume = ( empty( $t_volume ) ) ? 0 : array_product( $t_volume );
$height += $t_height * $item_ar['quantity'];
$width += $t_width * $item_ar['quantity'];
$length += $t_length * $item_ar['quantity'];
$area += $t_area * $item_ar['quantity'];
$volume += $t_volume * $item_ar['quantity'];
// adjust number data
$subtotal += $this->get_line_item_price( $item_ar );
$quantity += $item_ar['quantity'];
$weight += $this->get_line_item_weight( $item_ar ) * $item_ar['quantity'];
// add additional product information
if( $item->get_type() == 'variation' )
$parent_id = ( version_compare( WC_VERSION, '3.0', ">=" ) ) ? $item->get_parent_id(): $item->parent->id;
$products[] = ( $item->get_type() == 'variation' ) ? $parent_id : $item->get_id();
$shipping_classes[] = apply_filters( 'betrs_settings_shipping_class', $item->get_shipping_class_id() );
$status[] = $item->get_stock_status();
$get_categories = ( $item->get_type() == 'variation' ) ? get_the_terms( $parent_id, 'product_cat' ) : get_the_terms( $item->get_id(), 'product_cat' );
if( $get_categories ) {
foreach( $get_categories as $cat ){
$categories[] = $cat->term_id;
}
}
}
}
$shipping_classes = array_unique( $shipping_classes );
$categories = array_unique( $categories );
$weight = ( $this->method->round_weight === 'yes' ) ? ceil( $weight ) : $weight;
// setup outgoing data for return
$data = array(
'subtotal' => $subtotal,
'quantity' => $quantity,
'weight' => $weight,
'height' => $height,
'width' => $width,
'length' => $length,
'area' => $area,
'volume' => $volume,
'products' => $products,
'shipping_classes' => $shipping_classes,
'categories' => $categories,
'status' => $status,
);
return apply_filters( 'betrs_calculated_totals-per_order', $data, $items );
}
/**
* calculate order totals (Per Item and Per Line Item).
*
* @access public
* @param array $package (default: array())
* @return array
*/
function calculate_totals_item( $items, $per_line = false ) {
// setup initialized variables
$data = array();
// cycle through cart items
foreach( $items as $item_ar ) {
// only count the ones that apply to shipping
if( isset( $item_ar['data'] ) && $item_ar['data']->needs_shipping() ) {
$item = $item_ar['data'];
$categories = $status = array();
// add additional product information
if( $item->get_type() == 'variation' )
$parent_id = ( version_compare( WC_VERSION, '3.0', ">=" ) ) ? $item->get_parent_id(): $item->parent->id;
// manage measurement calculations
$t_height = (float) apply_filters( 'betrs_calculated_item-height', $item->get_height(), $item_ar );
$t_width = (float) apply_filters( 'betrs_calculated_item-width', $item->get_width(), $item_ar );
$t_length = (float) apply_filters( 'betrs_calculated_item-length', $item->get_length(), $item_ar );
$t_area = array_filter( array( $t_height, $t_width ) );
$t_area = ( empty( $t_area ) ) ? 0 : array_product( $t_area );
$t_volume = array_filter( array( $t_height, $t_width, $t_length ) );
$t_volume = ( empty( $t_volume ) ) ? 0 : array_product( $t_volume );
// add additional product information
$get_categories = ( $item->get_type() == 'variation' ) ? get_the_terms( $parent_id, 'product_cat' ) : get_the_terms( $item->get_id(), 'product_cat' );
if( $get_categories ) {
foreach( $get_categories as $cat ){
$categories[] = $cat->term_id;
}
}
$status[] = $item->get_stock_status();
// get proper product ID
$product_id = $item->get_id();
if( $item->get_type() == 'variation' ) {
$product_id = ( version_compare( WC_VERSION, '3.0', ">=" ) ) ? $item->get_parent_id(): $item->parent->id;
}
// adjust numbers if Per Line Item is the selected condition
if( $per_line === true ) {
$weight = $this->get_line_item_weight( $item_ar ) * $item_ar['quantity'];
$weight = ( $this->method->round_weight === 'yes' ) ? ceil( $weight ) : $weight;
// setup outgoing data for return
$temp_ar = array(
'subtotal' => $this->get_line_item_price( $item_ar ),
'quantity' => $item_ar['quantity'],
'weight' => $weight,
'height' => $t_height * $item_ar['quantity'],
'width' => $t_width * $item_ar['quantity'],
'length' => $t_length * $item_ar['quantity'],
'area' => $t_area * $item_ar['quantity'],
'volume' => $t_volume * $item_ar['quantity'],
'products' => array( $product_id ),
'shipping_classes' => apply_filters( 'betrs_settings_shipping_class', array( $item->get_shipping_class_id() ) ),
'categories' => $categories,
'status' => $status,
);
if( isset( $data[ $item->get_id() ] ) ) {
$data[ $item->get_id() ] += $temp_ar;
} else {
$data[ $item->get_id() ] = $temp_ar;
}
} else {
$weight = $this->get_line_item_weight( $item_ar );
$weight = ( $this->method->round_weight === 'yes' ) ? ceil( $weight ) : $weight;
// setup outgoing data for return
$temp_ar = array(
'subtotal' => $this->get_line_item_price( $item_ar ) / $item_ar['quantity'],
'quantity' => $item_ar['quantity'],
'weight' => $weight,
'height' => $t_height,
'width' => $t_width,
'length' => $t_length,
'area' => $t_area,
'volume' => $t_volume,
'products' => array( $product_id ),
'shipping_classes' => apply_filters( 'betrs_settings_shipping_class', array( $item->get_shipping_class_id() ) ),
'categories' => $categories,
'status' => $status,
);
if( isset( $data[ $item->get_id() ] ) ) {
$data[ $item->get_id() ] = $this->array_add( $data[ $item->get_id() ], $temp_ar );
} else {
$data[ $item->get_id() ] = $temp_ar;
}
}
}
}
return apply_filters( 'betrs_calculated_totals-per_item', $data, $items );
}
/**
* calculate order totals.
*
* @access public
* @param array $package (default: array())
* @return array
*/
function calculate_totals_class( $items ) {
// setup empty return value
$data = array();
// cycle through cart items
foreach( $items as $item_ar ) {
// only count the ones that apply to shipping
if( isset( $item_ar['data'] ) && $item_ar['data']->needs_shipping() ) {
// initialize necessary variables
$item = $item_ar['data'];
$shipping_class_id = apply_filters( 'betrs_settings_shipping_class', $item->get_shipping_class_id() );
// add additional product information
if( $item->get_type() == 'variation' )
$parent_id = ( version_compare( WC_VERSION, '3.0', ">=" ) ) ? $item->get_parent_id(): $item->parent->id;
if( ! isset( $data[ $shipping_class_id ] ) ) {
$data[ $shipping_class_id ] = array(
'subtotal' => 0,
'quantity' => 0,
'weight' => 0,
'height' => 0,
'width' => 0,
'length' => 0,
'area' => 0,
'volume' => 0,
'products' => array(),
'shipping_classes' => array( $shipping_class_id ),
'categories' => array(),
'status' => array(),
);
}
// manage measurement calculations
$t_height = (float) apply_filters( 'betrs_calculated_item-height', $item->get_height(), $item_ar );
$t_width = (float) apply_filters( 'betrs_calculated_item-width', $item->get_width(), $item_ar );
$t_length = (float) apply_filters( 'betrs_calculated_item-length', $item->get_length(), $item_ar );
$t_area = array_filter( array( $t_height, $t_width ) );
$t_area = ( empty( $t_area ) ) ? 0 : array_product( $t_area );
$t_volume = array_filter( array( $t_height, $t_width, $t_length ) );
$t_volume = ( empty( $t_volume ) ) ? 0 : array_product( $t_volume );
// add additional product information
$get_categories = ( $item->get_type() == 'variation' ) ? get_the_terms( $parent_id, 'product_cat' ) : get_the_terms( $item->get_id(), 'product_cat' );
if( $get_categories ) {
foreach( $get_categories as $cat ){
$data[ $shipping_class_id ]['categories'][] = $cat->term_id;
}
}
$data[ $shipping_class_id ]['status'][] = $item->get_stock_status();
// calculate product weight based on settings
$weight = $this->get_line_item_weight( $item_ar ) * $item_ar['quantity'];
$weight = ( $this->method->round_weight === 'yes' ) ? ceil( $weight ) : $weight;
// retrieve correct product ID
$product_id = $item->get_id();
if( $item->get_type() == 'variation' )
$product_id = ( version_compare( WC_VERSION, '3.0', ">=" ) ) ? $item->get_parent_id(): $item->parent->id;
// setup outgoing data for return
$data[ $shipping_class_id ][ 'subtotal' ] += $this->get_line_item_price( $item_ar );
$data[ $shipping_class_id ][ 'quantity' ] += $item_ar['quantity'];
$data[ $shipping_class_id ][ 'weight' ] += $weight;
$data[ $shipping_class_id ][ 'height' ] += $t_height * $item_ar['quantity'];
$data[ $shipping_class_id ][ 'width' ] += $t_width * $item_ar['quantity'];
$data[ $shipping_class_id ][ 'length' ] += $t_length * $item_ar['quantity'];
$data[ $shipping_class_id ][ 'area' ] += $t_area * $item_ar['quantity'];
$data[ $shipping_class_id ][ 'volume' ] += $t_volume * $item_ar['quantity'];
$data[ $shipping_class_id ][ 'products' ][] = $product_id;
}
}
// clear out unnecessary data
foreach( $data as $key => $value ) {
$data[ $key ]['categories'] = array_unique( $value['categories'] );
}
return apply_filters( 'betrs_calculated_totals-per_class', $data, $items );
}
/**
* Find valid options for calculated cart data.
*
* @access public
* @param array $package (default: array())
* @return array
*/
function process_table_rates( $cart_data ) {
global $betrs_shipping;
// setup necessary variables
$rates = array();
if( ! empty( $cart_data ) && ! empty( $this->table_rates ) ) {
// step through each table rate row
foreach( $this->table_rates['settings'] as $o_key => $option ) {
$cost = false;
$description = "";
$description_op = ( isset( $option['description'] ) && ! empty( $option['description'] ) ) ? wp_kses( $option['description'], $betrs_shipping->allowedtags ) : "";
// skip processing if option is disabled
if( isset( $option['disable_op'] ) && $option['disable_op'] === 'on' ) continue;
foreach( $option['rows'] as $r_key => $row ) {
if( ! empty( $row['conditions'] ) ) {
$qualifies = false;
$results = array();
foreach( $row['conditions'] as $cond ) {
$results[] = $this->determine_condition_result( $cond, $cart_data );
}
if( in_array( true, $results ) && !in_array( false, $results ) )
$qualifies = true;
if( $qualifies === true ) {
// calculate costs for qualifying row
$cost = $this->calculate_shipping_costs( $row['costs'], $cart_data );
$description = $row['description'];
$row_id = $r_key;
}
} else {
$cost = $this->calculate_shipping_costs( $row['costs'], $cart_data );
$description = $row['description'];
$row_id = $r_key;
}
}
// setup defaults for new fields
$option_combine_desc = ( isset( $option['combine_desc'] ) ) ? sanitize_title( $option['combine_desc'] ) : 'no';
// setup shipping option if cart qualifies
if( $cost !== false ) {
$option_id = $this->generate_option_id( $option['option_id'] );
$processed_rate = array(
'id' => $option_id,
'label' => stripslashes( $option['title'] ),
'cost' => $cost,
'description' => $description,
'description_op' => $description_op,
'default' => $option['default'],
'hide_ops' => $option['hide_ops'],
'combine_desc' => $option_combine_desc,
'row_id' => $row_id,
);
$rates[ $option['option_id'] ] = apply_filters( 'betrs_processed_rate', $processed_rate, $option, $o_key, $row_id );
}
}
}
return $rates;
}
/**
* Determine if cart information qualifies for given condition.
*
* @access public
* @param array $cond, array $cart_data
* @return bool
*/
function determine_condition_result( $cond, $cart_data ) {
if( is_array( $cond ) && isset( $cond['cond_type'] ) ) {
$cond_type = sanitize_title( $cond['cond_type'] );
// perform the correct check based on condition type
if( in_array( $cond_type, array( 'subtotal', 'quantity', 'weight', 'height', 'width', 'length', 'area', 'volume' ) ) ) {
// allow third party plugins to adjust numbers conversion
$cond_tertiary = (float) apply_filters( 'betrs_condition_tertiary_' . $cond_type, wc_format_decimal( $cond['cond_tertiary'] ), $cond );
$epsilon = 0.001;
if( isset( $cart_data[ $cond_type ] ) )
$comparison = (float) $cart_data[ $cond_type ];
else
return false;
switch( $cond['cond_secondary'] ) {
case 'greater_than':
if( $comparison >= $cond_tertiary || abs($cond_tertiary - $comparison) < $epsilon )
return true;
break;
case 'less_than':
if( $comparison < $cond_tertiary || abs($cond_tertiary - $comparison) < $epsilon )
return true;
break;
case 'equal_to':
if( abs($cond_tertiary - $comparison) < $epsilon )
return true;
break;
default:
return apply_filters( 'betrs_condition_secondary_numbers', false, $cond, $cart_data );
break;
}
} elseif( in_array( $cond_type, array( 's_class', 'product', 'category', 'status' ) ) ) {
$cond_tertiary = apply_filters( 'betrs_condition_tertiary_' . $cond_type, $cond['cond_tertiary'], $cond );
switch( $cond_type ) {
case 's_class':
$comparison = apply_filters( 'betrs_comparison_tertiary_' . $cond_type, $cart_data['shipping_classes'], $cond );
break;
case 'product':
$comparison = apply_filters( 'betrs_comparison_tertiary_' . $cond_type, $cart_data['products'], $cond );
break;
case 'category':
$comparison = apply_filters( 'betrs_comparison_tertiary_' . $cond_type, $cart_data['categories'], $cond );
break;
case 'status':
$comparison = apply_filters( 'betrs_comparison_tertiary_' . $cond_type, $cart_data['status'], $cond );
break;
default:
return apply_filters( 'betrs_condition_secondary_classes', false, $cond, $cart_data );
break;
}
if( is_array( $comparison ) ) {
if( is_array( $cond_tertiary ) ) {
if( $cond['cond_secondary'] === 'includes' ) {
foreach( $comparison as $comp ) {
if( in_array( $comp, $cond_tertiary ) )
return true;
}
}
if( $cond['cond_secondary'] === 'excludes' ) {
$temp = true;
foreach( $comparison as $comp ) {
if( in_array( $comp, $cond_tertiary ) )
$temp = false;
}
return $temp;
}
} else {
if( $cond['cond_secondary'] === 'includes' && in_array( $cond_tertiary, $comparison ) )
return true;
if( $cond['cond_secondary'] === 'excludes' && ! in_array( $cond_tertiary, $comparison ) )
return true;
}
}
} elseif( $cond_type == 'dates' ) {
$dates = json_decode( stripslashes( $cond['cond_secondary'] ) );
if( isset( $dates->start ) && isset( $dates->end ) ) {
// convert dates to timestamps
$start_date = strtotime( $dates->start );
$end_date = strtotime( $dates->end );
$now = current_time('timestamp');
// Check that user date is between start & end
return ( ( $now >= $start_date ) && ( $now <= $end_date ) );
}
} elseif( $cond_type == 'times' ) {
$time_current = current_time('timestamp');
$time_conditional = strtotime( sanitize_text_field( $cond['cond_tertiary'] ) );
switch( sanitize_title( $cond['cond_secondary'] ) ) {
case 'after':
if( $time_current > $time_conditional )
return true;
break;
case 'before':
default:
if( $time_current < $time_conditional )
return true;
break;
}
return false;
} elseif( $cond_type == 'dayweek' ) {
if( sanitize_title( $cond['cond_secondary'] ) == date( 'w' ) )
return true;
} elseif( $cond_type == 'coupon' ) {
if( $cond['cond_secondary'] == 'betrs_free_ship' ) {
// check if free shipping is enabled
$applied_coupons = WC()->cart->get_applied_coupons();
foreach( $applied_coupons as $cp ) {
$c = new WC_Coupon( $cp );
if( $c->get_free_shipping() )
return true;
}
} else {
// check for custom coupon code entered
$coupon = WC()->cart->has_discount( $cond['cond_tertiary'] );
if( ( $cond['cond_secondary'] === 'excludes' && ! $coupon ) ||
( $cond['cond_secondary'] === 'includes' && $coupon ) )
return true;
}
return false;
} else {
return apply_filters( 'betrs_determine_condition_result', false, $cond, $cart_data );
}
}
return false;
}
/**
* Determine if cart information qualifies for given condition.
*
* @access public
* @param array $cond, array $cart_data
* @return float
*/
function calculate_shipping_costs( $costs, $cart_data ) {
if( ! is_array( $costs ) ) return 0;
// cycle through the different cost options
$cost_ops = apply_filters( 'betrs_shipping_cost_options', array(
'' => get_woocommerce_currency_symbol(),
'%' => '%',
'x' => esc_html__( 'multiplied by', 'be-table-ship' ),
'every' => esc_html__( 'for every', 'be-table-ship' ),
) );
$calcs = array();
foreach( $costs as $cost ) {
switch ( $cost['cost_type'] ) {
case '':
$calcs[] = $cost['cost_value'];
break;
case '%':
$calcs[] = $cart_data['subtotal'] * ( $cost['cost_value'] / 100 );
break;
case 'x':
$calcs[] = $cost['cost_value'] * $cart_data[ $cost['cost_op_extra'] ];
break;
case 'every':
if( $cost['cost_op_extra'] === 'dimensions' ) {
// determine which dimensional value to multiply by
if( isset( $cart_data[ $cost['cost_op_extra_secondary'] ] ) ) {
$calcs[] = ceil( $cart_data[ $cost['cost_op_extra_secondary'] ] / $cost['cost_op_extra_val'] ) * $cost['cost_value'];
}
} else {
// calculate the value based on select data
if( isset( $cart_data[ $cost['cost_op_extra'] ] ) ) {
$calcs[] = ceil( $cart_data[ $cost['cost_op_extra'] ] / $cost['cost_op_extra_val'] ) * $cost['cost_value'];
}
}
break;
default:
$calcs[] = (float) apply_filters( 'betrs_determine_cost_result', $cost['cost_value'], $cost['cost_type'], $cost );
break;
}
}
return array_sum( array_map( 'floatval', $calcs ) );
}
/**
* determine item price based on TRS tax and coupon settings.
*
* @access public
* @param array $item
* @return float
*/
function get_line_item_price( $item ) {
$return_cost = 0;
if( $this->method->include_coupons === 'yes' ) {
if( $this->method->includetax === 'yes' ) {
$return_cost = $item['line_total'] + $item['line_tax'];
} else {
$return_cost = $item['line_total'];
}
} else {
if( $this->method->includetax === 'yes' ) {
$return_cost = $item['line_subtotal'] + $item['line_subtotal_tax'];
} else {
$return_cost = $item['line_subtotal'];
}
}
return wc_format_decimal( apply_filters( 'betrs_calculated_item-price', $return_cost, $item, $this->method ), wc_get_price_decimals() );
}
/**
* determine item weight based on TRS volumetric settings.
*
* @access public
* @param array $item
* @return float
*/
function get_line_item_weight( $item_ar ) {
// setup item
$item = $item_ar['data'];
// set default weight
$weight = $item->get_weight();
if( isset( $this->method->volumetric_number ) && is_numeric( $this->method->volumetric_number ) && $this->method->volumetric_number > 0 ) {
// allow third party plugin overrides when necessary
$t_height = (float) apply_filters( 'betrs_calculated_item-height', $item->get_height(), $item_ar );
$t_width = (float) apply_filters( 'betrs_calculated_item-width', $item->get_width(), $item_ar );
$t_length = (float) apply_filters( 'betrs_calculated_item-length', $item->get_length(), $item_ar );
// dimensional check
if( isset( $this->method->volumetric_dim_rec ) && $this->method->volumetric_dim_rec == 'yes' ) {
if( $t_height === '' && $t_width === '' && $t_length === '' ) {
return (float) apply_filters( 'betrs_calculated_item-weight', $weight, $item_ar );
}
}
// manage measurement calculations
$t_volume = array_filter( array( $t_height, $t_width, $t_length ) );
$volume = ( empty( $t_volume ) ) ? 0 : array_product( $t_volume );
if( $this->method->volumetric_operand === 'multiply' ) {
$volumetric = $volume * $this->method->volumetric_number;
} elseif( $volume > 0 ) {
$volumetric = $volume / $this->method->volumetric_number;
} else {
$volumetric = 0;
}
if( $this->method->volumetric_exclude == 'yes' || $volumetric > $item->get_weight() )
$weight = $volumetric;
}
return (float) apply_filters( 'betrs_calculated_item-weight', $weight, $item_ar );
}
/**
* Combine numeric values of array.
*
* @access public
* @param array $array_1, array $array_2
* @return array
*/
function array_add( $array_1, $array_2 ) {
// cycle through array 1 keys
if( is_array( $array_1 ) && is_array( $array_2 ) ) {
foreach( $array_1 as $key => $value ) {
if( isset( $array_2[ $key ] ) && is_numeric( $array_1[ $key ] ) && is_numeric( $array_2[ $key ] ) ) {
$array_1[ $key ] += $array_2[ $key ];
}
}
}
return $array_1;
}
/**
* Setup shipping option ID tag.
*
* @access public
* @param int $option_id
* @return string
*/
function generate_option_id( $option_id ) {
$option_id = (int) $option_id;
return $this->method->id . ':' . $this->method->instance_id . '-' . $option_id;
}
}
}
?>