/**
  * Test related method
  */
 public function testConstruct()
 {
     $this->assertEntity($this->attribute);
     $this->assertEmptyCollection($this->attribute->getOptions());
     $this->assertNull($this->attribute->getAvailableLocales());
     $this->assertEmptyCollection($this->attribute->getTranslations());
     $this->assertFalse($this->attribute->isRequired());
     $this->assertFalse($this->attribute->isUnique());
     $this->assertNull($this->attribute->getDefaultValue());
     $this->assertFalse($this->attribute->isLocalizable());
     $this->assertFalse($this->attribute->isScopable());
     $this->assertFalse($this->attribute->isUseableAsGridColumn());
     $this->assertFalse($this->attribute->isUseableAsGridFilter());
     $this->assertNull($this->attribute->isDecimalsAllowed());
     $this->assertNull($this->attribute->isNegativeAllowed());
 }
 function it_does_not_validate_attribute_with_non_string_options(AbstractAttribute $attribute, ExecutionContext $context, AttributeOption $option1, AttributeOption $option2, AttributeOption $option3, AttributeOption $option4)
 {
     $option1->getCode()->willReturn('ab');
     $option2->getCode()->willReturn(0);
     $option3->getCode()->willReturn('ef');
     $option4->getCode()->willReturn('gh');
     $attribute->getOptions()->willReturn([$option1, $option2, $option3, $option4]);
     $context->addViolation('Code must be a string. Type "integer" found.')->shouldBeCalled();
     $this->areOptionsValid($attribute, $context);
 }
 /**
  * Validation rule for attribute option values
  *
  * @param AbstractAttribute $attribute
  * @param ExecutionContext  $context
  */
 public static function areOptionsValid(AbstractAttribute $attribute, ExecutionContext $context)
 {
     $existingValues = array();
     foreach ($attribute->getOptions() as $option) {
         $code = $option->getCode();
         if (isset($existingValues[$code])) {
             $context->addViolation(self::VIOLATION_DUPLICATE_OPTION_CODE);
         } elseif ($code === null) {
             $context->addViolation(self::VIOLATION_OPTION_CODE_REQUIRED);
         } elseif (!is_string($code)) {
             $context->addViolation(self::VIOLATION_NON_STRING_CODE . sprintf(' Type "%s" found.', gettype($code)));
         } else {
             $existingValues[$code] = '';
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function normalizeOptions(AbstractAttribute $attribute)
 {
     $options = $attribute->getOptions();
     if ($options->isEmpty()) {
         $options = '';
     } else {
         $data = array();
         foreach ($options as $option) {
             $item = array();
             foreach ($option->getOptionValues() as $value) {
                 $label = str_replace('{locale}', $value->getLocale(), self::LOCALIZABLE_PATTERN);
                 $label = str_replace('{value}', $value->getValue(), $label);
                 $item[] = $label;
             }
             $data[] = 'Code:' . $option->getCode() . self::ITEM_SEPARATOR . implode(self::ITEM_SEPARATOR, $item);
         }
         $options = implode(self::GROUP_SEPARATOR, $data);
     }
     return $options;
 }
 /**
  * Get a random option from an attribute
  *
  * @param AbstractAttribute $attribute
  *
  * @return AttributeOption
  */
 protected function getRandomOptionFromAttribute(AbstractAttribute $attribute)
 {
     if (!isset($this->attributeOptions[$attribute->getCode()])) {
         $this->attributeOptions[$attribute->getCode()] = [];
         foreach ($attribute->getOptions() as $option) {
             $this->attributeOptions[$attribute->getCode()][] = $option;
         }
     }
     return $this->faker->randomElement($this->attributeOptions[$attribute->getCode()]);
 }
 /**
  * Call when form is valid
  * @param AbstractAttribute $entity
  * @param Collection        $oldOptions
  */
 protected function onSuccess(AbstractAttribute $entity, Collection $oldOptions)
 {
     foreach ($entity->getOptions() as $option) {
         // Setting translatable to true for now - option not implemented in UI
         $option->setTranslatable(true);
         // Validation not implemented yet - this should probably be checked there
         if (!$option->getSortOrder()) {
             $option->setSortOrder(1);
         }
         foreach ($option->getOptionValues() as $optionValue) {
             if (!$optionValue->getValue()) {
                 $option->removeOptionValue($optionValue);
             }
         }
     }
     // Manually remove if option is removed from entity
     foreach ($oldOptions as $oldOption) {
         if (false === $entity->getOptions()->contains($oldOption)) {
             $this->manager->remove($oldOption);
         }
     }
     $this->manager->persist($entity);
     $this->manager->flush();
 }
 /**
  * Normalize options
  *
  * @param AbstractAttribute $attribute
  *
  * @return array
  */
 protected function normalizeOptions(AbstractAttribute $attribute)
 {
     $data = array();
     $options = $attribute->getOptions();
     foreach ($options as $option) {
         $data[$option->getCode()] = array();
         foreach ($option->getOptionValues() as $value) {
             $data[$option->getCode()][$value->getLocale()] = $value->getValue();
         }
     }
     return $data;
 }
 /**
  * Get price mapping for an attribute.
  *
  * @param AbstractAttribute $attribute
  * @param int               $basePrice
  * @param array             $products
  * @param array             $priceChanges
  * @param MappingCollection $attributeMapping
  * @param boolean           $lowest
  *
  * @return array
  */
 protected function getAttributePriceMapping(AbstractAttribute $attribute, $basePrice, array $products, array $priceChanges, MappingCollection $attributeMapping, $lowest)
 {
     $attributePriceMapping = [];
     foreach ($attribute->getOptions() as $option) {
         $productsWithOption = $this->getProductsWithOption($products, $option);
         if (count($productsWithOption) > 0) {
             $priceDiff = $this->getLimitPrice($productsWithOption, $attributeMapping, $priceChanges, $lowest) - $basePrice;
             $attributePriceMapping[$option->getCode()] = $priceDiff;
         }
     }
     return $attributePriceMapping;
 }
 /**
  * Add attribute default options
  *
  * @param AbstractAttribute $attribute
  * @param array             $data
  */
 protected function addDefaultOptions(AbstractAttribute $attribute, $data)
 {
     $defaultOptions = array_filter(explode('|', $data['default_options']));
     foreach ($defaultOptions as $defaultOption) {
         $translations = explode(',', $defaultOption);
         foreach ($translations as $translation) {
             $translation = explode(':', $translation);
             $locale = reset($translation);
             $value = end($translation);
             $options = $attribute->getOptions();
             foreach ($options as $option) {
                 $optionValues = $option->getOptionValues();
                 foreach ($optionValues as $optionValue) {
                     if ($optionValue->getLocale() == $locale && $optionValue->getValue() == $value) {
                         $option->setDefault(true);
                         break;
                     }
                 }
             }
         }
     }
 }
 /**
  * Add attribute default options
  *
  * @param AbstractAttribute $attribute
  * @param array             $data
  */
 protected function addDefaultOptions(AbstractAttribute $attribute, $data)
 {
     $defaultOptions = array_keys($data['default_options']);
     foreach ($defaultOptions as $code) {
         $options = $attribute->getOptions();
         foreach ($options as $option) {
             if ($code == $option->getCode()) {
                 $option->setDefault(true);
             }
         }
     }
 }
 /**
  * Generate value content based on backend type
  *
  * @param AbstractAttribute $attribute
  * @param string            $key
  *
  * @return string
  */
 protected function generateValueData(AbstractAttribute $attribute, $key)
 {
     $data = "";
     if (isset($this->forcedValues[$attribute->getCode()])) {
         return $this->forcedValues[$attribute->getCode()];
     }
     switch ($attribute->getBackendType()) {
         case "varchar":
             $validationRule = $attribute->getValidationRule();
             switch ($validationRule) {
                 case 'url':
                     $data = $this->faker->url();
                     break;
                 default:
                     $data = $this->faker->sentence();
                     break;
             }
             break;
         case "text":
             $data = $this->faker->sentence();
             break;
         case "date":
             $data = $this->faker->dateTimeBetween($attribute->getDateMin(), $attribute->getDateMax());
             $data = $data->format('Y-m-d');
             break;
         case "metric":
         case "decimal":
         case "prices":
             if ($attribute->getBackendType() && preg_match('/-' . self::METRIC_UNIT . '$/', $key)) {
                 $data = $attribute->getDefaultMetricUnit();
             } else {
                 $min = $attribute->getNumberMin() != null ? $attribute->getNumberMin() : self::DEFAULT_NUMBER_MIN;
                 $max = $attribute->getNumberMax() != null ? $attribute->getNumberMax() : self::DEFAULT_NUMBER_MAX;
                 $decimals = $attribute->isDecimalsAllowed() ? self::DEFAULT_NB_DECIMALS : 0;
                 $data = $this->faker->randomFloat($decimals, $min, $max);
             }
             break;
         case "boolean":
             $data = $this->faker->boolean() ? "1" : "0";
             break;
         case "option":
         case "options":
             $options = [];
             foreach ($attribute->getOptions() as $option) {
                 $options[] = $option;
             }
             $option = $this->faker->randomElement($options);
             if (is_object($option)) {
                 $data = $option->getCode();
             }
             break;
         default:
             $data = '';
             break;
     }
     return (string) $data;
 }