1

I wanted to apologise off the bat for asking a question with very little prior information to go on, but im at a loss as to how to even start.

I need to create a list of SKUs based on a preset grouping of SKUs that already exists its like a combination table, or iteration table.

However doing this manually is a ridiculous task and I could find no Javascript site that would allow me to do it as required.

Using PHP Classes i thought it would be a much more efficient way to achieve the goal.

AIM: The target item will consist of 5 or so TYPES of items. For each TYPE there is approximately 15-20 exact codes it could consist of.

For example TYPE 1 could be Apple, Pear, Orange, Pineapple. Etc. TYPE 2 could be Red,Green,Blue,Black. Etc

I need to be able to input a list of Variants for each TYPE and have it concatenate the Variants in every possible iteration of an item that could exist.

I am aware this would create 10s of thousands of (in this case) SKUs.

The problem i encounter is when creating the iterations the types always duplicate. Furthermore there are exceptions to this rule, for example Variant Apple could never be with Variant Black. So those types would never be found in the same concatenated code.

Im sure that for someone out their this is really very simple basic grouping and class configuration. So I very much appreciate any help that anyone might have for this.

Many Thanks - Lewis

LewisMCT333
  • 105
  • 2
  • 10
  • Sadly I am at my work computer and do not have any of my code here. Hence the heartfelt apology. – LewisMCT333 Sep 28 '16 at 13:36
  • 1
    Sounds like you need to find the cartesian product of a bunch of arrays containing the different variant types. This would produce all the different permutations... you then need to filter out the bad results with variants that should not match. You can do this by creating an array of rules and process all the generated variants. Finally some logic to turn those into SKUs... perhaps assigning unique codes to each type? – R. Chappell Sep 28 '16 at 13:39
  • Cartesian Products! never heard of it before but after looking at the math that sounds very much like what I need. No idea how to do that in PHP though. – LewisMCT333 Sep 28 '16 at 13:42
  • 1
    Good thing you're on Stackoverflow! http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays – R. Chappell Sep 28 '16 at 13:43
  • Im so happy I could cry. This gives me a great point to go off of! Im still clueless but atleast now i know what the principle is called i can learn how to make one. If anyone has any suggestions on how to create exception ruling for this principle id be very grateful, i can and will do it on my own but sadly im against the clock on this one so anyone who wants to help is more than welcome to. – LewisMCT333 Sep 28 '16 at 13:47

1 Answers1

4

The following is something VERY QUICK and VERY DIRTY, I've just thrown it together to give you a helping hand and something to start with... so please not "ah thats rubbish code comments" ;)

<?php

class SkuGenerator2000
{
    public function generate($productId, array $variants, array $disallow)
    {
        // First lets get all of the different permutations = cartesian product
        $permutations = $this->permutate($variants);

        // Now lets get rid of the pesky combinations we don't want
        $filtered     = $this->squelch($permutations, $disallow);

        // Finally we can generate some SKU codes using the $productId as the prefix
        // this assumes you want to reuse this code for different products
        $skus         = $this->skuify($productId, $filtered);

        return $skus;
    }

    public function permutate(array $variants)
    {
        // filter out empty values
        // This is the cartesian product code
         $input  = array_filter($variants);
         $result = array(array());
         foreach ($input as $key => $values) {
             $append = array();
             foreach($result as $product) {
                 foreach($values as $item) {
                     $product[$key] = $item;
                     $append[] = $product;
                 }
             }
             $result = $append;
         }

         return $result;
    }

    public function squelch(array $permutations, array $rules)
    {
        // We need to loop over the differnt permutations we have generated
        foreach ($permutations as $per => $values) {
            $valid = true;
            $test  = array();
            // Using the values, we build up a comparison array to use against the rules
            foreach ($values as $id => $val) {
                // Add the KEY from the value to the test array, we're trying to make an
                // array which is the same as our rule
                $test[$id] = $val[0];
            }
            // Now lets check all of our rules against our new test array
            foreach ($rules as $rule) {
                // We use array_diff to get an array of differences, then count this array
                // if the count is zero, then there are no differences and our test matches
                // the rule exactly, which means our permutation is invalid
                if (count(array_diff($rule, $test)) <= 0) {
                    $valid = false;
                }
            }
            // If we found it was an invalid permutation, we need to remove it from our data
            if (!$valid) {
                unset($permutations[$per]);
            }
        }
        // return the permutations, with the bad combinations removed
        return $permutations;
    }

    public function skuify($productId, array $variants)
    {
        // Lets create a new array to store our codes
        $skus = array();

        // For each of the permutations we generated
        foreach ($variants as $variant) {
            $ids = array();
            // Get the ids (which are the first values) and add them to an array
            foreach ($variant as $vals) {
                $ids[] = $vals[0];
            }

            // Now we create our SKU code using the ids we got from our values. First lets use the
            // product id as our prefix, implode will join all the values in our array together using 
            // the separator argument givem `-`. This creates our new SKU key, and we store the original
            // variant as its value
            $skus[$productId . '-' . implode('-', $ids)] = $variant;
            // The bit above can be modified to generate the skues in a different way. It's a case of
            // dumping out our variant data and trying to figure what you want to do with it.
        }
        // finall we return our skus
        return $skus;
    }
}

// Possible variants
$variants = array(
    'brand' => array(
        // the first value in our array is our SKU identifier, this will be used to create our unqiue SKU code
        // the second value is a nice name, description if you will
        array('AP', 'Apple'),
        array('BA', 'Banana'),
        array('PE', 'Pear'),
    ),
    'color' => array(
        array('RE', 'Red'),
        array('GR', 'Green'),
        array('BL', 'Blue'),
    ),
);

// Rules for combinations I dont want
$disallow = array(
    array('brand' => 'AP', 'color' => 'GR'), // No green apples
    array('brand' => 'AP', 'color' => 'RE'), // No red apples
    array('brand' => 'PE', 'color' => 'BL'), // No blue pears
);

// Create new class
$skuGenerator = new SkuGenerator2000();

// Get me my skus!
$skus = $skuGenerator->generate('PHONE1', $variants, $disallow);

var_dump(array_keys($skus)); // Dump just the skus

// separate our data
echo "\n\n";

// Now dump the entire result!
var_dump($skus); // Dump it all
  • generate = this takes your instructions
  • permutate = the cartesian product function stolen from the link I provided before
  • squelch = removes permutations based on the rules
  • skuify = takes the product id and generates SKU codes as the key and the variant remains the value so it can be used for something else.
R. Chappell
  • 1,184
  • 6
  • 17
  • Wow that was quick, thats amazing, I truly am very grateful. This gives me a much better point to go from in regards to the exception rules as well this is pretty much exactly what i need. Although you have used some practices here that i am unfamiliar with, at the risk of asking far too much of you, would you be able to explain to me how this works? I would rather learn than just let you do it for me. But i am aware this is a tall request. – LewisMCT333 Sep 28 '16 at 15:18
  • This produces string location identifiers in the dump, is there anyway to remove those and have them split by line? – LewisMCT333 Sep 28 '16 at 15:40
  • If you remove `array_keys($skus)` on the last line and just do `var_dump($skus)` you'll see it contains everything. I'll add some comments to the code so it'll help – R. Chappell Sep 28 '16 at 15:42
  • You are a star! thanks a lot again, i will go through this all and learn how it works so i can make the alterations needed to produce the exact results i require, youve literally saved me a month of work with this so i cant thank you enough. – LewisMCT333 Sep 28 '16 at 16:51
  • So currently this produces an output of data that gives strings and number references that is less than useful. It currently looks like this:- [0]=> string(18) "SKU-SKU-SKU" [1]=> string(20) "SKU-SKU-SKU" Is there a way to make the output exclude the String references and seperate on each line? – LewisMCT333 Sep 29 '16 at 08:21