/** * @param ProductValueInterface $value * @param mixed $data * @param string $currency */ protected function addPriceForCurrency(ProductValueInterface $value, $data, $currency) { $priceValue = $this->productBuilder->addPriceForCurrency($value, $currency); $priceValue->setCurrency($currency); $priceValue->setData($data); $value->addPrice($priceValue); }
/** * Find a product by its id or return a 404 response * * @param int $id the product id * * @throws NotFoundHttpException * * @return ProductInterface */ protected function findProductOr404($id) { $product = $this->productRepository->findOneById($id); if (!$product) { throw new NotFoundHttpException(sprintf('Product with id %s could not be found.', $id)); } $this->productBuilder->addMissingAssociations($product); return $product; }
/** * @param string $identifier * @param string|null $familyCode * * @return ProductInterface */ protected function findOrCreateProduct($identifier, $familyCode) { $product = $this->repository->findOneByIdentifier($identifier); if (!$product) { $product = $this->builder->createProduct($identifier, $familyCode); } return $product; }
/** * Transform an array of values to ProductValues * * @param array $arrayValues * * @return ArrayCollection */ protected function transformArrayToValues(array $arrayValues) { $product = $this->productBuilder->createProduct(); $this->productUpdater->update($product, $arrayValues); $values = $product->getValues(); $values->removeElement($product->getIdentifier()); return $values; }
/** * {@inheritdoc} */ public function process($product) { $this->initSecurityContext($this->stepExecution); $this->productBuilder->addMissingProductValues($product); $parameters = $this->stepExecution->getJobParameters(); $normalizerContext = $this->getNormalizerContext($parameters); $productStandard = $this->normalizer->normalize($product, 'json', $normalizerContext); if ($this->areAttributesToFilter($parameters)) { $productStandard = $this->filterProperties($productStandard, $parameters->get('selected_properties')); } if ($parameters->has('with_media') && $parameters->get('with_media')) { $directory = $this->stepExecution->getJobExecution()->getExecutionContext()->get(JobInterface::WORKING_DIRECTORY_PARAMETER); $this->fetchMedia($product, $directory); } $this->detacher->detach($product); return $productStandard; }
/** * Find a product by its id or return a 404 response * * @param int $id the product id * * @throws NotFoundHttpException * * @return ProductInterface */ protected function findProductOr404($id) { $product = $this->productRepository->findOneByWithValues($id); if (!$product) { throw new NotFoundHttpException(sprintf('Product with id %s could not be found.', (string) $id)); } // With this version of the form we need to add missing values from family $this->productBuilder->addMissingProductValues($product); $this->productBuilder->addMissingAssociations($product); return $product; }
/** * Returns a ProductValue * * @param ProductInterface $product * @param ColumnInfoInterface $columnInfo * * @return ProductValueInterface */ protected function getProductValue(ProductInterface $product, ColumnInfoInterface $columnInfo) { $productValue = $product->getValue($columnInfo->getName(), $columnInfo->getLocale(), $columnInfo->getScope()); if (null === $productValue) { $attribute = $columnInfo->getAttribute(); $locale = $columnInfo->getLocale(); $scope = $columnInfo->getScope(); $productValue = $this->productBuilder->createProductValue($attribute, $locale, $scope); $product->addValue($productValue); } return $productValue; }
/** * Apply current values to a fake product and test its integrity with the product validator. * If violations are raised, values are not valid. * * Errors are stored in json format to be useable by the Product Edit Form. * * @return bool */ public function hasValidValues() { $data = json_decode($this->values, true); $locale = $this->userContext->getUiLocale()->getCode(); $data = $this->localizedConverter->convertToDefaultFormats($data, ['locale' => $locale]); $product = $this->productBuilder->createProduct('FAKE_SKU_FOR_MASS_EDIT_VALIDATION_' . microtime()); $this->productUpdater->update($product, $data); $violations = $this->productValidator->validate($product); $violations->addAll($this->localizedConverter->getViolations()); $errors = ['values' => $this->internalNormalizer->normalize($violations, 'internal_api', ['product' => $product])]; $this->errors = json_encode($errors); return 0 === $violations->count(); }
/** * Build product values from template values raw data * * @param ProductTemplateInterface $template * @param AttributeInterface[] $attributes * @param string $locale * * @return ProductValueInterface[] */ protected function buildProductValuesFromTemplateValuesData(ProductTemplateInterface $template, array $attributes, $locale) { $options = ['locale' => $locale, 'disable_grouping_separator' => true]; $values = $this->denormalizer->denormalize($template->getValuesData(), 'ProductValue[]', 'json', $options); $product = new $this->productClass(); foreach ($values as $value) { $product->addValue($value); } foreach ($attributes as $attribute) { $this->productBuilder->addAttributeToProduct($product, $attribute); } $this->productBuilder->addMissingProductValues($product); return $product->getValues(); }
/** * Remove an optional attribute from a product * * @param int $id The product id * @param int $attributeId The attribute id * * @AclAncestor("pim_enrich_product_remove_attribute") * * @throws NotFoundHttpException If product is not found or the user cannot see it * @throws AccessDeniedHttpException If the user does not have right to edit the product * @throws BadRequestHttpException If the attribute is not removable * * @return JsonResponse */ public function removeAttributeAction($id, $attributeId) { $product = $this->findProductOr404($id); if ($this->objectFilter->filterObject($product, 'pim.internal_api.product.edit')) { throw new AccessDeniedHttpException(); } $attribute = $this->findAttributeOr404($attributeId); if (!$product->isAttributeRemovable($attribute)) { throw new BadRequestHttpException(); } $this->productBuilder->removeAttributeFromProduct($product, $attribute); $this->productSaver->save($product); return new JsonResponse(); }
/** * {@inheritdoc} */ public function process($product) { $parameters = $this->stepExecution->getJobParameters(); $structure = $parameters->get('filters')['structure']; $channel = $this->channelRepository->findOneByIdentifier($structure['scope']); $this->productBuilder->addMissingProductValues($product, [$channel], $channel->getLocales()->toArray()); $productStandard = $this->normalizer->normalize($product, 'json', ['channels' => [$channel->getCode()], 'locales' => array_intersect($channel->getLocaleCodes(), $parameters->get('filters')['structure']['locales'])]); if ($this->areAttributesToFilter($parameters)) { $attributesToFilter = $this->getAttributesToFilter($parameters); $productStandard['values'] = $this->filterValues($productStandard['values'], $attributesToFilter); } if ($parameters->has('with_media') && $parameters->get('with_media')) { $directory = $this->stepExecution->getJobExecution()->getExecutionContext()->get(JobInterface::WORKING_DIRECTORY_PARAMETER); $this->fetchMedia($product, $directory); } else { $mediaAttributes = $this->attributeRepository->findMediaAttributeCodes(); $productStandard['values'] = array_filter($productStandard['values'], function ($attributeCode) use($mediaAttributes) { return !in_array($attributeCode, $mediaAttributes); }, ARRAY_FILTER_USE_KEY); } $this->detacher->detach($product); return $productStandard; }
/** * Add all the values required by the given attribute * * @param AttributeInterface $attribute * @param LocaleInterface $locale */ protected function addValues(AttributeInterface $attribute, $locale) { if ($attribute->isScopable()) { foreach ($locale->getChannels() as $channel) { $key = $attribute->getCode() . '_' . $channel->getCode(); $value = $this->productBuilder->createProductValue($attribute, $locale->getCode(), $channel->getCode()); $this->productBuilder->addMissingPrices($value); $this->values[$key] = $value; } } else { $value = $this->productBuilder->createProductValue($attribute, $locale->getCode()); $this->productBuilder->addMissingPrices($value); $this->values[$attribute->getCode()] = $value; } }
/** * Denormalize product values * * @param string $data * @param string $format * @param array $context * @param ProductInterface $product */ protected function denormalizeValues($data, $format, array $context, ProductInterface $product) { foreach ($product->getValues() as $value) { $product->removeValue($value); } foreach ($data as $attFieldName => $dataValue) { $attributeInfos = $this->attFieldExtractor->extractColumnInfo($attFieldName); $attribute = $attributeInfos['attribute']; unset($attributeInfos['attribute']); if (!$product->hasAttribute($attribute)) { $this->productBuilder->addAttributeToProduct($product, $attribute); } // Denormalize data value. // The value is already added to the product so automatically updated $productValue = $product->getValue($attribute->getCode(), $attributeInfos['locale_code'], $attributeInfos['scope_code']); $this->serializer->denormalize($dataValue, $this->productValueClass, $format, ['product' => $product, 'entity' => $productValue] + $attributeInfos + $context); } }
/** * Add missing associations (if association type has been added after the last processing) * * @param ProductInterface $product */ protected function addMissingAssociations(ProductInterface $product) { $this->productBuilder->addMissingAssociations($product); }
function it_merges_original_and_new_values(GroupInterface $variantGroup, ProductTemplateInterface $template, ProductBuilderInterface $productBuilder, ProductInterface $product, ProductValueInterface $identifier, ArrayCollection $values, \Iterator $valuesIterator) { $originalValues = ['description' => [['locale' => 'en_US', 'scope' => 'ecommerce', 'data' => 'original description en_US'], ['locale' => 'de_DE', 'scope' => 'ecommerce', 'data' => 'original description de_DE']]]; $newValues = ['description' => [['locale' => 'en_US', 'scope' => 'ecommerce', 'data' => 'new description en_US'], ['locale' => 'fr_FR', 'scope' => 'ecommerce', 'data' => 'new description fr_FR']]]; $expectedValues = ['description' => [['locale' => 'en_US', 'scope' => 'ecommerce', 'data' => 'new description en_US'], ['locale' => 'de_DE', 'scope' => 'ecommerce', 'data' => 'original description de_DE'], ['locale' => 'fr_FR', 'scope' => 'ecommerce', 'data' => 'new description fr_FR']]]; $variantGroup->getProductTemplate()->willReturn($template); $template->getValuesData()->willReturn($originalValues); $productBuilder->createProduct()->willReturn($product); $product->getValues()->willReturn($values); $product->getIdentifier()->willReturn($identifier); $values->removeElement($identifier)->shouldBeCalled(); $values->getIterator()->willReturn($valuesIterator); $template->setValues($values)->shouldBeCalled(); $template->setValuesData($expectedValues)->shouldBeCalled(); $variantGroup->setProductTemplate($template)->shouldBeCalled(); $this->setValues($variantGroup, $newValues); }