title: calculate product variants based on option groups and options
body: <p>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. </p>
  
  <p>So a Tshirt Product has 3 option groups and options:</p>
  
  <p><strong>Size</strong>:
  Small,
  Medium,
  Large,</p>
  
  <p><strong>Color</strong>:
  Red,
  Blue,
  Yellow,
  Black,</p>
  
  <p><strong>Material</strong>:
  Cotton,
  Nylon,</p>
  
  <p>which creates: small red cotton, small red nylon, small blue cotton, small blue nylon, ... so on and so forth</p>
  
  <p>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.</p>
  
  <pre><code>    if(count($option_groups) &gt; 1)
      {
          // start the variants up
          foreach($option_groups[0]-&gt;get_options() as $option)
          {
              $variants[] = array($option);
          }
  
          // go through every other option group to make combos
          for($x = 1; $x &lt; count($option_groups); $x++)
          {
              $combos = array();
  
              foreach($variants as $variant)
              {
                  $new = array();
                  foreach($option_groups[$x]-&gt;get_options() as $option)
                  {
                      $tmp        = $variant;
                      $tmp[]  = $option;
                      $new[]  = $tmp;
                  }
                  $combos[] = $new;
              }
              $variants = array();
              foreach($combos as $combo)
              {
                  foreach($combo as $tmp)
                  {
                      $variants[] = $tmp;
                  }
              }
          }
      }
  </code></pre>
  
  <p>This isn't super time sensitive, but I'd like to have a more maintainable chunk of code, this is pretty gross.</p>
  
  <p>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.</p>
  
  <p><strong>EDIT</strong>
  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!</p>
  
  <pre><code>private function _possible_combos($groups, $prefix = array())
  {
      $result = array();
      $group  = array_shift($groups);
      foreach($group-&gt;get_options() as $selected)
      {
          if($groups)
          {
              $tmp            = $prefix;
              $tmp[]      = $selected;
            $result = array_merge($result, $this-&gt;_possible_combos($groups, $tmp));
          }
          else
          {
              $tmp            = $prefix;
              $tmp[]      = $selected;
            $result[] = $tmp; 
          }
      }
  
      return $result;
  }
  </code></pre>