public function testVariantsSelectOrder()
 {
     $productData = ['productType' => ['typeId' => 'product-type', 'id' => 'test-id'], 'masterVariant' => ['id' => 1, 'sku' => 'VARIANT-1', 'attributes' => [['name' => 'size', 'value' => '36'], ['name' => 'color', 'value' => ['key' => 'black', 'label' => 'Black']]]], 'variants' => [['id' => 2, 'sku' => 'VARIANT-2', 'attributes' => [['name' => 'size', 'value' => '38'], ['name' => 'color', 'value' => ['key' => 'black', 'label' => 'Black']]]], ['id' => 3, 'sku' => 'VARIANT-3', 'attributes' => [['name' => 'color', 'value' => ['key' => 'white', 'label' => 'White']], ['name' => 'size', 'value' => '36']]], ['id' => 4, 'sku' => 'VARIANT-4', 'attributes' => [['name' => 'size', 'value' => '38'], ['name' => 'color', 'value' => ['key' => 'white', 'label' => 'White']]]]]];
     $productTypeData = ['id' => 'test-id', 'name' => 'test-type', 'attributes' => [['name' => 'size', 'type' => ['name' => 'text']], ['name' => 'color', 'type' => ['name' => 'enum', 'values' => [['key' => 'black', 'label' => 'Black'], ['key' => 'white', 'label' => 'White']]]]]];
     $selectSku = 'VARIANT-4';
     $expectedModel = ['variants' => ['36-Black' => 1, '38-Black' => 2, '36-White' => 3, '38-White' => 4], 'variantIdentifiers' => [0 => 'size', 1 => 'color'], 'attributes' => ['color' => ['key' => 'color', 'name' => 'color', 'list' => ['Black' => ['label' => 'Black', 'value' => 'Black', 'selected' => false], 'White' => ['label' => 'White', 'value' => 'White', 'selected' => true]], 'selectData' => ['Black' => ['size' => [0 => '36', 1 => '38']], 'White' => ['size' => [0 => '36', 1 => '38']]]], 'size' => ['key' => 'size', 'name' => 'size', 'list' => [36 => ['label' => '36', 'value' => '36', 'selected' => false], 38 => ['label' => '38', 'value' => '38', 'selected' => true]], 'selectData' => [36 => ['color' => [0 => 'Black', 1 => 'White']], 38 => ['color' => [0 => 'Black', 1 => 'White']]]]]];
     /**
      * @var ProductModel $model
      */
     $urlGenerator = $this->getMock('\\Symfony\\Component\\Routing\\Generator\\UrlGenerator', [], [], '', false);
     $productTypeRepository = $this->getMock('\\Commercetools\\Sunrise\\Model\\Repository\\ProductTypeRepository', [], [], '', false);
     $config = new Config(['sunrise' => ['products' => ['variantsSelector' => ['test-type' => ['size', 'color']]]]]);
     $model = new ProductModel(new NullCacheAdapter(), $config, $productTypeRepository, $urlGenerator);
     $product = ProductProjection::fromArray($productData);
     $productType = ProductType::fromArray($productTypeData);
     list($attributes, $variantKeys, $variantIdentifiers) = $model->getVariantSelectors($product, $productType, $selectSku);
     $variants = ['variants' => $variantKeys, 'variantIdentifiers' => $variantIdentifiers, 'attributes' => $attributes];
     $this->assertJsonStringEqualsJsonString(json_encode($expectedModel), json_encode($variants));
 }
 public function getVariantSelectors(ProductProjection $product, ProductType $productType, $sku)
 {
     $variantSelectors = [];
     if (isset($this->config['sunrise.products.variantsSelector'][$productType->getName()])) {
         $variantSelectors = $this->config['sunrise.products.variantsSelector'][$productType->getName()];
     }
     $variants = [];
     $attributes = [];
     /**
      * @var ProductVariant $variant
      */
     foreach ($product->getAllVariants() as $variant) {
         $variantId = $variant->getId();
         if (is_null($variant->getAttributes())) {
             continue;
         }
         $variant->getAttributes()->setAttributeDefinitions($productType->getAttributes());
         $selected = $sku == $variant->getSku();
         foreach ($variantSelectors as $attributeName) {
             $attribute = $variant->getAttributes()->getByName($attributeName);
             if ($attribute) {
                 $value = (string) $attribute->getValue();
                 $variants[$variantId][$attributeName] = $value;
                 if (!isset($attributes[$attributeName])) {
                     $attributes[$attributeName] = ['key' => $attributeName, 'name' => (string) $attribute->getName()];
                 }
                 if (!isset($attributes[$attributeName]['list'][$value])) {
                     $attributes[$attributeName]['list'][$value] = ['label' => $value, 'value' => $value, 'selected' => false];
                 }
                 if ($selected) {
                     $attributes[$attributeName]['list'][$value]['selected'] = $selected;
                 }
             }
         }
     }
     $variantKeys = [];
     $identifiers = array_values(array_intersect($variantSelectors, array_keys($attributes)));
     foreach ($variants as $variantId => $variantAttributes) {
         foreach ($identifiers as $selectorX) {
             foreach ($identifiers as $selectorY) {
                 if ($selectorX == $selectorY) {
                     continue;
                 }
                 if (isset($variantAttributes[$selectorX]) && isset($variantAttributes[$selectorY])) {
                     $valueX = $variantAttributes[$selectorX];
                     $valueY = $variantAttributes[$selectorY];
                     if (isset($attributes[$selectorX]['selectData'][$valueX][$selectorY]) && in_array($valueY, $attributes[$selectorX]['selectData'][$valueX][$selectorY])) {
                         // ignore duplicates in combination values
                         continue;
                     }
                     $attributes[$selectorX]['selectData'][$valueX][$selectorY][] = $valueY;
                 }
             }
         }
         if (count($variantAttributes) == count($identifiers)) {
             $variantKey = implode('-', $variantAttributes);
             $variantKeys[$variantKey] = $variantId;
         }
     }
     return [$attributes, $variantKeys, $identifiers];
 }