/** * Validate variant group * * @param GroupInterface $variantGroup * @param Constraint $constraint */ protected function validateVariantGroup(GroupInterface $variantGroup, Constraint $constraint) { $existingCombinations = []; $products = $variantGroup->getProducts(); if (null === $products) { $products = $this->getMatchingProducts($variantGroup); } foreach ($products as $product) { $values = []; foreach ($variantGroup->getAxisAttributes() as $attribute) { $code = $attribute->getCode(); $option = $product->getValue($code) ? (string) $product->getValue($code)->getOption() : null; if (null === $option && !$attribute->isBackendTypeReferenceData()) { $this->addEmptyAxisViolation($constraint, $variantGroup->getLabel(), $product->getIdentifier()->getVarchar(), $attribute->getCode()); } $values[] = sprintf('%s: %s', $code, $option); } $combination = implode(', ', $values); if (in_array($combination, $existingCombinations)) { $this->addExistingCombinationViolation($constraint, $variantGroup->getLabel(), $combination); } else { $existingCombinations[] = $combination; } } }
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); }
function it_adds_violation_when_validating_group_containing_products_with_non_unique_combination_of_axis_attributes($context, GroupInterface $tShirtVariantGroup, GroupTypeInterface $tShirtGroupType, ProductInterface $redTShirtProduct, ProductInterface $redTShirtProduct2, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeProductValue, ProductValueInterface $colorProductValue, UniqueVariantAxis $uniqueVariantAxisConstraint, ConstraintViolationBuilderInterface $violation) { $tShirtGroupType->isVariant()->willReturn(true); $tShirtVariantGroup->getType()->willReturn($tShirtGroupType); $tShirtVariantGroup->getProducts()->willReturn([$redTShirtProduct, $redTShirtProduct2]); $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $sizeAttribute->getCode()->willReturn('size'); $colorAttribute->getCode()->willReturn('color'); $sizeProductValue->getOption()->willReturn('XL'); $colorProductValue->getOption()->willReturn('Red'); $redTShirtProduct->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct->getValue('color')->willReturn($colorProductValue); $redTShirtProduct2->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct2->getValue('color')->willReturn($colorProductValue); $tShirtVariantGroup->getLabel()->willReturn('Groupe TShirt'); $context->buildViolation('Group "%variant group%" already contains another product with values "%values%"', ['%variant group%' => 'Groupe TShirt', '%values%' => 'size: XL, color: Red'])->shouldBeCalled()->willReturn($violation); $this->validate($tShirtVariantGroup, $uniqueVariantAxisConstraint); }
function it_updates_a_group($groupTypeRepository, $attributeRepository, $pqbFactory, GroupInterface $group, GroupTypeInterface $type, GroupTranslation $translatable, AttributeInterface $attributeColor, AttributeInterface $attributeSize, ProductInterface $removedProduct, ProductInterface $addedProduct, ProductQueryBuilderInterface $pqb) { $groupTypeRepository->findOneByIdentifier('RELATED')->willReturn($type); $attributeRepository->findOneByIdentifier('color')->willReturn($attributeColor); $attributeRepository->findOneByIdentifier('size')->willReturn($attributeSize); $pqbFactory->create()->willReturn($pqb); $pqb->addFilter('id', 'IN', [2])->shouldBeCalled(); $pqb->execute()->willReturn([$addedProduct]); $group->getTranslation()->willReturn($translatable); $translatable->setLabel('T-shirt super beau')->shouldBeCalled(); $group->setCode('mycode')->shouldBeCalled(); $group->setLocale('fr_FR')->shouldBeCalled(); $group->setType($type)->shouldBeCalled(); $group->setAxisAttributes([$attributeColor, $attributeSize])->shouldBeCalled(); $group->getId()->willReturn(null); $group->removeProduct($removedProduct)->shouldBeCalled(); $group->addProduct($addedProduct)->shouldBeCalled(); $group->getProducts()->willReturn([$removedProduct]); $values = ['code' => 'mycode', 'type' => 'RELATED', 'labels' => ['fr_FR' => 'T-shirt super beau'], 'axis' => ['color', 'size'], 'products' => [2]]; $this->update($group, $values, []); }
function it_updates_an_empty_variant_group($groupTypeRepository, $productBuilder, $pqbFactory, GroupInterface $variantGroup, GroupTypeInterface $type, ProductInterface $product, ProductTemplateInterface $productTemplate) { $groupTypeRepository->findOneByIdentifier('VARIANT')->willReturn($type); $pqbFactory->create()->shouldNotBeCalled(); $variantGroup->setCode('mycode')->shouldBeCalled(); $variantGroup->setType($type)->shouldBeCalled(); $variantGroup->setProductTemplate($productTemplate)->shouldBeCalled(); $variantGroup->getId()->willReturn(null); $variantGroup->getProducts()->willReturn([]); $variantGroup->getProductTemplate()->willReturn($productTemplate); $productTemplate->getValuesData()->willReturn([]); $productTemplate->setValues(Argument::any())->shouldBeCalled(); $productTemplate->setValuesData([])->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' => [], 'type' => 'VARIANT', 'labels' => [], 'values' => [], 'products' => []]; $this->update($variantGroup, $values, []); }
/** * @param GroupInterface $group * @param array $labels */ protected function setProducts(GroupInterface $group, array $productIds) { foreach ($group->getProducts() as $product) { $group->removeProduct($product); } if (empty($productIds)) { return; } $pqb = $this->productQueryBuilderFactory->create(); $pqb->addFilter('id', 'IN', $productIds); $products = $pqb->execute(); foreach ($products as $product) { $group->addProduct($product); } }
/** * 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); }
/** * 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); } } }
/** * Save associated products updated by the variant group update * * @param GroupInterface $group */ protected function saveAssociatedProducts(GroupInterface $group) { $productInGroup = $group->getProducts(); $productsToUpdate = $productInGroup->toArray(); $productToUpdateIds = array_map(function ($product) { return $product->getId(); }, $productsToUpdate); if (null !== $group->getId()) { $pqb = $this->productQueryBuilderFactory->create(); $pqb->addFilter('groups.id', Operators::IN_LIST, [$group->getId()]); $oldProducts = $pqb->execute(); foreach ($oldProducts as $oldProduct) { if (!in_array($oldProduct->getId(), $productToUpdateIds)) { $oldProduct->removeGroup($group); $productsToUpdate[] = $oldProduct; $productToUpdateIds[] = $oldProduct->getId(); } } } if (!empty($productsToUpdate)) { $this->productSaver->saveAll($productsToUpdate); } }
function it_marks_products_as_updated_when_a_group_is_removed_or_updated(EntityManager $em, ProductInterface $foo, ProductInterface $bar, GroupInterface $group) { $group->getProducts()->willReturn([$foo, $bar]); $this->guessUpdates($em, $group, UpdateGuesserInterface::ACTION_UPDATE_ENTITY)->shouldReturn([$foo, $bar]); $this->guessUpdates($em, $group, UpdateGuesserInterface::ACTION_DELETE)->shouldReturn([$foo, $bar]); }