LewisMCT333 LewisMCT333 - 2 months ago 14
PHP Question

Creating SKU Codes Using PHP

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

Answer

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.