for my convenience I have created the data structure of your Woocommerce in the most similar way possible.
You can test it with php client php x.php
<?php
function get_current_user_id(){
return 1;
}
function wp_list_pluck($items,$column){
$ares=[];
foreach($items as $item){
foreach($item as $k=>$v){
if( $k==$column){
$ares[]=$v;
}
}
}
return $ares;
}
$wc=[
"customer"=>[
"get_shipping_country"=>"Italy",
"get_shipping_state"=>"Not yet shipped",
"get_shipping_postcode"=>"32029",
"get_shipping_city"=>"Beautiful Field",
"get_shipping_address"=>"Road of Trees",
"get_shipping_address_2"=>""
],
"cart"=> [
"get_contents" => [
["prod_id"=>1, "shipping_group"=>["plane"],'line_total'=>11.00 ,'needs_shipping'=>true],
["prod_id"=>2, "shipping_group"=>["truck"],'line_total'=>14.00 ,'needs_shipping'=>true],
["prod_id"=>3, "shipping_group"=>[ 11, 15, 17],'line_total'=>16.00,'needs_shipping'=>true],
["prod_id"=>4, "shipping_group"=>["plane"],'line_total'=>22.00 ,'needs_shipping'=>true],
["prod_id"=>5, "shipping_group"=>["truck"],'line_total'=>24.00 ,'needs_shipping'=>true],
["prod_id"=>6, "shipping_group"=>[ 11, 15, 17],'line_total'=>26.00,'needs_shipping'=>true],
["prod_id"=>7, "shipping_group"=>["plane"],'line_total'=>32.00 ,'needs_shipping'=>true],
["prod_id"=>8, "shipping_group"=>["truck"],'line_total'=>34.00 ,'needs_shipping'=>true],
["prod_id"=>9, "shipping_group"=>[ 11, 15, 17],'line_total'=>36.00,'needs_shipping'=>true]
]
]
];
$wc["cart"]["get_cart"]=[
'contents' => $wc["cart"]["get_contents"],
'contents_cost' => array_sum( wp_list_pluck( $wc["cart"]["get_contents"], 'line_total' ) ),
'user' => array('ID' => get_current_user_id()),
'destination' => [
'country' => $wc["customer"]["get_shipping_country"],
'state' => $wc["customer"]["get_shipping_state"],
'postcode' => $wc["customer"]["get_shipping_postcode"],
'city' => $wc["customer"]["get_shipping_city"],
'address' => $wc["customer"]["get_shipping_address"],
'address_2' => $wc["customer"]["get_shipping_address_2"]
]
];
function arrarr_unique($a){
$l=[];$r=[];
foreach($a as $e){
$l[]=json_encode($e);
}
$lu = array_unique($l);
foreach($lu as $e){
$r[]=json_decode($e);
}
return $r;
}
function filter_match_shipping($items, $array_group){
$res=[];
foreach($items as $item){
if ($item["shipping_group"]==$array_group){
$res[]=$item;
}
}
return $res;
}
function add_filter(){
//do nothing
}
add_filter( 'woocommerce_cart_shipping_packages', 'wtf' );
function wtf($wc,$packages=[]){
$cts = $wc["cart"]["get_contents"];
$groups = arrarr_unique(wp_list_pluck($cts,'shipping_group'));
//Settings
$splitted_packages=[];
foreach($groups as $g){
$k=json_encode($g);
$splitted_packages[$k]=[];
}
//Fill
foreach($groups as $g){
$k=json_encode($g);
$splitted_packages[$k][] = filter_match_shipping( $cts,$g );
}
// Add grouped items as packages
if(is_array($splitted_packages)){
$c=0;
foreach($splitted_packages as $k => $splitted_package_items){
$packages[] = array(
'contents' => $splitted_package_items,
'contents_cost' => array_sum( wp_list_pluck( $splitted_package_items, 'line_total' ) ),
'user' => array(
'ID' => get_current_user_id(),
),
'destination' => array(
'country' => $wc["customer"]["get_shipping_country"],
'state' => $wc["customer"]["get_shipping_state"],
'postcode' => $wc["customer"]["get_shipping_postcode"],
'city' => $wc["customer"]["get_shipping_city"],
'address' => $wc["customer"]["get_shipping_address"],
'address_2' => $wc["customer"]["get_shipping_address_2"]
)
);
}
}
return $packages;
}
$pks = wtf($wc);
echo print_r($pks,1);
?>
Here the result:
Array
(
[0] => Array
(
[contents] => Array
(
[0] => Array
(
[0] => Array
(
[prod_id] => 1
[shipping_group] => Array
(
[0] => plane
)
[line_total] => 11
[needs_shipping] => 1
)
[1] => Array
(
[prod_id] => 4
[shipping_group] => Array
(
[0] => plane
)
[line_total] => 22
[needs_shipping] => 1
)
[2] => Array
(
[prod_id] => 7
[shipping_group] => Array
(
[0] => plane
)
[line_total] => 32
[needs_shipping] => 1
)
)
)
[contents_cost] => 0
[user] => Array
(
[ID] => 1
)
[destination] => Array
(
[country] => Italy
[state] => Not yet shipped
[postcode] => 32029
[city] => Beautiful Field
[address] => Road of Trees
[address_2] =>
)
)
[1] => Array
(
[contents] => Array
(
[0] => Array
(
[0] => Array
(
[prod_id] => 2
[shipping_group] => Array
(
[0] => truck
)
[line_total] => 14
[needs_shipping] => 1
)
[1] => Array
(
[prod_id] => 5
[shipping_group] => Array
(
[0] => truck
)
[line_total] => 24
[needs_shipping] => 1
)
[2] => Array
(
[prod_id] => 8
[shipping_group] => Array
(
[0] => truck
)
[line_total] => 34
[needs_shipping] => 1
)
)
)
[contents_cost] => 0
[user] => Array
(
[ID] => 1
)
[destination] => Array
(
[country] => Italy
[state] => Not yet shipped
[postcode] => 32029
[city] => Beautiful Field
[address] => Road of Trees
[address_2] =>
)
)
[2] => Array
(
[contents] => Array
(
[0] => Array
(
[0] => Array
(
[prod_id] => 3
[shipping_group] => Array
(
[0] => 11
[1] => 15
[2] => 17
)
[line_total] => 16
[needs_shipping] => 1
)
[1] => Array
(
[prod_id] => 6
[shipping_group] => Array
(
[0] => 11
[1] => 15
[2] => 17
)
[line_total] => 26
[needs_shipping] => 1
)
[2] => Array
(
[prod_id] => 9
[shipping_group] => Array
(
[0] => 11
[1] => 15
[2] => 17
)
[line_total] => 36
[needs_shipping] => 1
)
)
)
[contents_cost] => 0
[user] => Array
(
[ID] => 1
)
[destination] => Array
(
[country] => Italy
[state] => Not yet shipped
[postcode] => 32029
[city] => Beautiful Field
[address] => Road of Trees
[address_2] =>
)
)
)
To clarify, I divide the script into its basic parts below
Data structure: I used Array of array but the sintax of your WC Class and methods call can be simply identify.
$wc=[
"customer"=>[
"get_shipping_country"=>"Italy",
"get_shipping_state"=>"Not yet shipped",
"get_shipping_postcode"=>"32029",
"get_shipping_city"=>"Beautiful Field",
"get_shipping_address"=>"Road of Trees",
"get_shipping_address_2"=>""
],
"cart"=> [
"get_contents" => [
["prod_id"=>1, "shipping_group"=>["plane"],'line_total'=>11.00 ,'needs_shipping'=>true],
["prod_id"=>2, "shipping_group"=>["truck"],'line_total'=>14.00 ,'needs_shipping'=>true],
["prod_id"=>3, "shipping_group"=>[ 11, 15, 17],'line_total'=>16.00,'needs_shipping'=>true],
["prod_id"=>4, "shipping_group"=>["plane"],'line_total'=>22.00 ,'needs_shipping'=>true],
["prod_id"=>5, "shipping_group"=>["truck"],'line_total'=>24.00 ,'needs_shipping'=>true],
["prod_id"=>6, "shipping_group"=>[ 11, 15, 17],'line_total'=>26.00,'needs_shipping'=>true],
["prod_id"=>7, "shipping_group"=>["plane"],'line_total'=>32.00 ,'needs_shipping'=>true],
["prod_id"=>8, "shipping_group"=>["truck"],'line_total'=>34.00 ,'needs_shipping'=>true],
["prod_id"=>9, "shipping_group"=>[ 11, 15, 17],'line_total'=>36.00,'needs_shipping'=>true]
]
]
];
$wc["cart"]["get_cart"]=[
'contents' => $wc["cart"]["get_contents"],
'contents_cost' => array_sum( wp_list_pluck( $wc["cart"]["get_contents"], 'line_total' ) ),
'user' => array('ID' => get_current_user_id()),
'destination' => [
'country' => $wc["customer"]["get_shipping_country"],
'state' => $wc["customer"]["get_shipping_state"],
'postcode' => $wc["customer"]["get_shipping_postcode"],
'city' => $wc["customer"]["get_shipping_city"],
'address' => $wc["customer"]["get_shipping_address"],
'address_2' => $wc["customer"]["get_shipping_address_2"]
]
];
The i create Fake Woocommerce function in order for the script to work
function get_current_user_id(){
return 1;
}
function wp_list_pluck($items,$column){
$ares=[];
foreach($items as $item){
foreach($item as $k=>$v){
if( $k==$column){
$ares[]=$v;
}
}
}
return $ares;
}
function add_filter(){
//do nothing
}
Then some function to support the process
function arrarr_unique($a){
$l=[];$r=[];
foreach($a as $e){
$l[]=json_encode($e);
}
$lu = array_unique($l);
foreach($lu as $e){
$r[]=json_decode($e);
}
return $r;
}
function filter_match_shipping($items, $array_group){
$res=[];
foreach($items as $item){
if ($item["shipping_group"]==$array_group){
$res[]=$item;
}
}
return $res;
}
The function of the Woocommerce Filter to add .
add_filter( 'woocommerce_cart_shipping_packages', 'wtf' );
function wtf($wc,$packages=[]){
$cts = $wc["cart"]["get_contents"];
$groups = arrarr_unique(wp_list_pluck($cts,'shipping_group'));
//Settings
$splitted_packages=[];
foreach($groups as $g){
$k=json_encode($g);
$splitted_packages[$k]=[];
}
//Fill
foreach($groups as $g){
$k=json_encode($g);
$splitted_packages[$k][] = filter_match_shipping( $cts,$g );
}
// Add grouped items as packages
if(is_array($splitted_packages)){
$c=0;
foreach($splitted_packages as $k => $splitted_package_items){
$packages[] = array(
'contents' => $splitted_package_items,
'contents_cost' => array_sum( wp_list_pluck( $splitted_package_items, 'line_total' ) ),
'user' => array(
'ID' => get_current_user_id(),
),
'destination' => array(
'country' => $wc["customer"]["get_shipping_country"],
'state' => $wc["customer"]["get_shipping_state"],
'postcode' => $wc["customer"]["get_shipping_postcode"],
'city' => $wc["customer"]["get_shipping_city"],
'address' => $wc["customer"]["get_shipping_address"],
'address_2' => $wc["customer"]["get_shipping_address_2"]
)
);
}
}
return $packages;
}
$pks = wtf($wc);
echo print_r($pks,1);
It is possible that there are some tweaks to do that I will do with pleasure. For any clarification or problem solving. write me in the comments.