/**
  * Calculate the total measurement needed
  *
  * @since 3.4.0
  * @param object $product
  * @return float total measurement needed
  */
 private function calculate_measurement_needed($product)
 {
     $measurement_needed = null;
     // get measurement type
     $settings = new WC_Price_Calculator_Settings($product);
     $measurement_type = $settings->get_calculator_type();
     foreach ($this->measurements_needed as $measurement) {
         // convert to common unit
         $measurement_value = WC_Price_Calculator_Measurement::convert($measurement['value'], $measurement['unit'], $measurement['common_unit']);
         if ('area-surface' === $measurement_type) {
             // get dimensions
             $length = WC_Price_Calculator_Measurement::convert($this->measurements_needed['length']['value'], $this->measurements_needed['length']['unit'], $this->measurements_needed['length']['common_unit']);
             $width = WC_Price_Calculator_Measurement::convert($this->measurements_needed['width']['value'], $this->measurements_needed['width']['unit'], $this->measurements_needed['width']['common_unit']);
             $height = WC_Price_Calculator_Measurement::convert($this->measurements_needed['height']['value'], $this->measurements_needed['height']['unit'], $this->measurements_needed['height']['common_unit']);
             $measurement_needed = 2 * ($length * $width + $width * $height + $length * $height);
             /**
              * Filter surface area value.
              *
              * @since 3.5.0
              * @param float $surface_area The calculated surface area.
              * @param WP_Product $product
              * @param float $length
              * @param float $width
              * @param float $height
              */
             $measurement_needed = apply_filters('wc_measurement_price_calculator_measurement_needed_surface_area', $measurement_needed, $product, $length, $width, $height);
             break;
         }
         if ('area-linear' === $measurement_type) {
             if (!$measurement_needed) {
                 // first or single measurement
                 $measurement_needed = 2 * $measurement_value;
             } else {
                 // multiply to get either the area or volume measurement
                 $measurement_needed += 2 * $measurement_value;
             }
         } else {
             if (!$measurement_needed) {
                 // first or single measurement
                 $measurement_needed = $measurement_value;
             } else {
                 // multiply to get either the area or volume measurement
                 $measurement_needed *= $measurement_value;
             }
         }
     }
     // get common unit
     $product_measurement = WC_Price_Calculator_Product::get_product_measurement($product, $settings);
     $measurements = $settings->get_calculator_measurements();
     list($measurement) = $measurements;
     $product_measurement->set_common_unit($measurement->get_unit_common());
     /**
      * Filter the calculated measurement needed.
      *
      * @since 3.5.2
      * @param float $measurement_needed the calculated measurement needed.
      * @param string $measurement_type the calculator type e.g. "area-linear"
      * @param WP_Product $product
      * @param WC_Price_Calculator_Cart $this Measurement Price Calculator Cart instance
      */
     $measurement_needed = apply_filters('wc_measurement_price_calculator_measurement_needed', $measurement_needed, $measurement_type, $product, $this);
     // convert measurment to pricing unit
     $measurement_needed = WC_Price_Calculator_Measurement::convert($measurement_needed, $product_measurement->get_unit_common(), $settings->get_pricing_unit());
     return $measurement_needed;
 }
 /**
  * Returns the pricing rules (if any) associated with this calculator, which are
  * avilable only if the pricing calculator is enabled.  Pricing rules ranges
  * default to pricing units.
  *
  * @since 3.0
  * @param string $to_unit optional units to return the pricing rules ranges in,
  *        defaults to pricing units.
  * @return array of pricing rules with ranges in terms of $to_unit
  */
 public function get_pricing_rules($to_unit = null)
 {
     // default if the pricing calculator is not enabled
     $pricing_rules = array();
     if ($this->is_pricing_calculator_enabled() && $this->product) {
         // load the pricing rules when needed
         if (is_null($this->pricing_rules)) {
             $this->set_pricing_rules($this->product->wc_price_calculator_pricing_rules);
         }
         // default pricing rules
         $pricing_rules = $this->pricing_rules;
         // if a conversion
         if ($to_unit && $to_unit != $this->get_pricing_unit()) {
             foreach ($pricing_rules as &$rule) {
                 $rule['range_start'] = WC_Price_Calculator_Measurement::convert($rule['range_start'], $this->get_pricing_unit(), $to_unit);
                 if ('' !== $rule['range_end']) {
                     $rule['range_end'] = WC_Price_Calculator_Measurement::convert($rule['range_end'], $this->get_pricing_unit(), $to_unit);
                 }
             }
         }
     }
     return $pricing_rules;
 }
 /**
  * Gets the measurement stock quantity for the given item if its a pricing
  * calculator item with inventory enabled, for purposes of reducing the
  * product stock.  Ie, if $quantity is 2 and the item is 3 ft fabric, the
  * measurement stock returned would be 6
  *
  * @since 3.0
  * @param numeric $quantity the cart item quantity
  * @param WC_Order the order object
  * @param array $item the order item
  */
 public function get_order_item_measurement_quantity($quantity, $order, $item)
 {
     // always need the actual parent product, not the useless variation product
     $product = wc_get_product($item['product_id']);
     if (WC_Price_Calculator_Product::pricing_calculator_inventory_enabled($product) && isset($item['item_meta']['_measurement_data'][0]) && $item['item_meta']['_measurement_data'][0]) {
         $measurement_data = maybe_unserialize($item['item_meta']['_measurement_data'][0]);
         $settings = new WC_Price_Calculator_Settings($product);
         // get the measurement quantity (ie item quantity is '2' pieces of fabric at 3 ft each, so the measurement quantity is '6'
         $quantity *= WC_Price_Calculator_Measurement::convert($measurement_data['_measurement_needed'], $measurement_data['_measurement_needed_unit'], $settings->get_pricing_unit());
     }
     return $quantity;
 }