예제 #1
0
 /**
  * @param FilterInterface $filter
  * @param bool $isNegation
  * @param string $query
  * @return string
  */
 private function processQueryWithField(FilterInterface $filter, $isNegation, $query)
 {
     /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
     $attribute = $this->config->getAttribute(Product::ENTITY, $filter->getField());
     if ($filter->getField() === 'price') {
         $resultQuery = str_replace($this->connection->quoteIdentifier('price'), $this->connection->quoteIdentifier('price_index.min_price'), $query);
     } elseif ($filter->getField() === 'category_ids') {
         return 'category_ids_index.category_id = ' . $filter->getValue();
     } elseif ($attribute->isStatic()) {
         $alias = $this->tableMapper->getMappingAlias($filter);
         $resultQuery = str_replace($this->connection->quoteIdentifier($attribute->getAttributeCode()), $this->connection->quoteIdentifier($alias . '.' . $attribute->getAttributeCode()), $query);
     } elseif ($filter->getType() === FilterInterface::TYPE_TERM && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true)) {
         $alias = $this->tableMapper->getMappingAlias($filter);
         if (is_array($filter->getValue())) {
             $value = sprintf('%s IN (%s)', $isNegation ? 'NOT' : '', implode(',', $filter->getValue()));
         } else {
             $value = ($isNegation ? '!' : '') . '= ' . $filter->getValue();
         }
         $resultQuery = sprintf('%1$s.value %2$s', $alias, $value);
     } else {
         $table = $attribute->getBackendTable();
         $select = $this->connection->select();
         $ifNullCondition = $this->connection->getIfNullSql('current_store.value', 'main_table.value');
         $currentStoreId = $this->scopeResolver->getScope()->getId();
         $select->from(['main_table' => $table], 'entity_id')->joinLeft(['current_store' => $table], 'current_store.attribute_id = main_table.attribute_id AND current_store.store_id = ' . $currentStoreId, null)->columns([$filter->getField() => $ifNullCondition])->where('main_table.attribute_id = ?', $attribute->getAttributeId())->where('main_table.store_id = ?', Store::DEFAULT_STORE_ID)->having($query);
         $resultQuery = 'search_index.entity_id IN (
             select entity_id from  ' . $this->conditionManager->wrapBrackets($select) . ' as filter
         )';
     }
     return $resultQuery;
 }
예제 #2
0
 /**
  * {@inheritdoc}
  */
 public function buildFilter(\Magento\Framework\Search\Request\FilterInterface $filter)
 {
     $adapter = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
     /** @var \Magento\Framework\Search\Request\Filter\Term $filter */
     $condition = sprintf('%s = %s', $filter->getField(), $adapter->quote($filter->getValue()));
     return $condition;
 }
예제 #3
0
 /**
  * @param RequestFilterInterface|\Magento\Framework\Search\Request\Filter\Bool $filter
  * @param bool $isNegation
  * @return string
  */
 private function processBoolFilter(RequestFilterInterface $filter, $isNegation)
 {
     $must = $this->buildFilters($filter->getMust(), Select::SQL_AND, $isNegation);
     $should = $this->buildFilters($filter->getShould(), Select::SQL_OR, $isNegation);
     $mustNot = $this->buildFilters($filter->getMustNot(), Select::SQL_AND, !$isNegation);
     $queries = [$must, $this->conditionManager->wrapBrackets($should), $this->conditionManager->wrapBrackets($mustNot)];
     return $this->conditionManager->combineQueries($queries, Select::SQL_AND);
 }
예제 #4
0
 protected function processFilter(RequestFilterInterface $filter, DataObject $params, $conditionType)
 {
     if ($filter->getType() == RequestFilterInterface::TYPE_TERM) {
         $filters = $params->hasFilters() ? $params->getFilters() : [];
         $filters[$filter->getField()] = $filter->getValue();
         $params->setFilters($filters);
     }
     /* ignore otherwise */
 }
예제 #5
0
 /**
  * @param FilterInterface $filter
  * @param bool $isNegation
  * @param string $query
  * @param QueryContainer $queryContainer
  * @return string
  */
 private function processQueryWithField(FilterInterface $filter, $isNegation, $query, QueryContainer $queryContainer)
 {
     $currentStoreId = $this->scopeResolver->getScope()->getId();
     $attribute = $this->config->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $filter->getField());
     $select = $this->getConnection()->select();
     $table = $attribute->getBackendTable();
     if ($filter->getField() == 'price') {
         $query = str_replace('price', 'min_price', $query);
         $select->from(['main_table' => $this->resource->getTableName('catalog_product_index_price')], 'entity_id')->where($query);
     } elseif ($filter->getField() == 'category_ids') {
         return 'category_index.category_id = ' . $filter->getValue();
     } else {
         if ($attribute->isStatic()) {
             $select->from(['main_table' => $table], 'entity_id')->where($query);
         } else {
             if ($filter->getType() == FilterInterface::TYPE_TERM) {
                 if (is_array($filter->getValue())) {
                     $value = sprintf('%s IN (%s)', $isNegation ? 'NOT' : '', implode(',', $filter->getValue()));
                 } else {
                     $value = ($isNegation ? '!' : '') . '= ' . $filter->getValue();
                 }
                 $filterQuery = sprintf('cpie.store_id = %d AND cpie.attribute_id = %d AND cpie.value %s', $this->scopeResolver->getScope()->getId(), $attribute->getId(), $value);
                 $queryContainer->addFilter($filterQuery);
                 return '';
             }
             $ifNullCondition = $this->getConnection()->getIfNullSql('current_store.value', 'main_table.value');
             $select->from(['main_table' => $table], 'entity_id')->joinLeft(['current_store' => $table], 'current_store.attribute_id = main_table.attribute_id AND current_store.store_id = ' . $currentStoreId, null)->columns([$filter->getField() => $ifNullCondition])->where('main_table.attribute_id = ?', $attribute->getAttributeId())->where('main_table.store_id = ?', \Magento\Store\Model\Store::DEFAULT_STORE_ID)->having($query);
         }
     }
     return 'search_index.entity_id IN (
         select entity_id from  ' . $this->conditionManager->wrapBrackets($select) . ' as filter
         )';
 }
예제 #6
0
 /**
  * Returns mapping data for field in format: [
  *  'table_alias',
  *  'table',
  *  'join_condition',
  *  ['fields']
  * ]
  * @param FilterInterface $filter
  * @return array
  */
 private function getMappingData(FilterInterface $filter)
 {
     $alias = null;
     $table = null;
     $mapOn = null;
     $mappedFields = null;
     $field = $filter->getField();
     $fieldToTableMap = $this->getFieldToTableMap($field);
     if ($fieldToTableMap) {
         list($alias, $table, $mapOn, $mappedFields) = $fieldToTableMap;
         $table = $this->resource->getTableName($table);
     } elseif ($attribute = $this->getAttributeByCode($field)) {
         if ($filter->getType() === FilterInterface::TYPE_TERM && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true)) {
             $table = $this->resource->getTableName('catalog_product_index_eav');
             $alias = $field . '_filter';
             $mapOn = sprintf('search_index.entity_id = %1$s.entity_id AND %1$s.attribute_id = %2$d AND %1$s.store_id = %3$d', $alias, $attribute->getId(), $this->getStoreId());
             $mappedFields = [];
         } elseif ($attribute->getBackendType() === AbstractAttribute::TYPE_STATIC) {
             $table = $attribute->getBackendTable();
             $alias = $field . '_filter';
             $mapOn = 'search_index.entity_id = ' . $alias . '.entity_id';
             $mappedFields = null;
         }
     }
     return [$alias, $table, $mapOn, $mappedFields];
 }
예제 #7
0
 /**
  * @param FilterInterface $filter
  * @param bool $isNegation
  * @param string $query
  * @return string
  * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  */
 private function processQueryWithField(FilterInterface $filter, $isNegation, $query)
 {
     $currentStoreId = $this->scopeResolver->getScope()->getId();
     $attribute = $this->config->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $filter->getField());
     $select = $this->getSelect();
     $table = $attribute->getBackendTable();
     if ($filter->getField() == 'price') {
         $query = str_replace('price', 'min_price', $query);
         $select->from(['main_table' => $this->resource->getTableName('catalog_product_index_price')], 'entity_id')->where($query);
     } elseif ($filter->getField() == 'category_ids') {
         return 'category_index.category_id = ' . $filter->getValue();
     } else {
         if ($attribute->isStatic()) {
             $select->from(['main_table' => $table], 'entity_id')->where($query);
         } else {
             if ($filter->getType() == FilterInterface::TYPE_TERM) {
                 $field = $filter->getField();
                 $mapper = function ($value) use($field, $isNegation) {
                     return ($isNegation ? '-' : '') . $this->attributePrefix . $field . '_' . $value;
                 };
                 if (is_array($filter->getValue())) {
                     $value = implode(' ', array_map($mapper, $filter->getValue()));
                 } else {
                     $value = $mapper($filter->getValue());
                 }
                 return 'MATCH (data_index) AGAINST (' . $this->getConnection()->quote($value) . ' IN BOOLEAN MODE)';
             }
             $ifNullCondition = $this->getConnection()->getIfNullSql('current_store.value', 'main_table.value');
             $select->from(['main_table' => $table], 'entity_id')->joinLeft(['current_store' => $table], 'current_store.attribute_id = main_table.attribute_id AND current_store.store_id = ' . $currentStoreId, null)->columns([$filter->getField() => $ifNullCondition])->where('main_table.attribute_id = ?', $attribute->getAttributeId())->where('main_table.store_id = ?', \Magento\Store\Model\Store::DEFAULT_STORE_ID)->having($query);
         }
     }
     return 'search_index.product_id IN (
         select entity_id from  ' . $this->conditionManager->wrapBrackets($select) . ' as filter
         )';
 }
예제 #8
0
 /**
  * {@inheritdoc}
  */
 public function build(RequestFilterInterface $filter)
 {
     switch ($filter->getType()) {
         case RequestFilterInterface::TYPE_BOOL:
             /** @var \Magento\Framework\Search\Request\Filter\Bool $filter */
             $queries = [];
             $must = $this->buildFilters($filter->getMust(), Select::SQL_AND);
             if (!empty($must)) {
                 $queries[] = $must;
             }
             $should = $this->buildFilters($filter->getShould(), Select::SQL_OR);
             if (!empty($should)) {
                 $queries[] = $this->wrapBrackets($should);
             }
             $mustNot = $this->buildFilters($filter->getMustNot(), Select::SQL_AND);
             if (!empty($mustNot)) {
                 $queries[] = '!' . $this->wrapBrackets($mustNot);
             }
             $query = $this->generateQuery($queries, Select::SQL_AND);
             break;
         case RequestFilterInterface::TYPE_TERM:
             /** @var \Magento\Framework\Search\Request\Filter\Term $filter */
             $query = $this->term->buildFilter($filter);
             break;
         case RequestFilterInterface::TYPE_RANGE:
             /** @var \Magento\Framework\Search\Request\Filter\Range $filter */
             $query = $this->range->buildFilter($filter);
             break;
         default:
             throw new \InvalidArgumentException(sprintf('Unknown filter type \'%s\'', $filter->getType()));
     }
     return $this->wrapBrackets($query);
 }
예제 #9
0
 public function testProcessNotStaticAttribute()
 {
     $expectedResult = 'search_index.entity_id IN (select entity_id from (TEST QUERY PART) as filter)';
     $scopeId = 0;
     $isNegation = false;
     $query = 'SELECT field FROM table';
     $attributeId = 1234567;
     $this->scope->expects($this->once())->method('getId')->will($this->returnValue($scopeId));
     $this->filter->expects($this->exactly(4))->method('getField')->will($this->returnValue('not_static_attribute'));
     $this->config->expects($this->exactly(1))->method('getAttribute')->with(\Magento\Catalog\Model\Product::ENTITY, 'not_static_attribute')->will($this->returnValue($this->attribute));
     $this->attribute->expects($this->once())->method('isStatic')->will($this->returnValue(false));
     $this->attribute->expects($this->once())->method('getBackendTable')->will($this->returnValue('backend_table'));
     $this->attribute->expects($this->once())->method('getAttributeId')->will($this->returnValue($attributeId));
     $this->connection->expects($this->once())->method('getIfNullSql')->with('current_store.value', 'main_table.value')->will($this->returnValue('IF NULL SQL'));
     $this->select->expects($this->once())->method('from')->with(['main_table' => 'backend_table'], 'entity_id')->will($this->returnSelf());
     $this->select->expects($this->once())->method('joinLeft')->with(['current_store' => 'backend_table'])->will($this->returnSelf());
     $this->select->expects($this->once())->method('columns')->with(['not_static_attribute' => 'IF NULL SQL'])->will($this->returnSelf());
     $this->select->expects($this->exactly(2))->method('where')->will($this->returnSelf());
     $this->select->expects($this->once())->method('__toString')->will($this->returnValue('TEST QUERY PART'));
     $actualResult = $this->target->process($this->filter, $isNegation, $query);
     $this->assertSame($expectedResult, $this->removeWhitespaces($actualResult));
 }
예제 #10
0
 /**
  * @param RequestFilterInterface|RangeFilterRequest $filter
  * @param bool $isNegation
  * @return string
  */
 private function getRightConditionPart(RequestFilterInterface $filter, $isNegation)
 {
     return $this->getPart($filter->getField(), $isNegation ? self::CONDITION_PART_GREATER_THAN : self::CONDITION_PART_LOWER_THAN, $filter->getTo());
 }
예제 #11
0
 /**
  * @param \Magento\Framework\Search\Request\FilterInterface $filter
  * @return \Magento\Framework\DB\Select
  */
 public function buildFilter(\Magento\Framework\Search\Request\FilterInterface $filter)
 {
     $adapter = $this->resource->getConnection(Resource::DEFAULT_READ_RESOURCE);
     /** @var \Magento\Framework\Search\Request\Filter\Range $filter */
     return $this->generateCondition($filter->getField(), $filter->getFrom(), $filter->getTo(), $adapter);
 }
예제 #12
0
 /**
  * @param FilterInterface $filter
  * @param string $query
  * @param Attribute $attribute
  * @return string
  */
 private function processRangeNumeric(FilterInterface $filter, $query, $attribute)
 {
     $tableSuffix = $attribute->getBackendType() === 'decimal' ? '_decimal' : '';
     $table = $this->resource->getTableName("catalog_product_index_eav{$tableSuffix}");
     $select = $this->connection->select();
     $currentStoreId = $this->scopeResolver->getScope()->getId();
     $select->from(['main_table' => $table], 'entity_id')->columns([$filter->getField() => 'main_table.value'])->where('main_table.attribute_id = ?', $attribute->getAttributeId())->where('main_table.store_id = ?', $currentStoreId)->having($query);
     $resultQuery = 'search_index.entity_id IN (
             select entity_id from  ' . $this->conditionManager->wrapBrackets($select) . ' as filter
         )';
     return $resultQuery;
 }
예제 #13
0
 /**
  * {@inheritdoc}
  */
 public function buildFilter(RequestFilterInterface $filter, $isNegation)
 {
     /** @var \Magento\Framework\Search\Request\Filter\Term $filter */
     return $this->conditionManager->generateCondition($filter->getField(), $this->getConditionOperator($filter->getValue(), $isNegation), $filter->getValue());
 }
예제 #14
0
 /**
  * {@inheritdoc}
  */
 public function buildFilter(\Magento\Framework\Search\Request\FilterInterface $filter, $isNegation)
 {
     /** @var \Magento\Framework\Search\Request\Filter\Wildcard $filter */
     $searchValue = '%' . $filter->getValue() . '%';
     return $this->conditionManager->generateCondition($filter->getField(), $isNegation ? self::CONDITION_NOT_LIKE : self::CONDITION_LIKE, $searchValue);
 }