I am writing an ecommerce site, and need a good way to calculate product variations. The Site has products, products can have many option groups, option groups can have many options.
So a Tshirt Product has 3 option groups and options:
Size: Small, Medium, Large,
Color: Red, Blue, Yellow, Black,
Material: Cotton, Nylon,
which creates: small red cotton, small red nylon, small blue cotton, small blue nylon, ... so on and so forth
I know that the script below works, but also that it can be optimized. Can anyone furnish a better working example of this? It should be possible using recursion as well... but I'm hitting a mental block.
if(count($option_groups) > 1)
{
// start the variants up
foreach($option_groups[0]->get_options() as $option)
{
$variants[] = array($option);
}
// go through every other option group to make combos
for($x = 1; $x < count($option_groups); $x++)
{
$combos = array();
foreach($variants as $variant)
{
$new = array();
foreach($option_groups[$x]->get_options() as $option)
{
$tmp = $variant;
$tmp[] = $option;
$new[] = $tmp;
}
$combos[] = $new;
}
$variants = array();
foreach($combos as $combo)
{
foreach($combo as $tmp)
{
$variants[] = $tmp;
}
}
}
}
This isn't super time sensitive, but I'd like to have a more maintainable chunk of code, this is pretty gross.
Also does this problem (I feel like it isn't an original problem, many carts do this) have a name? I wasn't pulling anything up on google for this problem.
EDIT This is what I ended up with, its based off of profitphp's solution, but maintains my objects instead of giving me the options per variant concatenated as a string. All thanks to Profitphp!
private function _possible_combos($groups, $prefix = array())
{
$result = array();
$group = array_shift($groups);
foreach($group->get_options() as $selected)
{
if($groups)
{
$tmp = $prefix;
$tmp[] = $selected;
$result = array_merge($result, $this->_possible_combos($groups, $tmp));
}
else
{
$tmp = $prefix;
$tmp[] = $selected;
$result[] = $tmp;
}
}
return $result;
}
This should do the trick:
<?
$data[]=array('shirt');
$data[]=array('red','yellow','black');
$data[]=array('small','medium','large');
$combos=possible_combos($data);
//calculate all the possible comobos creatable from a given choices array
function possible_combos($groups, $prefix='') {
$result = array();
$group = array_shift($groups);
foreach($group as $selected) {
if($groups) {
$result = array_merge($result, possible_combos($groups, $prefix . $selected. ' '));
} else {
$result[] = $prefix . $selected;
}
}
return $result;
}
echo count($combos) . "\n";
print_r($combos);
Tested: http://www.ideone.com/NZE5S
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With