/** * Sets the attribute * * @param AbstractAttribute $attribute * * @throws ColumnLabelException */ public function setAttribute(AbstractAttribute $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 { $this->propertyPath = $attribute->getBackendType(); $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', array('%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', array('%column%' => $this->label)); } } $this->suffixes = $suffixes; } }
/** * {@inheritdoc} */ public function addAttributeFilter(AbstractAttribute $attribute, $operator, $value) { $backendType = $attribute->getBackendType(); $joinAlias = 'filter' . $attribute->getCode() . $this->aliasCounter++; // join to value $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); if ('EMPTY' === $operator) { $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); // join to price $joinAliasPrice = 'filterP' . $attribute->getCode() . $this->aliasCounter; $priceData = $joinAlias . '.' . $backendType; $this->qb->leftJoin($priceData, $joinAliasPrice); // add conditions $condition = $this->preparePriceCondition($joinAliasPrice, $operator, $value); $exprNull = $this->qb->expr()->isNull($joinAliasPrice . '.id'); $exprOr = $this->qb->expr()->orX($condition, $exprNull); $this->qb->andWhere($exprOr); } else { $this->qb->innerJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); $joinAliasPrice = 'filterP' . $attribute->getCode() . $this->aliasCounter; $condition = $this->preparePriceCondition($joinAliasPrice, $operator, $value); $this->qb->innerJoin($joinAlias . '.' . $backendType, $joinAliasPrice, 'WITH', $condition); } return $this; }
/** * Add data * * @param mixed $data * * @return EntityAttributeValue */ public function addData($data) { $backendType = $this->attribute->getBackendType(); if (substr($backendType, -1, 1) === 's') { $backendType = substr($backendType, 0, strlen($backendType) - 1); } $name = 'add' . ucfirst($backendType); return $this->{$name}($data); }
function it_returns_attribute_informations_from_field_name_with_price_attribute($managerRegistry, AttributeRepository $repository, AbstractAttribute $attribute) { $attribute->getCode()->willReturn('foo'); $attribute->isLocalizable()->willReturn(false); $attribute->isScopable()->willReturn(false); $attribute->getBackendType()->willReturn('prices'); $repository->findByReference('foo')->willReturn($attribute); $managerRegistry->getRepository(self::ATTRIBUTE_CLASS)->willReturn($repository); $this->extractAttributeFieldNameInfos('foo-USD')->shouldReturn(['attribute' => $attribute, 'locale_code' => null, 'scope_code' => null, 'price_currency' => 'USD']); }
function it_normalizes_value_with_decimal_support_backend(ProductValueInterface $value, AbstractAttribute $attribute) { $attribute->getCode()->willReturn('code'); $attribute->getBackendType()->willReturn('decimal'); $attribute->isLocalizable()->willReturn(false); $attribute->isScopable()->willReturn(false); $value->getData()->willReturn('42.42'); $value->getAttribute()->willReturn($attribute); $this->normalize($value, 'mongodb_json', [])->shouldReturn(['code' => 42.42]); }
function it_normalizes_a_product_value_into_mongodb_document($mongoFactory, $serializer, AbstractProductValue $value, AbstractAttribute $attribute, \MongoDBRef $mongoDBRef, \MongoId $mongoId) { $context = ['_id' => $mongoId, 'collection_name' => 'product']; $mongoFactory->createMongoId()->willReturn($mongoId); $mongoFactory->createMongoDBRef('product', $mongoId)->willReturn($mongoDBRef); $attribute->getId()->willReturn(123); $attribute->getBackendType()->willReturn('text'); $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']); }
/** * {@inheritdoc} */ public function addAttributeSorter(AbstractAttribute $attribute, $direction) { $aliasPrefix = 'sorter'; $joinAlias = $aliasPrefix . 'V' . $attribute->getCode() . $this->aliasCounter++; $backendType = $attribute->getBackendType(); // join to value $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); $joinAliasMetric = $aliasPrefix . 'M' . $attribute->getCode() . $this->aliasCounter; $this->qb->leftJoin($joinAlias . '.' . $backendType, $joinAliasMetric); $this->qb->addOrderBy($joinAliasMetric . '.baseData', $direction); return $this; }
function it_adds_a_like_filter_in_the_query(QueryBuilder $queryBuilder, AbstractAttribute $sku) { $sku->getId()->willReturn(42); $sku->getCode()->willReturn('sku'); $sku->getBackendType()->willReturn('varchar'); $sku->isLocalizable()->willReturn(false); $sku->isScopable()->willReturn(false); $queryBuilder->expr()->willReturn(new Expr()); $queryBuilder->getRootAlias()->willReturn('p'); $condition = "filtersku1.attribute = 42 AND filtersku1.varchar LIKE 'My Sku'"; $queryBuilder->innerJoin('p.values', 'filtersku1', 'WITH', $condition)->shouldBeCalled(); $this->addAttributeFilter($sku, 'LIKE', 'My Sku'); }
/** * {@inheritdoc} */ public function addAttributeSorter(AbstractAttribute $attribute, $direction) { $aliasPrefix = 'sorter'; $joinAlias = $aliasPrefix . 'V' . $attribute->getCode() . $this->aliasCounter++; $backendType = $attribute->getBackendType(); // join to value $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); $this->qb->leftJoin($this->qb->getRootAlias() . '.' . $attribute->getBackendStorage(), $joinAlias, 'WITH', $condition); // then to option and option value to sort on $joinAliasOpt = $aliasPrefix . 'O' . $attribute->getCode() . $this->aliasCounter; $this->qb->leftJoin($joinAlias . '.' . $backendType, $joinAliasOpt); $this->qb->addOrderBy($joinAliasOpt . '.code', $direction); return $this; }
/** * {@inheritdoc} */ public function addAttributeFilter(AbstractAttribute $attribute, $operator, $value) { $joinAlias = 'filter' . $attribute->getCode() . $this->aliasCounter++; $backendField = sprintf('%s.%s', $joinAlias, $attribute->getBackendType()); if ($operator === 'EMPTY') { $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $this->prepareAttributeJoinCondition($attribute, $joinAlias)); $this->qb->andWhere($this->prepareCriteriaCondition($backendField, $operator, $value)); } else { $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); $condition .= ' AND ' . $this->prepareCriteriaCondition($backendField, $operator, $value); $this->qb->innerJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); } return $this; }
/** * {@inheritdoc} */ public function guessConstraints(AbstractAttribute $attribute) { $constraints = array(); if ($attribute->isRequired()) { $constraints[] = new Constraints\NotBlank(); } switch ($attribute->getBackendType()) { case AbstractAttributeType::BACKEND_TYPE_DATE: $constraints[] = new Constraints\Date(); break; case AbstractAttributeType::BACKEND_TYPE_DATETIME: $constraints[] = new Constraints\DateTime(); break; } return $constraints; }
function it_adds_a_sorter_in_the_query(QueryBuilder $queryBuilder, AbstractAttribute $sku) { $sku->getId()->willReturn(42); $sku->getCode()->willReturn('sku'); $sku->getBackendType()->willReturn('varchar'); $sku->isLocalizable()->willReturn(false); $sku->isScopable()->willReturn(false); $queryBuilder->expr()->willReturn(new Expr()); $queryBuilder->getRootAlias()->willReturn('p'); $queryBuilder->getDQLPart('join')->willReturn([]); $queryBuilder->resetDQLPart('join')->shouldBeCalled(); $condition = "sorterVsku1.attribute = 42"; $queryBuilder->leftJoin('p.values', 'sorterVsku1', 'WITH', $condition)->shouldBeCalled(); $queryBuilder->addOrderBy('sorterVsku1.varchar', 'DESC')->shouldBeCalled(); $this->addAttributeSorter($sku, 'DESC'); }
/** * {@inheritdoc} */ public function addAttributeSorter(AbstractAttribute $attribute, $direction) { $aliasPrefix = 'sorter'; $joinAlias = $aliasPrefix . 'V' . $attribute->getCode() . $this->aliasCounter++; $backendType = $attribute->getBackendType(); // join to value and sort on $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); // Remove current join in order to put the orderBy related join // at first place in the join queue for performances reasons $joinsSet = $this->qb->getDQLPart('join'); $this->qb->resetDQLPart('join'); $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); $this->qb->addOrderBy($joinAlias . '.' . $backendType, $direction); // Reapply previous join after the orderBy related join $this->applyJoins($joinsSet); return $this; }
/** * {@inheritdoc} */ public function addAttributeSorter(AbstractAttribute $attribute, $direction) { $aliasPrefix = 'sorter'; $joinAlias = $aliasPrefix . 'V' . $attribute->getCode() . $this->aliasCounter++; $backendType = $attribute->getBackendType(); // join to value $condition = $this->prepareAttributeJoinCondition($attribute, $joinAlias); $this->qb->leftJoin($this->qb->getRootAlias() . '.values', $joinAlias, 'WITH', $condition); // then to option and option value to sort on $joinAliasOpt = $aliasPrefix . 'O' . $attribute->getCode() . $this->aliasCounter; $condition = $joinAliasOpt . ".attribute = " . $attribute->getId(); $this->qb->leftJoin($joinAlias . '.' . $backendType, $joinAliasOpt, 'WITH', $condition); $joinAliasOptVal = $aliasPrefix . 'OV' . $attribute->getCode() . $this->aliasCounter; $condition = $joinAliasOptVal . '.locale = ' . $this->qb->expr()->literal($this->context->getLocaleCode()); $this->qb->leftJoin($joinAliasOpt . '.optionValues', $joinAliasOptVal, 'WITH', $condition); $this->qb->addOrderBy($joinAliasOpt . '.code', $direction); $this->qb->addOrderBy($joinAliasOptVal . '.value', $direction); return $this; }
/** * Extract informations from an attribute and exploded field name * This method is used from extractAttributeFieldNameInfos and can be redefine to add new rules * * @param AbstractAttribute $attribute * @param array $explodedFieldName * * @return array */ protected function extractAttributeInfos(AbstractAttribute $attribute, array $explodedFieldName) { if ($attribute->isLocalizable() && $attribute->isScopable()) { $localeCode = $explodedFieldName[1]; $scopeCode = $explodedFieldName[2]; $priceCurrency = $attribute->getBackendType() === 'prices' ? $explodedFieldName[3] : null; } elseif ($attribute->isLocalizable()) { $localeCode = $explodedFieldName[1]; $scopeCode = null; $priceCurrency = $attribute->getBackendType() === 'prices' ? $explodedFieldName[2] : null; } elseif ($attribute->isScopable()) { $localeCode = null; $scopeCode = $explodedFieldName[1]; $priceCurrency = $attribute->getBackendType() === 'prices' ? $explodedFieldName[2] : null; } else { $localeCode = null; $scopeCode = null; $priceCurrency = $attribute->getBackendType() === 'prices' ? $explodedFieldName[1] : null; } $priceArray = null === $priceCurrency ? [] : ['price_currency' => $priceCurrency]; return ['attribute' => $attribute, 'locale_code' => $localeCode, 'scope_code' => $scopeCode] + $priceArray; }
/** * {@inheritdoc} */ public function supportAttribute(AbstractAttribute $attribute) { $availableTypes = array(AbstractAttributeType::BACKEND_TYPE_VARCHAR, AbstractAttributeType::BACKEND_TYPE_DATE, AbstractAttributeType::BACKEND_TYPE_DATETIME, AbstractAttributeType::BACKEND_TYPE_DECIMAL, AbstractAttributeType::BACKEND_TYPE_INTEGER); return in_array($attribute->getBackendType(), $availableTypes); }
/** * 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; }
/** * 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()]; } if (preg_match('/-' . self::METRIC_UNIT . '$/', $key)) { return $attribute->getDefaultMetricUnit(); } switch ($attribute->getBackendType()) { case "varchar": $data = $this->generateVarcharData($attribute); break; case "text": $data = $this->generateTextData(); break; case "date": $data = $this->generateDateData($attribute); break; case "metric": case "decimal": case "prices": $data = $this->generateNumberData($attribute); break; case "boolean": $data = $this->generateBooleanData(); break; case "option": case "options": $data = $this->generateOptionData($attribute); break; default: $data = ''; break; } return (string) $data; }
function it_generates_attribute_indexes_when_saving_filterable_scopable_and_localizable_attribute($collection, $namingUtility, AbstractAttribute $description) { $description->getCode()->willReturn('description'); $description->getBackendType()->willReturn('varchar'); $description->isLocalizable()->willReturn(true); $description->isScopable()->willReturn(true); $description->isUseableAsGridFilter()->willReturn(true); $description->getAttributeType()->willReturn('pim_catalog_simpleselect'); $namingUtility->getAttributeNormFields($description)->willReturn(['normalizedData.description-en_US-ecommerce', 'normalizedData.description-de_DE-ecommerce', 'normalizedData.description-en_US-mobile']); $this->ensureIndexesFromAttribute($description); }