Пример #1
0
 /**
  * Sets the attribute
  *
  * @param AttributeInterface $attribute
  *
  * @throws ColumnLabelException
  */
 public function setAttribute(AttributeInterface $attribute = null)
 {
     $this->attribute = $attribute;
     if (null === $attribute) {
         $this->locale = null;
         $this->scope = null;
         $this->suffixes = $this->rawSuffixes;
         $this->propertyPath = lcfirst(Inflector::classify($this->name));
     } else {
         if (!in_array($attribute->getBackendType(), [AbstractAttributeType::BACKEND_TYPE_REF_DATA_OPTION, AbstractAttributeType::BACKEND_TYPE_REF_DATA_OPTIONS])) {
             $this->propertyPath = $attribute->getBackendType();
         } else {
             $this->propertyPath = $attribute->getReferenceDataName();
         }
         $suffixes = $this->rawSuffixes;
         if ($attribute->isLocalizable()) {
             if (count($suffixes)) {
                 $this->locale = array_shift($suffixes);
             } else {
                 throw new ColumnLabelException('The column "%column%" must contain a locale code', ['%column%' => $this->label]);
             }
         }
         if ($attribute->isScopable()) {
             if (count($suffixes)) {
                 $this->scope = array_shift($suffixes);
             } else {
                 throw new ColumnLabelException('The column "%column%" must contain a scope code', ['%column%' => $this->label]);
             }
         }
         $this->suffixes = $suffixes;
     }
 }
 function it_denormalizes_data_into_reference_data($resolver, AttributeInterface $attribute, ReferenceDataInterface $battlecruiser, ReferenceDataRepository $referenceDataRepo)
 {
     $attribute->getReferenceDataName()->willReturn('starship');
     $resolver->resolve('starship')->willReturn($referenceDataRepo);
     $referenceDataRepo->findOneBy(['code' => 'battlecruiser'])->willReturn($battlecruiser);
     $this->denormalize('battlecruiser', 'pim_reference_data_simpleselect', 'json', ['attribute' => $attribute])->shouldReturn($battlecruiser);
 }
 function let(TranslationNormalizer $transnormalizer, AttributeInterface $attribute, AttributeGroupInterface $attributeGroup)
 {
     $this->beConstructedWith($transnormalizer);
     $transnormalizer->normalize(Argument::cetera())->willReturn([]);
     $attribute->getAttributeType()->willReturn('Yes/No');
     $attribute->getCode()->willReturn('attribute_size');
     $attribute->getGroup()->willReturn($attributeGroup);
     $attributeGroup->getCode()->willReturn('size');
     $attribute->isUnique()->willReturn(true);
     $attribute->isUseableAsGridFilter()->willReturn(false);
     $attribute->getAllowedExtensions()->willReturn(['csv', 'xml', 'json']);
     $attribute->getMetricFamily()->willReturn('Length');
     $attribute->getDefaultMetricUnit()->willReturn('Centimenter');
     $attribute->getReferenceDataName()->willReturn('color');
     $attribute->isLocalizable()->willReturn(true);
     $attribute->isScopable()->willReturn(false);
     $attribute->getLocaleSpecificCodes()->willReturn(['en_US', 'fr_FR']);
     $attribute->getMaxCharacters()->willReturn(null);
     $attribute->getValidationRule()->willReturn(null);
     $attribute->getValidationRegexp()->willReturn(null);
     $attribute->isWysiwygEnabled()->willReturn(false);
     $attribute->getNumberMin()->willReturn('');
     $attribute->getNumberMax()->willReturn('');
     $attribute->isDecimalsAllowed()->willReturn(false);
     $attribute->isNegativeAllowed()->willReturn(false);
     $attribute->getDateMin()->willReturn(null);
     $attribute->getDateMax()->willReturn(null);
     $attribute->getMaxFileSize()->willReturn(null);
     $attribute->getMinimumInputLength()->willReturn(null);
     $attribute->getSortOrder()->willReturn(0);
 }
 function it_normalizes_attribute($transNormalizer, $dateTimeNormalizer, AttributeInterface $attribute, AttributeGroupInterface $attributeGroup)
 {
     $transNormalizer->normalize(Argument::cetera())->willReturn([]);
     $dateMin = new \DateTime('2015-05-23 15:55:50');
     $dateMax = new \DateTime('2015-06-23 15:55:50');
     $attribute->getAttributeType()->willReturn('Yes/No');
     $attribute->getCode()->willReturn('attribute_size');
     $attribute->getGroup()->willReturn($attributeGroup);
     $attributeGroup->getCode()->willReturn('size');
     $attribute->isUnique()->willReturn(true);
     $attribute->isUseableAsGridFilter()->willReturn(true);
     $attribute->getAllowedExtensions()->willReturn(['csv', 'xml', 'json']);
     $attribute->getMetricFamily()->willReturn('Length');
     $attribute->getDefaultMetricUnit()->willReturn('Centimenter');
     $attribute->getReferenceDataName()->willReturn('color');
     $attribute->isLocalizable()->willReturn(true);
     $attribute->isScopable()->willReturn(true);
     $attribute->getLocaleSpecificCodes()->willReturn(['en_US', 'fr_FR']);
     $attribute->getMaxCharacters()->willReturn(255);
     $attribute->getValidationRule()->willReturn('email');
     $attribute->getValidationRegexp()->willReturn('[0-9]*');
     $attribute->isWysiwygEnabled()->willReturn(true);
     $attribute->getNumberMin()->willReturn('0.55');
     $attribute->getNumberMax()->willReturn('1500.55');
     $attribute->isDecimalsAllowed()->willReturn(true);
     $attribute->isNegativeAllowed()->willReturn(true);
     $attribute->getDateMin()->willReturn($dateMin);
     $attribute->getDateMax()->willReturn($dateMax);
     $attribute->getMaxFileSize()->willReturn(1024);
     $attribute->getMinimumInputLength()->willReturn(2);
     $attribute->getSortOrder()->willReturn(4);
     $dateTimeNormalizer->normalize($dateMin)->willReturn('2015-05-23T15:55:50+01:00');
     $dateTimeNormalizer->normalize($dateMax)->willReturn('2015-06-23T15:55:50+01:00');
     $this->normalize($attribute)->shouldReturn(['code' => 'attribute_size', 'type' => 'Yes/No', 'group' => 'size', 'unique' => true, 'useable_as_grid_filter' => true, 'allowed_extensions' => ['csv', 'xml', 'json'], 'metric_family' => 'Length', 'default_metric_unit' => 'Centimenter', 'reference_data_name' => 'color', 'available_locales' => ['en_US', 'fr_FR'], 'max_characters' => 255, 'validation_rule' => 'email', 'validation_regexp' => '[0-9]*', 'wysiwyg_enabled' => true, 'number_min' => '0.55', 'number_max' => '1500.55', 'decimals_allowed' => true, 'negative_allowed' => true, 'date_min' => '2015-05-23T15:55:50+01:00', 'date_max' => '2015-06-23T15:55:50+01:00', 'max_file_size' => '1024', 'minimum_input_length' => 2, 'sort_order' => 4, 'localizable' => true, 'scopable' => true, 'labels' => []]);
 }
 /**
  * @param AttributeInterface $attribute
  *
  * @return array
  */
 protected function getChoiceUrlParams(AttributeInterface $attribute)
 {
     $referenceDataName = $attribute->getReferenceDataName();
     $referenceData = $this->registry->get($referenceDataName);
     if (null === $referenceData) {
         throw new \InvalidArgumentException(sprintf('Reference data "%s" does not exist', $referenceDataName));
     }
     return ['class' => $referenceData->getClass(), 'dataLocale' => $this->userContext->getCurrentLocaleCode(), 'collectionId' => $attribute->getId()];
 }
 /**
  * {@inheritdoc}
  */
 public function addData($data)
 {
     $backendType = $this->attribute->getBackendType();
     if ($this->attribute->isBackendTypeReferenceData()) {
         $backendType = $this->attribute->getReferenceDataName();
     }
     if (substr($backendType, -1, 1) === 's') {
         $backendType = substr($backendType, 0, strlen($backendType) - 1);
     }
     $name = 'add' . ucfirst($backendType);
     return $this->{$name}($data);
 }
 function it_normalizes_a_product_value_into_mongodb_document($mongoFactory, $serializer, ProductValueInterface $value, AttributeInterface $attribute, \MongoDBRef $mongoDBRef, \MongoId $mongoId)
 {
     $context = ['_id' => $mongoId, 'collection_name' => 'product', 'database_name' => 'my_db'];
     $mongoFactory->createMongoId()->willReturn($mongoId);
     $mongoFactory->createMongoDBRef('product', $mongoId, 'my_db')->willReturn($mongoDBRef);
     $attribute->getId()->willReturn(123);
     $attribute->getBackendType()->willReturn('text');
     $attribute->getReferenceDataName()->willReturn(null);
     $value->getAttribute()->willReturn($attribute);
     $value->getData()->willReturn('my description');
     $value->getLocale()->willReturn(null);
     $value->getScope()->willReturn(null);
     $this->normalize($value, 'mongodb_document', $context)->shouldReturn(['_id' => $mongoId, 'attribute' => 123, 'entity' => $mongoDBRef, 'text' => 'my description']);
 }
 function it_has_a_property_path(AttributeInterface $attribute)
 {
     $this->beConstructedWith('foo_name-en_US-ecommerce');
     $this->getPropertyPath()->shouldReturn('fooName');
     $this->setPropertyPath('newName');
     $this->getPropertyPath()->shouldReturn('newName');
     $attribute->isLocalizable()->willReturn(true);
     $attribute->isScopable()->willReturn(true);
     $attribute->getBackendType()->willReturn(AbstractAttributeType::BACKEND_TYPE_REF_DATA_OPTION);
     $attribute->getReferenceDataName()->willReturn('ref_name');
     $this->setAttribute($attribute);
     $this->getPropertyPath()->shouldReturn('ref_name');
     $attribute->getBackendType()->willReturn(AbstractAttributeType::BACKEND_TYPE_BOOLEAN);
     $this->setAttribute($attribute);
     $this->getPropertyPath()->shouldReturn(AbstractAttributeType::BACKEND_TYPE_BOOLEAN);
 }
 function let(TranslationNormalizer $transnormalizer, AttributeInterface $attribute, AttributeGroupInterface $attributeGroup)
 {
     $this->beConstructedWith($transnormalizer);
     $transnormalizer->normalize(Argument::cetera())->willReturn([]);
     $attribute->getAttributeType()->willReturn('Yes/No');
     $attribute->getCode()->willReturn('attribute_size');
     $attribute->getGroup()->willReturn($attributeGroup);
     $attributeGroup->getCode()->willReturn('size');
     $attribute->isUnique()->willReturn(true);
     $attribute->isUseableAsGridFilter()->willReturn(false);
     $attribute->getAllowedExtensions()->willReturn(['csv', 'xml', 'json']);
     $attribute->getMetricFamily()->willReturn('Length');
     $attribute->getDefaultMetricUnit()->willReturn('Centimenter');
     $attribute->getReferenceDataName()->willReturn('color');
     $attribute->isLocalizable()->willReturn(true);
     $attribute->isScopable()->willReturn(false);
 }
 function it_sets_reference_data_collection_to_a_product_value($builder, $attrValidatorHelper, $repositoryResolver, ObjectRepository $repository, ReferenceDataInterface $refData1, ReferenceDataInterface $refData2, AttributeInterface $attribute, ProductInterface $product1, ProductInterface $product2, ProductInterface $product3, AnotherCustomProductValue $productValue1, AnotherCustomProductValue $productValue2, AnotherCustomProductValue $productValue3)
 {
     $locale = 'fr_FR';
     $scope = 'mobile';
     $collection = new ArrayCollection();
     $collection->add($refData1);
     $collection->add($refData2);
     $attrValidatorHelper->validateLocale(Argument::cetera())->shouldBeCalled();
     $attrValidatorHelper->validateScope(Argument::cetera())->shouldBeCalled();
     $attribute->getCode()->willReturn('custom_material');
     $attribute->getReferenceDataName()->willReturn('customMaterials');
     $repositoryResolver->resolve('customMaterials')->willReturn($repository);
     $repository->findOneBy(['code' => 'shiny_metal'])->willReturn($refData1);
     $repository->findOneBy(['code' => 'cold_metal'])->willReturn($refData2);
     $product1->getValue('custom_material', $locale, $scope)->willReturn(null);
     $product2->getValue('custom_material', $locale, $scope)->willReturn($productValue2);
     $product3->getValue('custom_material', $locale, $scope)->willReturn($productValue3);
     $builder->addProductValue($product1, $attribute, $locale, $scope)->shouldBeCalled()->willReturn($productValue1);
     $products = [$product1, $product2, $product3];
     $existantCollection = new ArrayCollection();
     $existantCollection->add($refData1);
     $existantCollection2 = new ArrayCollection();
     $existantCollection2->add($refData1);
     $existantCollection2->add($refData2);
     $productValue1->getCustomMaterials()->willReturn(new ArrayCollection());
     $productValue2->getCustomMaterials()->willReturn($existantCollection);
     $productValue3->getCustomMaterials()->willReturn($existantCollection2);
     $productValue1->addCustomMaterial($refData1)->shouldBeCalled();
     $productValue1->addCustomMaterial($refData2)->shouldBeCalled();
     $productValue2->addCustomMaterial($refData1)->shouldBeCalled();
     $productValue2->addCustomMaterial($refData2)->shouldBeCalled();
     $productValue3->addCustomMaterial($refData1)->shouldBeCalled();
     $productValue3->addCustomMaterial($refData2)->shouldBeCalled();
     $productValue2->removeCustomMaterial($refData1)->shouldBeCalled();
     $productValue3->removeCustomMaterial($refData1)->shouldBeCalled();
     $productValue3->removeCustomMaterial($refData2)->shouldBeCalled();
     foreach ($products as $product) {
         $this->setAttributeData($product, $attribute, ['shiny_metal', 'cold_metal'], ['locale' => $locale, 'scope' => $scope]);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function supportsAttribute(AttributeInterface $attribute)
 {
     $referenceDataName = $attribute->getReferenceDataName();
     return null !== $referenceDataName && null !== $this->registry->get($referenceDataName) ? true : false;
 }
 /**
  * @param ProductValueInterface $value
  * @param AttributeInterface    $attribute
  * @param string                $type
  *
  * @return string
  */
 private function getValueMethodName(ProductValueInterface $value, AttributeInterface $attribute, $type)
 {
     $method = MethodNameGuesser::guess($type, $attribute->getReferenceDataName(), true);
     if (!method_exists($value, $method)) {
         throw new \LogicException(sprintf('ProductValue method "%s" is not implemented', $method));
     }
     return $method;
 }
 /**
  * @param AttributeInterface $attribute
  * @param string             $value
  *
  * @return int
  */
 protected function valueCodesToIds(AttributeInterface $attribute, $value)
 {
     try {
         $value = $this->idsResolver->resolve($attribute->getReferenceDataName(), $value);
     } catch (\LogicException $e) {
         throw InvalidArgumentException::validEntityCodeExpected($attribute->getCode(), 'code', $e->getMessage(), 'setter', 'reference data', implode(',', $value));
     }
     return $value;
 }
 function it_allows_setting_reference_data_to_null($builder, $attrValidatorHelper, AttributeInterface $attribute, ProductInterface $product1, ProductInterface $product2, CustomProductValue $productValue1, CustomProductValue $productValue2)
 {
     $locale = 'en_US';
     $scope = 'ecommerce';
     $attrValidatorHelper->validateLocale(Argument::cetera())->shouldBeCalled();
     $attrValidatorHelper->validateScope(Argument::cetera())->shouldBeCalled();
     $attribute->getCode()->willReturn('custom_material');
     $attribute->getReferenceDataName()->willReturn('customMaterials');
     $product1->getValue('custom_material', $locale, $scope)->willReturn(null);
     $product2->getValue('custom_material', $locale, $scope)->willReturn($productValue2);
     $builder->addProductValue($product1, $attribute, $locale, $scope)->shouldBeCalled()->willReturn($productValue1);
     $products = [$product1, $product2];
     $productValue1->setCustomMaterial(null)->shouldBeCalled();
     $productValue2->setCustomMaterial(null)->shouldBeCalled();
     foreach ($products as $product) {
         $this->setAttributeData($product, $attribute, null, ['locale' => $locale, 'scope' => $scope]);
     }
 }
 function it_adds_a_violation_when_validating_product_in_groups_with_non_unique_combination_of_axis_attributes($context, $productRepository, GroupInterface $tShirtVariantGroup, ProductInterface $redTShirtProduct, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeProductValue, ProductValueInterface $colorProductValue, ProductInterface $redTShirtProduct2, UniqueVariantAxis $uniqueVariantAxisConstraint, ConstraintViolationBuilderInterface $violation)
 {
     $redTShirtProduct->getVariantGroup()->willReturn($tShirtVariantGroup);
     $tShirtVariantGroup->getId()->willReturn(1);
     $tShirtVariantGroup->getLabel()->willReturn('TShirts');
     $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]);
     $sizeAttribute->getCode()->willReturn('size');
     $sizeAttribute->isBackendTypeReferenceData()->willReturn(true);
     $sizeAttribute->getReferenceDataName()->willReturn('ref_size');
     $colorAttribute->getCode()->willReturn('color');
     $colorAttribute->isBackendTypeReferenceData()->willReturn(true);
     $colorAttribute->getReferenceDataName()->willReturn('ref_color');
     $redTShirtProduct->getValue('size')->willReturn($sizeProductValue);
     $redTShirtProduct->getValue('color')->willReturn($colorProductValue);
     $redTShirtProduct->getId()->willReturn(1);
     $sizeProductValue->getData()->willReturn('XL');
     $sizeProductValue->getOption()->willReturn(null);
     $colorProductValue->getData()->willReturn('Red');
     $colorProductValue->getOption()->willReturn(null);
     $criteria = [['attribute' => $sizeAttribute, 'referenceData' => ['name' => 'ref_size', 'data' => 'XL']], ['attribute' => $colorAttribute, 'referenceData' => ['name' => 'ref_color', 'data' => 'Red']]];
     $productRepository->findAllForVariantGroup($tShirtVariantGroup, $criteria)->shouldBeCalled()->willReturn([$redTShirtProduct2]);
     $context->buildViolation('Group "%variant group%" already contains another product with values "%values%"', ['%variant group%' => 'TShirts', '%values%' => 'size: XL, color: Red'])->shouldBeCalled()->willReturn($violation);
     $this->validate($redTShirtProduct, $uniqueVariantAxisConstraint);
 }
 /**
  * {@inheritdoc}
  *
  * @param AttributeInterface $attribute
  */
 public function normalize($attribute, $format = null, array $context = [])
 {
     return ['code' => $attribute->getCode(), 'type' => $attribute->getAttributeType(), 'group' => $attribute->getGroup() ? $attribute->getGroup()->getCode() : null, 'unique' => (bool) $attribute->isUnique(), 'useable_as_grid_filter' => (bool) $attribute->isUseableAsGridFilter(), 'allowed_extensions' => $attribute->getAllowedExtensions(), 'metric_family' => '' === $attribute->getMetricFamily() ? null : $attribute->getMetricFamily(), 'default_metric_unit' => '' === $attribute->getDefaultMetricUnit() ? null : $attribute->getDefaultMetricUnit(), 'reference_data_name' => $attribute->getReferenceDataName(), 'available_locales' => $attribute->getLocaleSpecificCodes(), 'max_characters' => null === $attribute->getMaxCharacters() ? null : (int) $attribute->getMaxCharacters(), 'validation_rule' => '' === $attribute->getValidationRule() ? null : $attribute->getValidationRule(), 'validation_regexp' => '' === $attribute->getValidationRegexp() ? null : $attribute->getValidationRegexp(), 'wysiwyg_enabled' => (bool) $attribute->isWysiwygEnabled(), 'number_min' => null === $attribute->getNumberMin() ? null : (string) $attribute->getNumberMin(), 'number_max' => null === $attribute->getNumberMax() ? null : (string) $attribute->getNumberMax(), 'decimals_allowed' => (bool) $attribute->isDecimalsAllowed(), 'negative_allowed' => (bool) $attribute->isNegativeAllowed(), 'date_min' => $this->dateTimeNormalizer->normalize($attribute->getDateMin()), 'date_max' => $this->dateTimeNormalizer->normalize($attribute->getDateMax()), 'max_file_size' => null === $attribute->getMaxFileSize() ? null : (string) $attribute->getMaxFileSize(), 'minimum_input_length' => null === $attribute->getMinimumInputLength() ? null : (int) $attribute->getMinimumInputLength(), 'sort_order' => (int) $attribute->getSortOrder(), 'localizable' => (bool) $attribute->isLocalizable(), 'scopable' => (bool) $attribute->isScopable(), 'labels' => $this->translationNormalizer->normalize($attribute, $format, $context)];
 }
 /**
  * Decide what is the key used for data inside the normalized product value
  *
  * @param ProductValueInterface $value
  * @param AttributeInterface    $attribute
  * @param string                $backendType
  *
  * @return string
  */
 protected function getKeyForValue(ProductValueInterface $value, AttributeInterface $attribute, $backendType)
 {
     if ('options' === $backendType) {
         return 'optionIds';
     }
     $refDataName = $attribute->getReferenceDataName();
     if (null === $refDataName) {
         return $backendType;
     }
     if ('reference_data_options' === $backendType) {
         return $this->getReferenceDataFieldName($value, $refDataName);
     }
     return $refDataName;
 }
 function it_throws_error_when_adder_method_of_the_reference_data_is_not_implemented($attrValidatorHelper, AttributeInterface $fromAttribute, AttributeInterface $toAttribute, ProductInterface $fromProduct, ProductInterface $toProduct, CustomProductValueBis $fromProductValue)
 {
     $fromLocale = 'fr_FR';
     $toLocale = 'fr_FR';
     $toScope = 'mobile';
     $fromScope = 'mobile';
     $toProductValue = new InvalidAdderCustomProductValue();
     $fromAttribute->getCode()->willReturn('fromAttributeCode');
     $toAttribute->getCode()->willReturn('toAttributeCode');
     $fromAttribute->getReferenceDataName()->willReturn('colors');
     $toAttribute->getReferenceDataName()->willReturn('colors');
     $attrValidatorHelper->validateLocale(Argument::cetera())->shouldBeCalled();
     $attrValidatorHelper->validateScope(Argument::cetera())->shouldBeCalled();
     $fromProduct->getValue('fromAttributeCode', $fromLocale, $fromScope)->willReturn($fromProductValue);
     $fromProduct->getValue('toAttributeCode', $toLocale, $toScope)->willReturn($toProductValue);
     $toProduct->getValue('fromAttributeCode', $fromLocale, $fromScope)->willReturn($fromProductValue);
     $toProduct->getValue('toAttributeCode', $toLocale, $toScope)->willReturn($toProductValue);
     $this->shouldThrow(new \LogicException('ProductValue method "addColor" is not implemented'))->during('copyAttributeData', [$fromProduct, $toProduct, $fromAttribute, $toAttribute, ['from_locale' => $fromLocale, 'to_locale' => $toLocale, 'from_scope' => $fromScope, 'to_scope' => $toScope]]);
 }