/** * Normalize the attributes * * @param GroupInterface $group * * @return array */ protected function normalizeAxisAttributes(GroupInterface $group) { $attributes = array(); foreach ($group->getAxisAttributes() as $attribute) { $attributes[] = $attribute->getCode(); } sort($attributes); return $attributes; }
/** * @param VariantGroupAxis $constraint * @param GroupInterface $variantGroup */ protected function validateAttributeAxis(VariantGroupAxis $constraint, GroupInterface $variantGroup) { $allowedTypes = [AttributeTypes::OPTION_SIMPLE_SELECT, AttributeTypes::REFERENCE_DATA_SIMPLE_SELECT]; foreach ($variantGroup->getAxisAttributes() as $attribute) { if (!in_array($attribute->getAttributeType(), $allowedTypes)) { $this->addInvalidAxisViolation($constraint, $variantGroup->getCode(), $attribute->getCode()); } } }
function it_throws_an_error_if_axis_is_updated(GroupInterface $variantGroup) { $variantGroup->setCode('mycode')->shouldBeCalled(); $variantGroup->getId()->willReturn(42); $attribute = new Attribute(); $attribute->setCode('other'); $variantGroup->getAxisAttributes()->willReturn(new ArrayCollection([$attribute])); $values = ['code' => 'mycode', 'axis' => ['main_color']]; $this->shouldThrow(new \InvalidArgumentException('Attributes: This property cannot be changed.'))->during('update', [$variantGroup, $values, []]); }
/** * Get missing axis codes of a product given a variant group * * @param ProductInterface $product * @param GroupInterface $variantGroup * * @return array */ protected function getMissingAxisCodes(ProductInterface $product, GroupInterface $variantGroup) { $missingAxisCodes = []; foreach ($variantGroup->getAxisAttributes() as $attribute) { $value = $product->getValue($attribute->getCode()); if (null === $value || null === $value->getData()) { $missingAxisCodes[] = $attribute->getCode(); } } return $missingAxisCodes; }
function it_adds_a_violation_if_a_group_contains_axis_attributes($context, GroupInterface $group, GroupType $type, VariantGroupAxis $constraint, AttributeInterface $axis) { $group->getId()->willReturn(null); $group->getType()->willReturn($type); $group->getCode()->willReturn('xsell'); $type->isVariant()->willReturn(false); $group->getAxisAttributes()->willReturn([$axis]); $violationData = ['%group%' => 'xsell']; $context->addViolation($constraint->unexpectedAxisMessage, $violationData)->shouldBeCalled(); $this->validate($group, $constraint); }
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); }
function it_adds_a_violation_if_axis_attributes_are_invalid($context, GroupInterface $variantGroup, GroupType $type, VariantGroupAxis $constraint, ConstraintViolationBuilderInterface $violation, AttributeInterface $invalidAxis) { $variantGroup->getId()->willReturn(12); $variantGroup->getType()->willReturn($type); $variantGroup->getCode()->willReturn('tshirt'); $type->isVariant()->willReturn(true); $variantGroup->getAxisAttributes()->willReturn([$invalidAxis]); $invalidAxis->getAttributeType()->willReturn(AttributeTypes::TEXT); $invalidAxis->getCode()->willReturn('name'); $violationData = ['%group%' => 'tshirt', '%attribute%' => 'name']; $context->buildViolation($constraint->invalidAxisMessage, $violationData)->shouldBeCalled()->willReturn($violation); $this->validate($variantGroup, $constraint); }
/** * 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->addViolation($constraint->message, array('%group%' => $variantGroup->getCode(), '%attributes%' => $this->formatValues($invalidAttrCodes))); } }
function it_adds_a_violation_when_validates_a_product_with_missing_value_for_an_axe_of_its_variant_group($context, ProductInterface $product, GroupInterface $tShirtVariantGroup, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeValue, ProductValueInterface $identifierValue, HasVariantAxes $constraint, ConstraintViolationBuilderInterface $violation) { $tShirtVariantGroup->getCode()->willReturn('tshirt'); $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $sizeAttribute->getCode()->willReturn('size'); $colorAttribute->getCode()->willReturn('color'); $product->getIdentifier()->willReturn($identifierValue); $product->getVariantGroup()->willReturn($tShirtVariantGroup); $product->getValue('size')->willReturn($sizeValue); $product->getValue('color')->willReturn(null); $sizeValue->getData()->willReturn('XL'); $context->buildViolation('The product "%product%" is in the variant group "%variant%" but it misses the following axes: %axes%.', ['%product%' => $identifierValue, '%variant%' => 'tshirt', '%axes%' => 'color'])->shouldBeCalled()->willReturn($violation); $this->validate($product, $constraint); }
function it_adds_a_violation_if_variant_group_template_contains_a_unique_attribute(GroupInterface $variantGroup, GroupType $type, ProductTemplateInterface $template, VariantGroupValues $constraint, $attributeRepository, $context) { $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->addViolation($constraint->message, $violationData)->shouldBeCalled(); $this->validate($variantGroup, $constraint); $template->getValuesData()->willReturn(['sku' => 'SKU-001', 'barcode' => 01122334455]); $violationData = ['%group%' => 'tshirt', '%attributes%' => '"sku", "barcode"']; $context->addViolation($constraint->message, $violationData)->shouldBeCalled(); $this->validate($variantGroup, $constraint); }
/** * Get non eligible attributes to a product template * * @param GroupInterface $group * * @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; }
/** * @param GroupInterface $variantGroup * @param array $axes * * @throws \InvalidArgumentException */ protected function setAxes(GroupInterface $variantGroup, array $axes) { if (null !== $variantGroup->getId()) { if (array_diff($this->getOriginalAxes($variantGroup->getAxisAttributes()), array_values($axes))) { throw new \InvalidArgumentException('Attributes: This property cannot be changed.'); } } foreach ($axes as $axis) { $attribute = $this->attributeRepository->findOneByIdentifier($axis); if (null !== $attribute) { $variantGroup->addAxisAttribute($attribute); } else { throw new \InvalidArgumentException(sprintf('Attribute "%s" does not exist', $axis)); } } }
/** * @param GroupInterface $variantGroup * * @return array */ protected function getAxisAttributeCodes($variantGroup) { $axisAttributes = $variantGroup->getAxisAttributes(); $axisAttributeCodes = []; foreach ($axisAttributes as $axisAttribute) { $axisAttributeCodes[] = $axisAttribute->getCode(); } return $axisAttributeCodes; }
/** * Prepare query criteria for variant group * * @param GroupInterface $variantGroup * @param ProductInterface $product * @param Constraint $constraint * * @return array */ protected function prepareQueryCriterias(GroupInterface $variantGroup, ProductInterface $product, Constraint $constraint) { $criteria = array(); foreach ($variantGroup->getAxisAttributes() as $attribute) { $value = $product->getValue($attribute->getCode()); // we don't add criteria when option is null, as this check is performed by HasVariantAxesValidator if (null !== $value && null !== $value->getOption()) { $criteria[] = ['attribute' => $attribute, 'option' => $value->getOption()]; } else { $this->addEmptyAxisViolation($constraint, $variantGroup->getLabel(), $product->getIdentifier()->getVarchar(), $attribute->getCode()); } } return $criteria; }
function it_is_not_attribute_removable_with_group_containing_attribute(AttributeInterface $attribute, GroupInterface $group, GroupTypeInterface $groupType, ArrayCollection $groupAttributes) { $groupType->isVariant()->willReturn(true); $groupAttributes->contains($attribute)->willReturn(true); $group->getType()->willReturn($groupType); $group->getAxisAttributes()->willReturn($groupAttributes); $group->addProduct($this)->willReturn($this); $this->addGroup($group); $this->isAttributeRemovable($attribute)->shouldReturn(false); }
function it_adds_a_violation_when_validating_product_in_groups_with_non_unique_combination_of_axis_attributes($context, $productRepository, GroupInterface $tShirtVariantGroup, GroupTypeInterface $tShirtGroupType, GroupInterface $clothesVariantGroup, GroupTypeInterface $clothesGroupType, ProductInterface $redTShirtProduct, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeProductValue, ProductValueInterface $colorProductValue, ProductInterface $redTShirtProduct2, UniqueVariantAxis $uniqueVariantAxisConstraint) { $redTShirtProduct->getGroups()->willReturn([$tShirtVariantGroup, $clothesVariantGroup]); $tShirtVariantGroup->getId()->willReturn(1); $tShirtVariantGroup->getLabel()->willReturn('TShirts'); $tShirtVariantGroup->getType()->willReturn($tShirtGroupType); $tShirtGroupType->isVariant()->willReturn(true); $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $clothesVariantGroup->getId()->willReturn(2); $clothesVariantGroup->getLabel()->willReturn('Clothes'); $clothesVariantGroup->getType()->willReturn($clothesGroupType); $clothesGroupType->isVariant()->willReturn(true); $clothesVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $sizeAttribute->getCode()->willReturn('size'); $colorAttribute->getCode()->willReturn('color'); $redTShirtProduct->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct->getValue('color')->willReturn($colorProductValue); $redTShirtProduct->getId()->willReturn(1); $sizeProductValue->getOption()->willReturn('XL'); $colorProductValue->getOption()->willReturn('Red'); $redTShirtProduct2->getGroups()->willReturn([$clothesVariantGroup]); $redTShirtProduct2->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct2->getValue('color')->willReturn($colorProductValue); $redTShirtProduct2->getId()->willReturn(2); $criteria = [['attribute' => $sizeAttribute, 'option' => 'XL'], ['attribute' => $colorAttribute, 'option' => 'Red']]; $productRepository->findAllForVariantGroup($tShirtVariantGroup, $criteria)->willReturn([]); $productRepository->findAllForVariantGroup($clothesVariantGroup, $criteria)->willReturn([$redTShirtProduct2]); $context->addViolation('Group "%variant group%" already contains another product with values "%values%"', ['%variant group%' => 'Clothes', '%values%' => 'size: XL, color: Red'])->shouldBeCalled(); $this->validate($redTShirtProduct, $uniqueVariantAxisConstraint); }
/** * Prepare query criteria for variant group * * @param GroupInterface $variantGroup * @param ProductInterface $product * * @return array */ protected function prepareQueryCriterias(GroupInterface $variantGroup, ProductInterface $product) { $criteria = array(); foreach ($variantGroup->getAxisAttributes() as $attribute) { $value = $product->getValue($attribute->getCode()); // we don't add criteria when option is null, as this check is performed by HasVariantAxesValidator if (null !== $value && null !== $value->getOption()) { $criteria[] = ['attribute' => $attribute, 'option' => $value->getOption()]; } } return $criteria; }
/** * Prepare query criteria for variant group * * @param GroupInterface $variantGroup * @param ProductInterface $product * @param Constraint $constraint * * @return array */ protected function prepareQueryCriterias(GroupInterface $variantGroup, ProductInterface $product, Constraint $constraint) { $criteria = []; foreach ($variantGroup->getAxisAttributes() as $attribute) { $value = $product->getValue($attribute->getCode()); // we don't add criteria when option is null, as this check is performed by HasVariantAxesValidator if (null === $value || null === $value->getOption() && !$attribute->isBackendTypeReferenceData()) { $this->addEmptyAxisViolation($constraint, $variantGroup->getLabel(), $product->getIdentifier()->getVarchar(), $attribute->getCode()); continue; } $current = ['attribute' => $attribute]; if (null !== $value->getOption()) { $current['option'] = $value->getOption(); } elseif ($attribute->isBackendTypeReferenceData()) { $current['referenceData'] = ['name' => $attribute->getReferenceDataName(), 'data' => $value->getData()]; } $criteria[] = $current; } return $criteria; }
function it_does_not_add_violation_when_validating_product_in_groups_with_unique_combination_of_axis_attributes($context, $productRepository, GroupInterface $tShirtVariantGroup, GroupTypeInterface $tShirtGroupType, ProductInterface $redTShirtProduct, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeProductValue, ProductValueInterface $redColorProductValue, UniqueVariantAxis $uniqueVariantAxisConstraint) { $tShirtVariantGroup->getId()->willReturn(1); $tShirtVariantGroup->getLabel()->willReturn('TShirts'); $tShirtVariantGroup->getType()->willReturn($tShirtGroupType); $tShirtGroupType->isVariant()->willReturn(true); $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $sizeAttribute->getCode()->willReturn('size'); $sizeAttribute->isBackendTypeReferenceData()->willReturn(false); $colorAttribute->getCode()->willReturn('color'); $colorAttribute->isBackendTypeReferenceData()->willReturn(false); $redTShirtProduct->getVariantGroup()->willReturn($tShirtVariantGroup); $redTShirtProduct->getId()->willReturn(1); $redTShirtProduct->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct->getValue('color')->willReturn($redColorProductValue); $sizeProductValue->getOption()->willReturn('XL'); $redColorProductValue->getOption()->willReturn('Red'); $criteria = [['attribute' => $sizeAttribute, 'option' => 'XL'], ['attribute' => $colorAttribute, 'option' => 'Red']]; $productRepository->findAllForVariantGroup($tShirtVariantGroup, $criteria)->willReturn([]); $context->buildViolation()->shouldNotBeCalled(Argument::cetera()); $this->validate($redTShirtProduct, $uniqueVariantAxisConstraint); }