/**
  * {@inheritdoc}
  */
 public function addAttributeFilter(AttributeInterface $attribute, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     try {
         $options = $this->resolver->resolve($options);
     } catch (\Exception $e) {
         throw InvalidArgumentException::expectedFromPreviousException($e, $attribute->getCode(), 'filter', 'options');
     }
     $this->checkLocaleAndScope($attribute, $locale, $scope, 'options');
     if (Operators::IS_EMPTY !== $operator && Operators::IS_NOT_EMPTY !== $operator) {
         $this->checkValue($options['field'], $value);
     }
     $joinAlias = $this->getUniqueAlias('filter' . $attribute->getCode());
     $joinAliasOpt = $this->getUniqueAlias('filterO' . $attribute->getCode());
     $backendField = sprintf('%s.%s', $joinAliasOpt, 'id');
     if (Operators::IS_EMPTY === $operator || Operators::IS_NOT_EMPTY === $operator) {
         $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope));
         $this->qb->leftJoin($joinAlias . '.' . $attribute->getBackendType(), $joinAliasOpt)->andWhere($this->prepareCriteriaCondition($backendField, $operator, null));
     } else {
         if (FieldFilterHelper::getProperty($options['field']) === FieldFilterHelper::CODE_PROPERTY) {
             $value = $this->objectIdResolver->getIdsFromCodes('option', $value, $attribute);
         }
         $this->qb->innerJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope))->innerJoin($joinAlias . '.' . $attribute->getBackendType(), $joinAliasOpt, 'WITH', $this->prepareCriteriaCondition($backendField, $operator, $value));
         if (Operators::NOT_IN_LIST === $operator) {
             $this->qb->andWhere($this->qb->expr()->notIn($this->qb->getRootAlias() . '.id', $this->getNotInSubquery($attribute, $locale, $scope, $value)));
         }
     }
     return $this;
 }
 function it_throws_an_error_if_an_option_code_is_unknown_on_attribute_data_set($attrOptionRepository, ProductInterface $product, AttributeInterface $attribute)
 {
     $attribute->getCode()->willReturn('attributeCode');
     $data = ['unknown code'];
     $attrOptionRepository->findOneByIdentifier('attributeCode.unknown code')->shouldBeCalledTimes(1)->willReturn(null);
     $this->shouldThrow(InvalidArgumentException::arrayInvalidKey('attributeCode', 'code', 'The option does not exist', 'setter', 'multi select', 'unknown code'))->during('setAttributeData', [$product, $attribute, $data, ['locale' => 'fr_FR', 'scope' => 'mobile']]);
 }
 function it_throws_an_error_if_attribute_data_value_does_not_contain_valid_currency($currencyManager, AttributeInterface $attribute, ProductInterface $product)
 {
     $attribute->getCode()->willReturn('attributeCode');
     $currencyManager->getActiveCodes()->willReturn(['EUR', 'USD']);
     $data = [['data' => 123, 'currency' => 'invalid currency']];
     $this->shouldThrow(InvalidArgumentException::arrayInvalidKey('attributeCode', 'currency', 'The currency does not exist', 'remover', 'prices collection', 'invalid currency'))->during('removeAttributeData', [$product, $attribute, $data, ['locale' => 'fr_FR', 'scope' => 'mobile']]);
 }
 /**
  * {@inheritdoc}
  */
 public function addAttributeFilter(AttributeInterface $attribute, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     try {
         $options = $this->resolver->resolve($options);
     } catch (\Exception $e) {
         throw InvalidArgumentException::expectedFromPreviousException($e, $attribute->getCode(), 'filter', 'option');
     }
     $this->checkLocaleAndScope($attribute, $locale, $scope, 'option');
     $field = $options['field'];
     if (Operators::IS_EMPTY !== $operator) {
         $this->checkValue($field, $value);
     }
     $joinAlias = $this->getUniqueAlias('filter' . $attribute->getCode(), true);
     // prepare join value condition
     $optionAlias = $joinAlias . '.option';
     if (Operators::IS_EMPTY === $operator) {
         $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope));
         $this->qb->andWhere($this->qb->expr()->isNull($optionAlias));
     } else {
         // inner join to value
         $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope);
         if (FieldFilterHelper::getProperty($field) === FieldFilterHelper::CODE_PROPERTY) {
             $value = $this->objectIdResolver->getIdsFromCodes('option', $value, $attribute);
         }
         $condition .= ' AND ( ' . $this->qb->expr()->in($optionAlias, $value) . ' ) ';
         $this->qb->innerJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition);
     }
     return $this;
 }
 function it_fails_if_the_group_code_is_not_found($groupRepository, ProductInterface $product, GroupInterface $pack, GroupTypeInterface $nonVariantType)
 {
     $groupRepository->findOneByIdentifier('not valid code')->willReturn(null);
     $pack->getType()->willReturn($nonVariantType);
     $nonVariantType->isVariant()->willReturn(false);
     $this->shouldThrow(InvalidArgumentException::expected('variant_group', 'existing variant group code', 'setter', 'variant_group', 'not valid code'))->during('setFieldData', [$product, 'variant_group', 'not valid code']);
 }
 function it_fails_if_one_of_the_associated_group_does_not_exist($productBuilder, $groupRepository, ProductInterface $product, AssociationInterface $xsellAssociation)
 {
     $product->getAssociations()->willReturn([$xsellAssociation]);
     $productBuilder->addMissingAssociations($product)->shouldBeCalled();
     $product->getAssociationForTypeCode('xsell')->willReturn($xsellAssociation);
     $groupRepository->findOneByIdentifier('not existing group')->willReturn(null);
     $this->shouldThrow(InvalidArgumentException::expected('associations', 'existing group code', 'adder', 'association', 'not existing group'))->during('addFieldData', [$product, 'associations', ['xsell' => ['groups' => ['not existing group'], 'products' => []]]]);
 }
 /**
  * Check locale and scope are valid
  *
  * @param AttributeInterface $attribute
  * @param string             $locale
  * @param string             $scope
  * @param string             $type
  *
  * @throws InvalidArgumentException
  */
 protected function checkLocaleAndScope(AttributeInterface $attribute, $locale, $scope, $type)
 {
     try {
         $this->attrValidatorHelper->validateLocale($attribute, $locale);
         $this->attrValidatorHelper->validateScope($attribute, $scope);
     } catch (\LogicException $e) {
         throw InvalidArgumentException::expectedFromPreviousException($e, $attribute->getCode(), 'setter', $type);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function addFieldFilter($field, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     if (!is_bool($value)) {
         throw InvalidArgumentException::booleanExpected($field, 'filter', 'boolean', gettype($value));
     }
     $field = sprintf('%s.%s', ProductQueryUtility::NORMALIZED_FIELD, $field);
     $this->applyFilter($field, $operator, $value);
     return $this;
 }
 /**
  * Check if value is valid
  *
  * @param string      $field
  * @param mixed       $value
  * @param string|null $locale
  * @param string|null $scope
  */
 protected function checkValue($field, $value, $locale, $scope)
 {
     if (!is_numeric($value)) {
         throw InvalidArgumentException::numericExpected($field, 'filter', 'completeness', gettype($value));
     }
     if (null === $locale || null === $scope) {
         throw InvalidArgumentException::localeAndScopeExpected($field, 'filter', 'completeness');
     }
 }
 /**
  * Check if data is valid
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  */
 protected function checkData(AttributeInterface $attribute, $data)
 {
     if (null === $data) {
         return;
     }
     if (!is_string($data)) {
         throw InvalidArgumentException::stringExpected($attribute->getCode(), 'setter', 'reference data', gettype($data));
     }
 }
 /**
  * {@inheritdoc}
  */
 public function addFieldFilter($field, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     if (!is_numeric($value) && !is_array($value)) {
         throw InvalidArgumentException::expected($field, 'array or numeric value', 'filter', 'productId', $value);
     }
     $field = current($this->qb->getRootAliases()) . '.' . $field;
     $condition = $this->prepareCriteriaCondition($field, $operator, $value);
     $this->qb->andWhere($condition);
     return $this;
 }
 function it_fails_if_the_group_code_does_not_correspond_to_a_simple_group($groupRepository, ProductInterface $product, GroupInterface $pack, GroupInterface $variant, GroupTypeInterface $nonVariantType, GroupTypeInterface $variantType)
 {
     $groupRepository->findOneByIdentifier('pack')->willReturn($pack);
     $pack->getType()->willReturn($nonVariantType);
     $nonVariantType->isVariant()->willReturn(false);
     $groupRepository->findOneByIdentifier('variant')->willReturn($variant);
     $variant->getType()->willReturn($variantType);
     $variantType->isVariant()->willReturn(true);
     $this->shouldThrow(InvalidArgumentException::expected('groups', 'non variant group code', 'remover', 'groups', 'variant'))->during('removeFieldData', [$product, 'groups', ['pack', 'variant']]);
 }
 /**
  * {@inheritdoc}
  */
 public function addFieldFilter($field, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     if (!is_bool($value)) {
         throw InvalidArgumentException::booleanExpected($field, 'filter', 'boolean', gettype($value));
     }
     $field = current($this->qb->getRootAliases()) . '.' . FieldFilterHelper::getCode($field);
     $condition = $this->prepareCriteriaCondition($field, $operator, $value);
     $this->qb->andWhere($condition);
     return $this;
 }
 /**
  * {@inheritdoc}
  */
 public function addFieldFilter($field, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     if (!is_string($value) && !is_array($value)) {
         throw InvalidArgumentException::expected($field, 'array or string value', 'filter', 'productId', $value);
     }
     $field = '_id';
     $value = is_array($value) ? $value : [$value];
     $this->applyFilter($value, $field, $operator);
     return $this;
 }
 function it_throws_an_exception_when_scope_is_expected_but_not_existing($attrValidatorHelper, AttributeInterface $attribute)
 {
     $e = new \LogicException('Attribute "attributeCode" expects an existing scope, "ecommerce" given.');
     $attribute->getCode()->willReturn('attributeCode');
     $attribute->isLocalizable()->willReturn(false);
     $attribute->isScopable()->willReturn(true);
     $attrValidatorHelper->validateLocale($attribute, null)->shouldBeCalled();
     $attrValidatorHelper->validateScope($attribute, 'ecommerce')->willThrow($e);
     $this->shouldThrow(InvalidArgumentException::expectedFromPreviousException($e, 'attributeCode', 'copier', 'concrete'))->during('testLocaleAndScope', [$attribute, null, 'ecommerce']);
 }
 /**
  * Check if data are valid
  *
  * @param string $field
  * @param mixed  $data
  */
 protected function checkData($field, $data)
 {
     if (!is_array($data)) {
         throw InvalidArgumentException::arrayExpected($field, 'adder', 'groups', gettype($data));
     }
     foreach ($data as $key => $value) {
         if (!is_string($value)) {
             throw InvalidArgumentException::arrayStringValueExpected($field, $key, 'adder', 'groups', gettype($value));
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function addAttributeFilter(AttributeInterface $attribute, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     $this->checkLocaleAndScope($attribute, $locale, $scope, 'number');
     if (!is_numeric($value) && null !== $value) {
         throw InvalidArgumentException::numericExpected($attribute->getCode(), 'filter', 'number', gettype($value));
     }
     $field = ProductQueryUtility::getNormalizedValueFieldFromAttribute($attribute, $locale, $scope);
     $field = sprintf('%s.%s', ProductQueryUtility::NORMALIZED_FIELD, $field);
     $this->applyFilter($operator, $value, $field);
     return $this;
 }
 /**
  * Check if data is valid
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  */
 protected function checkData(AttributeInterface $attribute, $data)
 {
     if (!is_array($data)) {
         throw InvalidArgumentException::arrayExpected($attribute->getCode(), 'remover', 'multi select', gettype($data));
     }
     foreach ($data as $key => $value) {
         if (!is_string($value)) {
             throw InvalidArgumentException::arrayStringValueExpected($attribute->getCode(), $key, 'remover', 'multi select', gettype($value));
         }
     }
 }
 function it_throws_an_exception_if_reference_data_does_not_exist($attrValidatorHelper, $repositoryResolver, ObjectRepository $repository, ProductInterface $product, AttributeInterface $attribute)
 {
     $attribute->getReferenceDataName()->willReturn('customMaterials');
     $attribute->getCode()->willReturn('lace_fabric');
     $attrValidatorHelper->validateLocale(Argument::cetera())->shouldBeCalled();
     $attrValidatorHelper->validateScope(Argument::cetera())->shouldBeCalled();
     $repositoryResolver->resolve('customMaterials')->willReturn($repository);
     $repository->findOneBy(['code' => 'hulk_retriever'])->willReturn(null);
     $exception = InvalidArgumentException::validEntityCodeExpected('lace_fabric', 'code', 'No reference data "customMaterials" with code "hulk_retriever" has been found', 'setter', 'reference data', 'hulk_retriever');
     $this->shouldThrow($exception)->during('setAttributeData', [$product, $attribute, 'hulk_retriever', ['locale' => 'fr_FR', 'scope' => 'mobile']]);
 }
 /**
  * Check if data is valid
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  */
 protected function checkData(AttributeInterface $attribute, $data)
 {
     if (!is_array($data)) {
         throw InvalidArgumentException::arrayExpected($attribute->getCode(), 'setter', 'metric', gettype($data));
     }
     if (!array_key_exists('data', $data)) {
         throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'data', 'setter', 'metric', print_r($data, true));
     }
     if (!array_key_exists('unit', $data)) {
         throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'unit', 'setter', 'metric', print_r($data, true));
     }
 }
 /**
  * Check if value is a valid identifier
  *
  * @param string $field
  * @param mixed  $value
  * @param string $filter
  */
 public static function checkIdentifier($field, $value, $filter)
 {
     $invalidIdField = static::hasProperty($field) && static::getProperty($field) === 'id' && !is_numeric($value);
     $invalidDefaultField = !static::hasProperty($field) && !is_numeric($value);
     if ($invalidIdField || $invalidDefaultField) {
         throw InvalidArgumentException::numericExpected(static::getCode($field), 'filter', $filter, gettype($value));
     }
     $invalidStringField = static::hasProperty($field) && static::getProperty($field) !== 'id' && !is_string($value);
     if ($invalidStringField) {
         throw InvalidArgumentException::stringExpected(static::getCode($field), 'filter', $filter, gettype($value));
     }
 }
 /**
  * Check if data are valid
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  *
  * @return mixed
  */
 protected function checkData(AttributeInterface $attribute, $data)
 {
     if (!is_array($data)) {
         throw InvalidArgumentException::arrayExpected($attribute->getCode(), 'setter', 'prices collection', gettype($data));
     }
     foreach ($data as $price) {
         if (!is_array($price)) {
             throw InvalidArgumentException::arrayOfArraysExpected($attribute->getCode(), 'setter', 'prices collection', gettype($data));
         }
         if (!array_key_exists('data', $price)) {
             throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'data', 'setter', 'prices collection', print_r($data, true));
         }
         if (!array_key_exists('currency', $price)) {
             throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'currency', 'setter', 'prices collection', print_r($data, true));
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 public function addAttributeFilter(AttributeInterface $attribute, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     $this->checkLocaleAndScope($attribute, $locale, $scope, 'number');
     if (!is_numeric($value) && null !== $value) {
         throw InvalidArgumentException::numericExpected($attribute->getCode(), 'filter', 'number', gettype($value));
     }
     $joinAlias = $this->getUniqueAlias('filter' . $attribute->getCode());
     $backendField = sprintf('%s.%s', $joinAlias, $attribute->getBackendType());
     if ($operator === Operators::IS_EMPTY) {
         $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope));
         $this->qb->andWhere($this->prepareCriteriaCondition($backendField, $operator, $value));
     } else {
         $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias, $locale, $scope);
         $condition .= ' AND ' . $this->prepareCriteriaCondition($backendField, $operator, $value);
         $this->qb->innerJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition);
     }
     return $this;
 }
 /**
  * {@inheritdoc}
  */
 public function addAttributeFilter(AttributeInterface $attribute, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     try {
         $options = $this->resolver->resolve($options);
     } catch (\Exception $e) {
         throw InvalidArgumentException::expectedFromPreviousException($e, $attribute->getCode(), 'filter', 'option');
     }
     $this->checkLocaleAndScope($attribute, $locale, $scope, 'option');
     if (Operators::IS_EMPTY !== $operator) {
         $this->checkValue($options['field'], $value);
         if (FieldFilterHelper::getProperty($options['field']) === FieldFilterHelper::CODE_PROPERTY) {
             $value = $this->objectIdResolver->getIdsFromCodes('option', $value, $attribute);
         }
     }
     $mongoField = sprintf('%s.%s.id', ProductQueryUtility::NORMALIZED_FIELD, ProductQueryUtility::getNormalizedValueFieldFromAttribute($attribute, $locale, $scope));
     $this->applyFilter($operator, $value, $mongoField, $options);
     return $this;
 }
 /**
  * Check if data are valid
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  *
  * @return mixed
  */
 protected function checkData(AttributeInterface $attribute, $data)
 {
     if (!is_array($data)) {
         throw InvalidArgumentException::arrayExpected($attribute->getCode(), 'adder', 'prices collection', gettype($data));
     }
     foreach ($data as $price) {
         if (!is_array($price)) {
             throw InvalidArgumentException::arrayOfArraysExpected($attribute->getCode(), 'adder', 'prices collection', gettype($data));
         }
         if (!array_key_exists('data', $price)) {
             throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'data', 'adder', 'prices collection', print_r($data, true));
         }
         if (!array_key_exists('currency', $price)) {
             throw InvalidArgumentException::arrayKeyExpected($attribute->getCode(), 'currency', 'adder', 'prices collection', print_r($data, true));
         }
         if (!is_numeric($price['data']) && null !== $price['data']) {
             throw InvalidArgumentException::arrayNumericKeyExpected($attribute->getCode(), 'data', 'adder', 'prices collection', gettype($price['data']));
         }
         if (!in_array($price['currency'], $this->currencyRepository->getActivatedCurrencyCodes())) {
             throw InvalidArgumentException::arrayInvalidKey($attribute->getCode(), 'currency', 'The currency does not exist', 'adder', 'prices collection', $price['currency']);
         }
     }
 }
 function it_throws_an_exception_if_value_had_not_a_valid_currency($currencyRepository, AttributeInterface $attribute)
 {
     $currencyRepository->getActivatedCurrencyCodes()->willReturn(['EUR', 'USD']);
     $attribute->getCode()->willReturn('price_code');
     $value = ['data' => 132, 'currency' => 'FOO'];
     $this->shouldThrow(InvalidArgumentException::arrayInvalidKey('price_code', 'currency', 'The currency does not exist', 'filter', 'price', 'FOO'))->during('addAttributeFilter', [$attribute, '=', $value]);
 }
 function it_throws_an_exception_if_value_had_not_a_valid_unit($measureManager, AttributeInterface $attribute)
 {
     $attribute->getMetricFamily()->willReturn('length');
     $measureManager->getUnitSymbolsForFamily('length')->willReturn(['CENTIMETER' => 'cm', 'METER' => 'm', 'KILOMETER' => 'km']);
     $attribute->getCode()->willReturn('metric_code');
     $value = ['data' => 132, 'unit' => 'foo'];
     $this->shouldThrow(InvalidArgumentException::arrayInvalidKey('metric_code', 'unit', 'The unit does not exist in the attribute\'s family "length"', 'filter', 'metric', 'foo'))->during('addAttributeFilter', [$attribute, '=', $value]);
 }
 function it_throws_an_exception_if_value_is_not_a_valid_array(AttributeInterface $attribute)
 {
     $attribute->getId()->willReturn(1);
     $attribute->getCode()->willReturn('color');
     $value = 'string';
     $this->shouldThrow(InvalidArgumentException::arrayExpected('color', 'filter', 'reference_data', $value))->during('addAttributeFilter', [$attribute, '=', $value, null, null, ['field' => 'color']]);
     $value = ['foo'];
     $this->shouldThrow(InvalidArgumentException::numericExpected('color', 'filter', 'reference_data', 'string'))->during('addAttributeFilter', [$attribute, '=', $value, null, null, ['field' => 'color']]);
 }
 function it_throws_an_exception_if_value_is_an_array_but_does_not_contain_two_values()
 {
     $this->shouldThrow(InvalidArgumentException::expected('release_date', 'array with 2 elements, string or \\Datetime', 'filter', 'date', print_r([123, 123, 'three'], true)))->during('addFieldFilter', ['release_date', '>', [123, 123, 'three']]);
 }
 /**
  * TODO: inform the user that this could take some time
  *
  * @param AttributeInterface $attribute
  * @param mixed              $data
  *
  * @throws InvalidArgumentException If an invalid filePath is provided
  *
  * @return FileInfoInterface|null
  */
 protected function storeFile(AttributeInterface $attribute, $data)
 {
     if (null === $data || null === $data['filePath'] && null === $data['originalFilename']) {
         return null;
     }
     try {
         $rawFile = new UploadedFile($data['filePath'], $data['originalFilename']);
         $file = $this->storer->store($rawFile, FileStorage::CATALOG_STORAGE_ALIAS);
     } catch (FileNotFoundException $e) {
         throw InvalidArgumentException::expected($attribute->getCode(), 'a valid pathname', 'setter', 'media', $data['filePath']);
     }
     return $file;
 }