(int) $rule['id'], 'label' => '', 'cost' => 0.0, 'abort' => true, 'abort_reason' => (string) $rule['rate_abort_reason'], )); } $is_priority_break = (int) $rule['rate_priority'] === 1; if ($is_priority_break) { $kept = array(); foreach ($out as $prev) { if (!isset($prev['_class']) || $prev['_class'] !== $class) { $kept[] = $prev; } } $out = $kept; } $out[] = array( 'rule_id' => (int) $rule['id'], 'label' => (string) $rule['rate_label'], 'cost' => $cost, 'abort' => false, 'abort_reason' => '', '_class' => $class, ); if ($is_priority_break) { $broken_classes[$class] = true; } } foreach ($out as &$row) { unset($row['_class']); } unset($row); return $out; } public static function summarise_package(array $package) { $subtotal = 0.0; $weight = 0.0; $qty = 0; $needs_shipping = false; $class_qty = array(); $class_subtotal = array(); $class_weight = array(); $contents = isset($package['contents']) && is_array($package['contents']) ? $package['contents'] : array(); foreach ($contents as $item) { if (!is_array($item)) { continue; } $line_qty = (int) ($item['quantity'] ?? 0); $line_total = (float) ($item['line_total'] ?? 0); $line_w = 0.0; $product = isset($item['data']) ? $item['data'] : null; if (is_object($product)) { $unit_w = (float) (method_exists($product, 'get_weight') ? (float) $product->get_weight() : 0); $line_w = $unit_w * $line_qty; $class = method_exists($product, 'get_shipping_class_id') ? (int) $product->get_shipping_class_id() : 0; $class_slug = $class > 0 ? (string) self::class_slug_from_term_id($class) : '0'; if (method_exists($product, 'needs_shipping') && $product->needs_shipping()) { $needs_shipping = true; } elseif (!method_exists($product, 'needs_shipping')) { $needs_shipping = true; } } else { $class_slug = '0'; if ($line_qty > 0) { $needs_shipping = true; } } $subtotal += $line_total; $weight += $line_w; $qty += $line_qty; $class_qty[$class_slug] = ($class_qty[$class_slug] ?? 0) + $line_qty; $class_subtotal[$class_slug] = ($class_subtotal[$class_slug] ?? 0.0) + $line_total; $class_weight[$class_slug] = ($class_weight[$class_slug] ?? 0.0) + $line_w; } $floor = (float) apply_filters('aieo_trs_min_package_weight', 0.001); if ($needs_shipping && $qty > 0 && $weight <= 0 && $floor > 0) { $weight = $floor; foreach ($class_qty as $slug => $cqty) { if ($cqty > 0 && (!isset($class_weight[$slug]) || (float) $class_weight[$slug] <= 0)) { $class_weight[$slug] = $floor; } } } return array( 'subtotal' => $subtotal, 'total_weight' => $weight, 'total_qty' => $qty, 'class_qty' => $class_qty, 'class_subtotal' => $class_subtotal, 'class_weight' => $class_weight, ); } private static function class_slug_from_term_id($term_id) { $cache_key = 'aieo_trs_class_slug_' . (int) $term_id; $cached = wp_cache_get($cache_key, 'aieo_trs'); if ($cached !== false) { return $cached; } $term = get_term((int) $term_id, 'product_shipping_class'); $slug = ($term && !is_wp_error($term)) ? (string) $term->slug : '0'; wp_cache_set($cache_key, $slug, 'aieo_trs', HOUR_IN_SECONDS); return $slug; } private static function package_has_class(array $summary, $class) { return isset($summary['class_qty'][$class]) && (int) $summary['class_qty'][$class] > 0; } private static function condition_value($rule, array $summary, $class) { $cond = (string) $rule['rate_condition']; switch ($cond) { case 'price': if ($class !== '') { return (float) ($summary['class_subtotal'][$class] ?? 0); } return (float) $summary['subtotal']; case 'weight': if ($class !== '') { return (float) ($summary['class_weight'][$class] ?? 0); } return (float) $summary['total_weight']; case 'items': return (int) $summary['total_qty']; case 'items_in_class': if ($class !== '') { return (int) ($summary['class_qty'][$class] ?? 0); } return (int) $summary['total_qty']; default: return 0; } } private static function condition_matches($rule, array $summary, $class) { $cond = (string) $rule['rate_condition']; if ($cond === '') { return true; } $val = self::condition_value($rule, $summary, $class); if ($rule['rate_min'] !== null && $val < (float) $rule['rate_min']) { return false; } if ($rule['rate_max'] !== null && $val > (float) $rule['rate_max']) { return false; } return true; } private static function compute_cost($rule, array $summary, $class) { $qty = ($class !== '' && isset($summary['class_qty'][$class])) ? (int) $summary['class_qty'][$class] : (int) $summary['total_qty']; $weight = ($class !== '' && isset($summary['class_weight'][$class])) ? (float) $summary['class_weight'][$class] : (float) $summary['total_weight']; $price = ($class !== '' && isset($summary['class_subtotal'][$class])) ? (float) $summary['class_subtotal'][$class] : (float) $summary['subtotal']; $cost = (float) $rule['rate_cost']; $cost += (float) $rule['rate_cost_per_item'] * $qty; $cost += (float) $rule['rate_cost_per_weight_unit'] * $weight; $cost += (float) $rule['rate_cost_percent'] * $price / 100.0; if ($cost < 0) { $cost = 0; } return $cost; } } }