/** * Insert an article attribute group. In respect of some changes in sw4, you'll need to pass a attributeoptionID as well * Also: Translations * * @param int|array $article * @return bool */ public function sArticleAttributeGroup($article) { if (empty($article) || !is_array($article)) { return false; } $article["articleID"] = $this->sGetArticleID($article); if (empty($article["articleID"])) { return false; } // If attributegroupID is not set, set filtergroupID to null if (empty($article["attributegroupID"])) { return $this->sDeleteArticleAttributeGroup((int) $article["articleID"]); } // New for sw4: OptionID also needed! if (empty($article["attributeoptionID"])) { $this->sAPI->sSetError("You need to specify 'attributeoptionID'", 10502); return false; } // If no values were passed, we're done if (empty($article["values"]) || !is_array($article["values"])) { return true; } // Get locales as iso-code. Needed for backward compability $sql = "SELECT DISTINCT LEFT(locale, 2) as isocode, l.id as id FROM s_core_shops s\n INNER JOIN s_core_locales l ON s.locale_id = l.id\n AND LEFT(l.locale,2) <> 'de'"; $languages = $this->sDB->getAll($sql); // Check if value-lengths match foreach ($languages as $languageArray) { $language = $languageArray['isocode']; if (!isset($article['values_' . $language])) { continue; } if (count($article['values_' . $language]) !== count($article['values'])) { $this->sAPI->sSetError("Value-Arrays may not differ in length", 10508); return false; } } // Models needed to persis $persistModels = array(); //Get the property group $groupModel = Shopware()->Models()->getRepository('\\Shopware\\Models\\Property\\Group')->find((int) $article["attributegroupID"]); if ($groupModel === null) { $this->sAPI->sSetError("Group not found", 10503); return false; } $optionModel = Shopware()->Models()->getRepository('\\Shopware\\Models\\Property\\Option')->find((int) $article["attributeoptionID"]); if ($optionModel === null) { $this->sAPI->sSetError("Option not found", 10504); return false; } // Check if the group already owns this option. If it doesn't: Add it $found = false; foreach ($groupModel->getOptions() as $option) { if ($option == $optionModel) { $found = true; } } if ($found === false) { $groupModel->addOption($optionModel); } // get article, set option and group $articleRepository = $this->getArticleRepository(); $articleModel = $articleRepository->find((int) $article['articleID']); if ($articleModel === null) { return false; } $articleModel->setPropertyGroup($groupModel); // Set persist models $persistModels[] = $articleModel; $persistModels[] = $groupModel; $persistModels[] = $optionModel; // Update/create value models $valueRepository = Shopware()->Models()->getRepository('\\Shopware\\Models\\Property\\Value'); foreach ($article['values'] as $key => $value) { $valueModel = $valueRepository->findOneBy(array('value' => $value, 'option' => $optionModel)); if ($valueModel === null) { $valueModel = new \Shopware\Models\Property\Value(); $valueModel->setValue($value); $valueModel->setOption($optionModel); } $persistModels[] = $valueModel; } // Persist models foreach ($persistModels as $model) { Shopware()->Models()->persist($model); } Shopware()->Models()->flush(); foreach ($languages as $languageArray) { $language = $languageArray['isocode']; $localeID = $languageArray['id']; if (!isset($article['values_' . $language])) { continue; } foreach ($article['values_' . $language] as $key => $value) { $valueModel = $valueRepository->findOneBy(array('value' => $article['values'][$key], 'option' => $optionModel)); $this->sTranslation("propertyvalue", $valueModel->getId(), $localeID, array($value)); } } return true; }
/** * @param array $data * @param \Shopware\Models\Article\Article $article * @throws \Shopware\Components\Api\Exception\CustomValidationException * @return array */ protected function preparePropertyValuesData($data, ArticleModel $article) { if (!isset($data['propertyValues'])) { return $data; } // remove assigned values if (empty($data['propertyValues'])) { return $data; } $propertyRepository = $this->getManager()->getRepository('Shopware\\Models\\Property\\Group'); /** * Get group - this is required. */ if (isset($data['propertyGroup'])) { $propertyGroup = $data['propertyGroup']; } else { $propertyGroup = $article->getPropertyGroup(); } if (!$propertyGroup instanceof \Shopware\Models\Property\Group) { throw new ApiException\CustomValidationException(sprintf("There is no propertyGroup specified")); } $models = []; foreach ($data['propertyValues'] as $valueData) { $value = null; /** @var \Shopware\Models\Property\Option $option */ $option = null; // Get value by id if (isset($valueData['id'])) { $value = $this->getManager()->getRepository('\\Shopware\\Models\\Property\\Value')->find($valueData['id']); if (!$value) { throw new ApiException\CustomValidationException(sprintf("Property value by id %s not found", $valueData['id'])); } // Get / create value by name } elseif (isset($valueData['value'])) { //get option if (isset($valueData['option'])) { // get option by id if (isset($valueData['option']['id'])) { $option = $this->getManager()->getRepository('\\Shopware\\Models\\Property\\Option')->find($valueData['option']['id']); if (!$option) { throw new ApiException\CustomValidationException(sprintf("Property option by id %s not found", $valueData['option']['id'])); } $filters = array(array('property' => "options.id", 'expression' => '=', 'value' => $option->getId()), array('property' => "groups.id", 'expression' => '=', 'value' => $propertyGroup->getId())); $query = $propertyRepository->getPropertyRelationQuery($filters, null, 1, 0); /** @var \Shopware\Models\Property\Relation $relation */ $relation = $query->getOneOrNullResult(self::HYDRATE_OBJECT); if (!$relation) { $propertyGroup->addOption($option); } // get/create option depending on associated filtergroups } elseif (isset($valueData['option']['name'])) { // if a name is passed and there is a matching option/group relation, get this option // if only a name is passed, create a new option $filters = [['property' => "options.name", 'expression' => '=', 'value' => $valueData['option']['name']], ['property' => "groups.name", 'expression' => '=', 'value' => $propertyGroup->getName()]]; $query = $propertyRepository->getPropertyRelationQuery($filters, null, 1, 0); /** @var \Shopware\Models\Property\Relation $relation */ $relation = $query->getOneOrNullResult(self::HYDRATE_OBJECT); if (!$relation) { //checks if a new option was created //because the new option is not written to the database at this point $groupOption = $this->getCollectionElementByProperty($propertyGroup->getOptions(), 'name', $valueData['option']['name']); //creates a new option if ($groupOption === null) { $option = new \Shopware\Models\Property\Option(); $propertyGroup->addOption($option); } else { $option = $groupOption; } } else { $option = $relation->getOption(); } } else { throw new ApiException\CustomValidationException("A property option need to be given for each property value"); } $option->fromArray($valueData['option']); if ($option->isFilterable() === null) { $option->setFilterable(false); } } else { throw new ApiException\CustomValidationException("A property option need to be given for each property value"); } // create the value // If there is a filter value with matching name and option, load this value, else create a new one $value = $this->getManager()->getRepository('\\Shopware\\Models\\Property\\Value')->findOneBy(['value' => $valueData['value'], 'optionId' => $option->getId()]); if (!$value) { $value = new \Shopware\Models\Property\Value($option, $valueData['value']); } if (isset($valueData['position'])) { $value->setPosition($valueData['position']); } $this->getManager()->persist($value); } else { throw new ApiException\CustomValidationException("Name or id for property value required"); } $models[] = $value; } $data['propertyValues'] = $models; return $data; }