/**
  * {@inheritdoc}
  */
 protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context)
 {
     if (!$group->getType()->isVariant() || null === $group->getProductTemplate()) {
         return [];
     }
     $valuesData = $group->getProductTemplate()->getValuesData();
     $values = $this->valuesDenormalizer->denormalize($valuesData, 'ProductValue[]', 'json');
     $normalizedValues = [];
     foreach ($values as $value) {
         $normalizedValues = array_replace($normalizedValues, $this->serializer->normalize($value, $format, ['entity' => 'product'] + $context));
     }
     ksort($normalizedValues);
     return $normalizedValues;
 }
 function it_updates_a_variant_group($attributeRepository, $groupTypeRepository, $productBuilder, GroupInterface $variantGroup, AttributeInterface $attribute, GroupTypeInterface $type, GroupTranslation $translatable, ProductInterface $product, ProductTemplateInterface $productTemplate)
 {
     $groupTypeRepository->findOneByIdentifier('VARIANT')->willReturn($type);
     $attributeRepository->findOneByIdentifier('main_color')->willReturn($attribute);
     $attributeRepository->findOneByIdentifier('secondary_color')->willReturn($attribute);
     $variantGroup->getTranslation()->willReturn($translatable);
     $translatable->setLabel('T-shirt super beau')->shouldBeCalled();
     $variantGroup->setCode('mycode')->shouldBeCalled();
     $variantGroup->setLocale('fr_FR')->shouldBeCalled();
     $variantGroup->setType($type)->shouldBeCalled();
     $variantGroup->getId()->willReturn(null);
     $variantGroup->addAxisAttribute(Argument::any())->shouldBeCalled();
     $productTemplate->getValuesData()->willReturn([]);
     $productTemplate->setValues(Argument::any())->shouldBeCalled();
     $productTemplate->setValuesData(['main_color' => [['locale' => null, 'scope' => null, 'data' => 'white']]])->shouldBeCalled();
     $variantGroup->getProductTemplate()->willReturn($productTemplate);
     $variantGroup->setProductTemplate($productTemplate)->shouldBeCalled();
     $productValue = new ProductValue();
     $identifierValue = new ProductValue();
     $productBuilder->createProduct()->willReturn($product);
     $product->getValues()->willReturn(new ArrayCollection([$productValue, $identifierValue]));
     $product->getIdentifier()->willReturn($identifierValue);
     $values = ['code' => 'mycode', 'axis' => ['main_color', 'secondary_color'], 'type' => 'VARIANT', 'labels' => ['fr_FR' => 'T-shirt super beau'], 'values' => ['main_color' => [['locale' => null, 'scope' => null, 'data' => 'white']]]];
     $this->update($variantGroup, $values, []);
 }
 /**
  * Normalize the variant group values
  *
  * @param GroupInterface $variantGroup
  *
  * @return array
  */
 protected function normalizeVariantGroupValues(GroupInterface $variantGroup)
 {
     if (null === ($template = $variantGroup->getProductTemplate())) {
         return [];
     }
     return $template->getValuesData();
 }
 function it_handles_media_values_of_variant_group_product_templates($templateMediaManager, $eventDispatcher, GroupInterface $group, GroupType $type, ProductTemplateInterface $template)
 {
     $group->getType()->willReturn($type);
     $group->getCode()->willReturn('my_code');
     $type->isVariant()->willReturn(true);
     $group->getProductTemplate()->willReturn($template);
     $templateMediaManager->handleProductTemplateMedia($template)->shouldBeCalled();
     $eventDispatcher->dispatch(StorageEvents::PRE_SAVE, Argument::cetera())->shouldBeCalled();
     $eventDispatcher->dispatch(StorageEvents::POST_SAVE, Argument::cetera())->shouldBeCalled();
     $this->save($group);
 }
 function it_throws_an_exception_if_media_of_variant_group_is_not_found($normalizer, $denormalizer, ArrayCollection $productValuesCollection, ArrayCollection $mediaCollection, ProductMediaInterface $media, GroupInterface $variantGroup, ProductTemplateInterface $productTemplate, ProductValueInterface $productValue)
 {
     $variantGroup->getProductTemplate()->willReturn($productTemplate);
     $variantGroup->getCode()->willReturn('my_variant_group');
     $productTemplate->getValuesData()->willReturn([$productValue]);
     $denormalizer->denormalize([$productValue], 'ProductValue[]', 'json')->willReturn($productValuesCollection);
     $productValuesCollection->filter(Argument::cetera())->willReturn($mediaCollection);
     $mediaCollection->toArray()->willReturn([$media]);
     $normalizer->normalize([$media], 'csv', ['field_name' => 'media', 'prepare_copy' => true, 'identifier' => 'my_variant_group'])->willThrow(new FileNotFoundException('upload/path/img.jpg'));
     $this->shouldThrow(new InvalidItemException('The file "upload/path/img.jpg" does not exist', ['item' => 'my_variant_group', 'uploadDirectory' => 'upload/path/']))->duringProcess($variantGroup);
 }
 function it_returns_non_eligible_attributes($attributeRepository, GroupInterface $group, ProductTemplateInterface $template, AttributeInterface $length, AttributeInterface $name, AttributeInterface $color, AttributeInterface $identifier, Collection $collection)
 {
     $group->getProductTemplate()->willReturn($template);
     $group->getAxisAttributes()->willReturn($collection);
     $collection->toArray()->willReturn([$length]);
     $template->getValuesData()->willReturn(['name' => 'foo', 'color' => 'bar']);
     $attributeRepository->findOneByIdentifier('name')->willReturn($name);
     $attributeRepository->findOneByIdentifier('color')->willReturn($color);
     $attributeRepository->findBy(['unique' => true])->willReturn([$name, $identifier]);
     $attributes = [$length, $name, $color, $identifier];
     $this->getNonEligibleAttributes($group)->shouldReturn($attributes);
 }
 /**
  * Fetch medias in local filesystem
  *
  * @param GroupInterface $variantGroup
  * @param string         $directory
  */
 protected function fetchMedia(GroupInterface $variantGroup, $directory)
 {
     if (null === ($productTemplate = $variantGroup->getProductTemplate())) {
         return;
     }
     $identifier = $variantGroup->getCode();
     $this->variantGroupUpdater->update($variantGroup, ['values' => $productTemplate->getValuesData()]);
     $this->mediaFetcher->fetchAll($productTemplate->getValues(), $directory, $identifier);
     foreach ($this->mediaFetcher->getErrors() as $error) {
         $this->stepExecution->addWarning($error['message'], [], new DataInvalidItem($error['media']));
     }
 }
 /**
  * Validate variant group product template values
  *
  * @param GroupInterface $variantGroup
  * @param Constraint     $constraint
  */
 protected function validateProductTemplateValues(GroupInterface $variantGroup, Constraint $constraint)
 {
     $template = $variantGroup->getProductTemplate();
     $valuesData = $template->getValuesData();
     $forbiddenAttrCodes = $this->attributeRepository->findUniqueAttributeCodes();
     foreach ($variantGroup->getAxisAttributes() as $axisAttribute) {
         $forbiddenAttrCodes[] = $axisAttribute->getCode();
     }
     $invalidAttrCodes = array_intersect($forbiddenAttrCodes, array_keys($valuesData));
     if (count($invalidAttrCodes) > 0) {
         $this->context->buildViolation($constraint->message, ['%group%' => $variantGroup->getCode(), '%attributes%' => $this->formatValues($invalidAttrCodes)])->addViolation();
     }
 }
 function it_does_not_copy_values_to_products_when_template_is_empty(GroupInterface $variantGroup, ProductTemplateInterface $productTemplate, Collection $productCollection, ProductInterface $productOne, ProductInterface $productTwo, $productTplApplier, $stepExecution)
 {
     $variantGroup->getId()->willReturn(42);
     $stepExecution->incrementSummaryInfo('process')->shouldBeCalled();
     $variantGroup->getProductTemplate()->willReturn($productTemplate);
     $productTemplate->getValuesData()->willReturn([]);
     $variantGroup->getProducts()->willReturn($productCollection);
     $productCollection->isEmpty()->willReturn(false);
     $productCollection->toArray()->willReturn([$productOne, $productTwo]);
     $productCollection->count()->willReturn(2);
     $productTplApplier->apply($productTemplate, [$productOne, $productTwo])->shouldNotBeCalled();
     $this->write([$variantGroup]);
 }
 function it_handles_media_values_of_variant_group_product_templates($optionsResolver, $templateMediaManager, $eventDispatcher, GroupInterface $group, GroupType $type, ProductTemplateInterface $template)
 {
     $optionsResolver->resolveSaveOptions(Argument::any())->willReturn(['flush' => true, 'copy_values_to_products' => false]);
     $group->getProducts()->willReturn(new ArrayCollection([]));
     $group->getType()->willReturn($type);
     $group->getCode()->willReturn('my_code');
     $group->getId()->willReturn(null);
     $group->getProductTemplate()->willReturn($template);
     $type->isVariant()->willReturn(true);
     $templateMediaManager->handleProductTemplateMedia($template)->shouldBeCalled();
     $eventDispatcher->dispatch(StorageEvents::PRE_SAVE, Argument::cetera())->shouldBeCalled();
     $eventDispatcher->dispatch(StorageEvents::POST_SAVE, Argument::cetera())->shouldBeCalled();
     $this->save($group);
 }
 /**
  * Get non eligible attributes to a product template
  *
  * @param GroupInterface $variantGroup
  *
  * @return AttributeInterface[]
  */
 public function getNonEligibleAttributes(GroupInterface $variantGroup)
 {
     $attributes = $variantGroup->getAxisAttributes()->toArray();
     $template = $variantGroup->getProductTemplate();
     if (null !== $template) {
         foreach (array_keys($template->getValuesData()) as $attributeCode) {
             $attributes[] = $this->attributeRepository->findOneByIdentifier($attributeCode);
         }
     }
     $uniqueAttributes = $this->attributeRepository->findBy(['unique' => true]);
     foreach ($uniqueAttributes as $attribute) {
         if (!in_array($attribute, $attributes)) {
             $attributes[] = $attribute;
         }
     }
     return $attributes;
 }
 function it_adds_a_violation_if_variant_group_template_contains_a_unique_attribute(GroupInterface $variantGroup, GroupType $type, ProductTemplateInterface $template, VariantGroupValues $constraint, $attributeRepository, $context, ConstraintViolationBuilderInterface $violation)
 {
     $variantGroup->getType()->willReturn($type);
     $variantGroup->getCode()->willReturn('tshirt');
     $type->isVariant()->willReturn(true);
     $variantGroup->getProductTemplate()->willReturn($template);
     $variantGroup->getAxisAttributes()->willReturn([]);
     $attributeRepository->findUniqueAttributeCodes()->willReturn(['sku', 'barcode']);
     $template->getValuesData()->willReturn(['sku' => 'SKU-001']);
     $violationData = ['%group%' => 'tshirt', '%attributes%' => '"sku"'];
     $context->buildViolation($constraint->message, $violationData)->shouldBeCalled()->willReturn($violation);
     $this->validate($variantGroup, $constraint);
     $template->getValuesData()->willReturn(['sku' => 'SKU-001', 'barcode' => 01122334455]);
     $violationData = ['%group%' => 'tshirt', '%attributes%' => '"sku", "barcode"'];
     $context->buildViolation($constraint->message, $violationData)->shouldBeCalled()->willReturn($violation);
     $this->validate($variantGroup, $constraint);
 }
 function it_normalizes_a_variant_group_with_its_values($transNormalizer, $valuesDenormalizer, $valuesNormalizer, GroupInterface $group, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate)
 {
     $groupType->getCode()->willReturn('VARIANT');
     $groupType->isVariant()->willReturn(true);
     $group->getCode()->willReturn('laser_sabers');
     $valuesData = ['name' => 'Light saber model', 'size' => '120'];
     $context = ['with_variant_group_values' => true];
     $format = 'csv';
     $productTemplate->getValuesData()->willReturn($valuesData);
     $valuesDenormalizer->denormalize($valuesData, Argument::any(), Argument::any())->willReturn('denormalized_values');
     $valuesNormalizer->normalize('denormalized_values', Argument::any(), Argument::any())->willReturn('normalized_values');
     $group->getProductTemplate()->willReturn($productTemplate);
     $group->getType()->willReturn($groupType);
     $attr->getCode()->willReturn('light_color');
     $group->getAxisAttributes()->willReturn([$attr]);
     $transNormalizer->normalize($group, $format, $context)->willReturn([]);
     $this->normalize($group, $format, $context)->shouldReturn(['code' => 'laser_sabers', 'type' => 'VARIANT', 'axis' => ['light_color'], 'values' => 'normalized_values']);
 }
 /**
  * Copy variant group values to products
  *
  * @param GroupInterface $variantGroup
  */
 protected function copyValuesToProducts(GroupInterface $variantGroup)
 {
     $template = $variantGroup->getProductTemplate();
     $products = $variantGroup->getProducts();
     if ($template && count($template->getValuesData()) > 0 && count($products) > 0) {
         $skippedMessages = $this->productTplApplier->apply($template, $products->toArray());
         $nbSkipped = count($skippedMessages);
         $nbUpdated = count($products) - $nbSkipped;
         $this->incrementUpdatedProductsCount($nbUpdated);
         if ($nbSkipped > 0) {
             $this->incrementSkippedProductsCount($nbSkipped, $skippedMessages);
         }
     }
 }
 /**
  * Prepares media files present in the product template of the variant group for export.
  * Returns an array of files to be copied from 'filePath' to 'exportPath'.
  *
  * @param GroupInterface $group
  *
  * @throws InvalidItemException If a media file is not found
  *
  * @return array
  */
 protected function prepareVariantGroupMedia(GroupInterface $group)
 {
     $mediaValues = $this->getProductTemplateMediaValues($group->getProductTemplate());
     if (count($mediaValues) < 1) {
         return [];
     }
     try {
         return $this->normalizer->normalize($mediaValues, $this->format, ['field_name' => 'media', 'prepare_copy' => true, 'identifier' => $group->getCode()]);
     } catch (FileNotFoundException $e) {
         throw new InvalidItemException($e->getMessage(), ['item' => $group->getCode(), 'uploadDirectory' => $this->uploadDirectory]);
     }
 }
 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);
 }
 /**
  * Normalize the variant group values
  *
  * @param GroupInterface $group
  * @param string         $format
  * @param array          $context
  *
  * @return array
  */
 protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context)
 {
     if (!$group->getType()->isVariant() || null === $group->getProductTemplate()) {
         return [];
     }
     $context["entity"] = "variant-group";
     // As variant group > product template > values data are not type hinted we cannot normalize them directly
     // so we first denormalize them into product values using the common format then normalize them
     // this allow to transform localization based values for example
     return $this->valuesNormalizer->normalize($this->valuesDenormalizer->denormalize($group->getProductTemplate()->getValuesData(), $format, $context), $format, $context);
 }
 /**
  * Convert localized values in template of a variant group
  *
  * @param GroupInterface $group
  */
 protected function convertLocalizedValues(GroupInterface $group)
 {
     $template = $group->getProductTemplate();
     if (null === $template) {
         return;
     }
     $options = ['locale' => $this->request->getLocale(), 'disable_grouping_separator' => true];
     $valuesData = $this->localizedConverter->convertLocalizedToDefaultValues($template->getValuesData(), $options);
     $template->setValuesData($valuesData);
 }
示例#19
0
 function it_has_attribute_in_a_variant_group_template(AttributeInterface $attribute, GroupInterface $group, GroupTypeInterface $groupType, ArrayCollection $groupAttributes, ProductTemplateInterface $template)
 {
     $groupType->isVariant()->willReturn(true);
     $groupAttributes->contains($attribute)->willReturn(false);
     $template->hasValueForAttribute($attribute)->shouldBeCalled()->willReturn(true);
     $group->getType()->willReturn($groupType);
     $group->getProductTemplate()->willReturn($template);
     $group->getAxisAttributes()->willReturn($groupAttributes);
     $group->addProduct($this)->willReturn($this);
     $this->addGroup($group);
     $this->hasAttributeInVariantGroup($attribute)->shouldReturn(true);
 }
 function it_throws_an_exception_if_media_of_variant_group_is_not_found($objectDetacher, $normalizer, $mediaFetcher, $stepExecution, $variantGroupUpdater, ArrayCollection $productValueCollection, FileInfoInterface $media1, FileInfoInterface $media2, GroupInterface $variantGroup, ProductTemplateInterface $productTemplate, ProductValueInterface $productValue1, ProductValueInterface $productValue2, JobParameters $jobParameters, JobExecution $jobExecution, JobInstance $jobInstance, ExecutionContext $executionContext)
 {
     $stepExecution->getJobParameters()->willReturn($jobParameters);
     $jobParameters->get('filePath')->willReturn('my/path/variant_group.csv');
     $jobParameters->has('with_media')->willReturn(true);
     $jobParameters->get('with_media')->willReturn(true);
     $variantGroup->getProductTemplate()->willReturn($productTemplate);
     $variantGroup->getCode()->willReturn('my_variant_group');
     $productValueCollection->toArray()->willReturn([$productValue1, $productValue2]);
     $productValue1->setMedia($media1);
     $productValue2->setMedia($media2);
     $stepExecution->getJobExecution()->willReturn($jobExecution);
     $jobExecution->getJobInstance()->willReturn($jobInstance);
     $jobExecution->getId()->willReturn(100);
     $jobInstance->getCode()->willReturn('csv_variant_group_export');
     $jobExecution->getExecutionContext()->willReturn($executionContext);
     $executionContext->get(JobInterface::WORKING_DIRECTORY_PARAMETER)->willReturn('/working/directory/');
     $values = ['picture' => ['locale' => null, 'scope' => null, 'data' => ['filePath' => 'path/not_found.jpg']]];
     $variantStandard = ['code' => 'my_variant_group', 'values' => $values];
     $normalizer->normalize($variantGroup, null, ['with_variant_group_values' => true, 'identifier' => 'my_variant_group'])->willReturn($variantStandard);
     $variantGroupUpdater->update($variantGroup, ['values' => $variantStandard['values']])->shouldBeCalled();
     $productTemplate->getValuesData()->willReturn($variantStandard['values']);
     $productTemplate->getValues()->willReturn($productValueCollection);
     $mediaFetcher->fetchAll($productValueCollection, '/working/directory/', 'my_variant_group')->shouldBeCalled();
     $mediaFetcher->getErrors()->willReturn([['message' => 'The media has not been found or is not currently available', 'media' => ['filePath' => 'path/not_found.jpg']]]);
     $stepExecution->addWarning('The media has not been found or is not currently available', [], new DataInvalidItem(['filePath' => 'path/not_found.jpg']))->shouldBeCalled();
     $this->process($variantGroup)->shouldReturn($variantStandard);
     $objectDetacher->detach($variantGroup)->shouldBeCalled();
 }
 function it_normalizes_a_variant_group_with_its_values_on_versioning_context($transNormalizer, $valuesDenormalizer, GroupInterface $group, CustomSerializer $serializer, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate, ProductValueInterface $productValue1)
 {
     $groupType->getCode()->willReturn('VARIANT');
     $groupType->isVariant()->willReturn(true);
     $group->getCode()->willReturn('lego');
     $valuesData = ['name' => 'Light saber model', 'size' => '120'];
     $context = ['versioning' => true];
     $format = 'csv';
     $productTemplate->getValuesData()->willReturn($valuesData);
     $valuesDenormalizer->denormalize($valuesData, 'ProductValue[]', 'json')->willReturn([$productValue1]);
     $newContext = array_merge($context, ['with_variant_group_values' => true]);
     $serializer->normalize($productValue1, $format, ['entity' => 'product'] + $newContext)->willReturn(['age' => '6+']);
     $group->getProductTemplate()->willReturn($productTemplate);
     $group->getType()->willReturn($groupType);
     $attr->getCode()->willReturn('model');
     $group->getAxisAttributes()->willReturn([$attr]);
     $transNormalizer->normalize($group, $format, $context)->willReturn([]);
     $this->setSerializer($serializer);
     $this->normalize($group, $format, $context)->shouldReturn(['code' => 'lego', 'type' => 'VARIANT', 'axis' => 'model', 'age' => '6+']);
 }
示例#22
0
 /**
  * Copy the variant group values on any products belonging in the variant group
  *
  * @param GroupInterface $group
  */
 protected function copyVariantGroupValues(GroupInterface $group)
 {
     $template = $group->getProductTemplate();
     $products = $group->getProducts()->toArray();
     $this->productTplApplier->apply($template, $products);
 }
 /**
  * @param GroupInterface $variantGroup
  *
  * @return \Pim\Component\Catalog\Model\ProductTemplateInterface
  */
 protected function getProductTemplate(GroupInterface $variantGroup)
 {
     if ($variantGroup->getProductTemplate()) {
         $template = $variantGroup->getProductTemplate();
     } else {
         $template = new $this->templateClass();
         $variantGroup->setProductTemplate($template);
     }
     return $template;
 }
 /**
  * Normalize the variant group values
  *
  * @param GroupInterface $group
  * @param string         $format
  * @param array          $context
  *
  * @return array
  */
 protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context)
 {
     $valuesData = [];
     if ($group->getType()->isVariant() && null !== $group->getProductTemplate()) {
         $template = $group->getProductTemplate();
         $valuesData = $template->getValuesData();
     }
     return $valuesData;
 }