/**
  * @param      $id
  * @param      $articleData
  * @param bool $recursiveCall
  * @return array
  */
 public function getArticleConfigurator($id, $articleData, $recursiveCall = false)
 {
     $id = intval($id);
     //get posted groups and options
     $selectedItems = $this->sSYSTEM->_POST["group"];
     if (empty($selectedItems)) {
         $selectedItems = array();
     }
     /**@var $repository \Shopware\Models\Article\Repository*/
     $repository = Shopware()->Models()->Article();
     /**@var $article \Shopware\Models\Article\Article*/
     $article = $this->getSingleArticle($id);
     //the data property contains now the configurator set. Set configurator set has the array keys "options" and "groups"
     //where the assigned configurator options and groups are.
     $data = $repository->getArticleConfiguratorSetByArticleIdIndexedByIdsQuery($id)->getArrayResult();
     $data = $data[0]['configuratorSet'];
     $customerGroupKey = $this->sSYSTEM->sUSERGROUP;
     if (empty($customerGroupKey)) {
         $customerGroupKey = 'EK';
     }
     if (empty($data)) {
         return $articleData;
     }
     //first we convert the configurator set settings from the new structure to the old structure.
     $settings = $this->getConfiguratorSettings($data, $article);
     $optionsIds = array();
     $mainDetailOptions = $this->getConfiguratorOptionsForVariantId($article['mainDetailId']);
     //now we iterate all activated options and assign them to the corresponding group.
     foreach ($data['options'] as $option) {
         //the convert functions changes the property names, so we save the ids in internal helper properties.
         $groupId = $option['groupId'];
         $optionId = $option['id'];
         //the groups in the data property indexed by their ids, so we can use "array_key_exists" to check if the group id of the current options exists in our group array.
         if (array_key_exists($groupId, $data['groups'])) {
             //if the group exist, we save the option id into in helper array. This helper array is only used for "configurator - tables".
             $optionsIds[] = $optionId;
             $selected = 0;
             if (empty($selectedItems)) {
                 /**@var $mainDetailOption \Shopware\Models\Article\Configurator\Option*/
                 foreach ($mainDetailOptions as $mainDetailOption) {
                     if ($mainDetailOption['id'] === $optionId) {
                         $selected = 1;
                     }
                 }
             } else {
                 $selected = (int) (array_key_exists($groupId, $selectedItems) && $selectedItems[$groupId] == $optionId);
             }
             //now we convert the configurator option data from the old property structure to new one.
             $option = $this->getConvertedOptionData($option);
             $option = $this->module->sGetTranslation($option, $option['optionID'], 'configuratoroption');
             $option['user_selected'] = $selected;
             $option['selected'] = $selected;
             //now we assign the option into the options array element to corresponding group.
             $data['groups'][$groupId]['options'][$optionId] = $option;
         }
     }
     //now we iterate all groups to convert them from the old property structure to new one.
     $sConfigurator = array();
     foreach ($data['groups'] as $group) {
         $data = $this->getConvertGroupData($group);
         $isSelected = (int) array_key_exists($group['id'], $selectedItems) && !empty($selectedItems[$group['id']]);
         //if the current group id exists in the post data, the group was selected already.
         $data['user_selected'] = $isSelected;
         $data['selected'] = $isSelected;
         $data = $this->module->sGetTranslation($data, $group['id'], 'configuratorgroup');
         $sConfigurator[] = $data;
     }
     /**
      * If the configurator set is configured as a table configurator, we have to create the "table structure array"
      * this array looks like this:
      * ['SIZE XXL']
      *     ['COLOR YELLOW']
      *     ['COLOR GREEN']
      *     ['COLOR RED']
      * ['SIZE L']
      *     ['COLOR YELLOW']
      *     ['COLOR GREEN']
      *     ['COLOR RED']
      * ...
      */
     $sConfiguratorValues = array();
     if ($settings['type'] == self::TYPE_TABLE) {
         $sConfiguratorValues = $this->getTableConfiguratorData($id, $optionsIds, $articleData, $article, $customerGroupKey);
     }
     //now we check if the sQuantity property is set in the post.
     $quantity = 1;
     if (!empty($this->sSYSTEM->_POST["sQuantity"]) && is_numeric($this->sSYSTEM->_POST["sQuantity"])) {
         $quantity = (int) $this->sSYSTEM->_POST["sQuantity"];
     }
     $articleData["quantity"] = $quantity;
     //if the posted quantity is lesser then the min purchase we have to set the min purchase as quantity
     if (empty($articleData["quantity"]) || $articleData["quantity"] < $articleData["minpurchase"]) {
         $articleData["quantity"] = $articleData["minpurchase"];
     }
     $selected = null;
     //if some items was selected from the user, we have to select the first available variant
     if (!empty($selectedItems)) {
         $builder = $this->getSelectionQueryBuilder($selectedItems);
         $builder->setParameter('articleId', $id);
         $builder->setParameter('customerGroup', $customerGroupKey);
         $selected = $builder->getQuery()->getArrayResult();
         if (empty($selected)) {
             $builder = $this->getSelectionQueryBuilder($selectedItems);
             $builder->setParameter('articleId', $id);
             $builder->setParameter('customerGroup', 'EK');
             $selected = $builder->getQuery()->getArrayResult();
         }
         //we can only set one variant as select, so we select the first one
         $detailData = $selected[0];
         if (!empty($detailData)) {
             if ($article['lastStock'] && $detailData['inStock'] < 1) {
                 $detailData['active'] = 0;
             }
             if (empty($detailData['prices'])) {
                 $detailData['prices'] = $this->getDefaultPrices($detailData['id']);
             }
             $detailData['prices'] = $this->getConvertedPrices($detailData['prices'], $articleData["tax"], $articleData["taxID"]);
             $selected = $this->getConvertedDetail($detailData);
             $attributeIndex = 1;
             //at least we creates the old "attr1-X" attributes with the option id as value.
             foreach ($detailData['configuratorOptions'] as $option) {
                 $attribute = 'attr' . $attributeIndex;
                 $selected[$attribute] = $option['id'];
                 $attributeIndex++;
             }
         }
     }
     if (!empty($selectedItems) && empty($selected)) {
         if ($settings['type'] == self::TYPE_STANDARD) {
             unset($this->sSYSTEM->_POST["group"]);
             return $this->getArticleConfigurator($id, $articleData, true);
         } elseif ($settings['type'] == self::TYPE_SELECTION) {
             $group = $this->sSYSTEM->_POST["group"];
             array_pop($group);
             $this->sSYSTEM->_POST["group"] = $group;
             return $this->getArticleConfigurator($id, $articleData, true);
         }
     }
     if (empty($selected)) {
         // Limiting the results with setMaxResults(1) will result in only one price being selected SW-4465
         $query = $repository->getConfiguratorTablePreSelectionItemQuery($id, $customerGroupKey, $article['lastStock'] === 1);
         $query->setFirstResult(0)->setMaxResults(1);
         $detail = $this->getOneOrNullResult($query);
         if ($article['lastStock'] && $detail['inStock'] < 1) {
             $detail['active'] = 0;
         }
         $preSelectedOptions = $detail['configuratorOptions'];
         foreach ($sConfigurator as &$group) {
             $preSelectedOption = $preSelectedOptions[$group['groupID']];
             $id = $preSelectedOption['id'];
             if (array_key_exists($id, $group['values'])) {
                 $group['values'][$preSelectedOption['id']]['user_selected'] = 1;
                 $group['values'][$preSelectedOption['id']]['selected'] = 1;
             }
         }
         if (!empty($detail)) {
             if (empty($detail['prices'])) {
                 $detail['prices'] = $this->getDefaultPrices($detail['id']);
             }
             $detail['prices'] = $this->getConvertedPrices($detail['prices'], $articleData["tax"], $articleData["taxID"]);
             $selected = $this->getConvertedDetail($detail);
         }
     }
     //if one variant are selected we have to calculate the prices and get the price
     if (!empty($selected)) {
         $selectedPrice = $selected['price'][0];
         foreach ($selected['price'] as $price) {
             if (!is_numeric($price['to'])) {
                 $selectedPrice = $price;
                 break;
             } elseif ($quantity < $price['to']) {
                 $selectedPrice = $price;
                 break;
             }
         }
         if (!empty($articleData['pricegroupActive'])) {
             $articleData['sBlockPrices'] = $this->module->sGetPricegroupDiscount($this->sSYSTEM->sUSERGROUP, $articleData["pricegroupID"], $selected['price'][0]['priceNet'], 1, true, $articleData);
         } elseif (count($selected['price']) > 1) {
             $articleData['sBlockPrices'] = $selected['price'];
         } else {
             $articleData['sBlockPrices'] = array();
         }
         if ($selected['kind'] > 1) {
             $articleData = $this->mergeSelectedAndArticleData($articleData, $selected, $selectedPrice);
             $articleData = $this->module->sGetTranslation($articleData, $selected['valueID'], 'variant');
         } else {
             $articleData["active"] = $selected["active"];
         }
         $articleData["sConfiguratorSelection"] = $selected;
     }
     $articleData['sConfiguratorValues'] = $sConfiguratorValues;
     $articleData['sConfigurator'] = $sConfigurator;
     $articleData['sConfiguratorSettings'] = $settings;
     if ($recursiveCall) {
         $articleData['sError']['variantNotAvailable'] = true;
     }
     return $articleData;
 }