The user requests a Product Category and says what quantity they want of it, ie Sugar 7 lbs.
In the search results, from the database, I have the following items (which are each different products):
Sugar, 8 oz .75
Sugar, 1 lb 1.50
Sugar, 2 lb 4.00
Sugar, 5 lb 7.00
Sugar, 10 lb 11.00
Current process:
- Get the search results
- Check for the cheapest option for any one of the results (only 10 lbs would meet it) or multiples of one of the results (however many of 1 needed to match the criteria, so 7 X 1 lb)
- Put the individual product ids into an array
- Get the 1:1 permutations, but within that, use some code to add in up to 3 repeats (because 5 lbs + 2 X 1 lbs is the cheapest option, not 5 lbs + 2 lbs)
- In this, check for different quantity unit (oz vs lb) and be able to convert and compare
- Compare for cheapest and return cheapest
- I'm even disregarding where there are more than 6 elements in the permutation to weed out unlikely options and reduce overhead
This works FINE unless there are > 9 product ids (for some I have > 25), then I get this error in the logs (and a completely unrelated error in the browser): Premature end of script headers
This is a lot of code. I'm sorry, just want to be thorough! Is there a more efficient/effective way?
function processCombos($arr, $qty_search, $qty_unit_search){ //$arr is the dataset, $qty_search is 7, $qty_unit_search is 1 for lbs
$combo=array();
$pid_arr = arrayifyProductIDs($arr);
$count = count($pid_arr);
$members = pow(2,$count);
for ($i = 0; $i < $members; $i++) {
$b = sprintf("%0".$count."b",$i);
$out = array();
for ($j = 0; $j < $count; $j++) {
if ($b{$j} == '1'){
$out[] = $pid_arr[$j];
}
}
$minLength=2;
$out_max = count($out);
if ($out_max >= $minLength) {
// now add in different repeats of each of them
$repeat_max = 3;
$indiv = array();
for($k=0;$k<$out_max;$k++){
$tmp = array();
for ($r = 0; $r < $repeat_max; $r++) $tmp[$r] = array_fill(0, $r + 1, $out[$k]);
$indiv[] = $tmp;
}
$x_ct = count($indiv[0]);
$y_ct = count($indiv[1]);
$z_ct = count($indiv[2]) > 0 ? count($indiv[2]): 0;
$perm = array();
for($x=0;$x<$x_ct;$x++){
for($y=0;$y<$y_ct;$y++){
if($z_ct > 0){
for($z=0;$z<$z_ct;$z++){
$perm = array_merge($indiv[0][$x],$indiv[1][$y],$indiv[2][$z]);
}
}else{
$perm = array_merge($indiv[0][$x],$indiv[1][$y]);
}
$p=0;
$max_p=count($perm);
if($max_p >=7){
}else{
$product_ids = array();
$qty = 0;
$price = 0;
while($p < $max_p){
$product_id = $perm[$p];
$data = $arr[$product_id];
if(!$data['qty_unit_id'] OR !$data['qty']){continue;} // go to the next one if it doens't have qty or qty_unit
if($data['qty_unit_id'] == $qty_unit_search){
$product_ids[] = $product_id;
$qty += $data['qty'];
$price += $data['price'];
}else{
$unit_to_convert_data = getQtyUnitName($qty_unit_search);
$unit_to_convert = $unit_to_convert_data['abbr'];
$unit_to_convert_type = $unit_to_convert_data['conv_file'];
if($unit_to_convert_type == $data['conv_file']){
if($data['conv_file'] == "Mass"){
$product_conv = new PhpUnitsOfMeasure\PhysicalQuantity\Mass($data['qty'], $data['qty_unit']);
}else{
$product_conv = new PhpUnitsOfMeasure\PhysicalQuantity\Volume($data['qty'], $data['qty_unit']);
}
$data['qty_CONV'] = number_format($product_conv->toUnit($unit_to_convert),3,".",",");
$product_ids[] = $product_id;
$qty += $data['qty_CONV'];
$price += $data['price'];
}
}
$p++;
}
if(count($combo)==0 AND $qty >= $qty_search){
$combo = array('product_ids' => $product_ids, 'qty' => $qty, 'price' => $price);
}elseif(($qty >= $qty_search AND $price < $combo['price']) OR
($qty >= $qty_search AND $price == $combo['price'] AND $qty > $combo['qty'])){
$combo = array('product_ids' => $product_ids, 'qty' => $qty, 'price' => $price);
}else{
}
}/// i think it should go here
}
}
}
}
return $combo;
}