diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index b57768ea9d283e8dcec2572c46d9baa998114d1d..6467ee02cc27f1d12099e1fca80ca34f87464888 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -6,6 +6,8 @@ namespace Magento\CatalogSearch\Model\ResourceModel\Advanced; use Magento\Catalog\Model\Product; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\Search\SearchCriteriaBuilder; use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage; /** @@ -23,19 +25,24 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection private $filters = []; /** - * @var \Magento\CatalogSearch\Model\Advanced\Request\Builder + * @var \Magento\Search\Api\SearchInterface */ - private $requestBuilder; + private $search; /** - * @var \Magento\Search\Model\SearchEngine + * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory */ - private $searchEngine; + private $temporaryStorageFactory; /** - * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @var SearchCriteriaBuilder */ - private $temporaryStorageFactory; + private $searchCriteriaBuilder; + + /** + * @var FilterBuilder + */ + private $filterBuilder; /** * Collection constructor. @@ -58,11 +65,12 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement + * @param \Magento\Search\Api\SearchInterface $search * @param \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation $productLimitation - * @param \Magento\CatalogSearch\Model\Advanced\Request\Builder $requestBuilder - * @param \Magento\Search\Model\SearchEngine $searchEngine * @param \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory - * @param \Zend_Db_Adapter_Abstract $connection + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param FilterBuilder $filterBuilder + * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -85,15 +93,17 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection \Magento\Customer\Model\Session $customerSession, \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Customer\Api\GroupManagementInterface $groupManagement, + \Magento\Search\Api\SearchInterface $search, \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation $productLimitation, - \Magento\CatalogSearch\Model\Advanced\Request\Builder $requestBuilder, - \Magento\Search\Model\SearchEngine $searchEngine, \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory, - $connection = null + SearchCriteriaBuilder $searchCriteriaBuilder, + FilterBuilder $filterBuilder, + \Magento\Framework\DB\Adapter\AdapterInterface $connection = null ) { - $this->requestBuilder = $requestBuilder; - $this->searchEngine = $searchEngine; + $this->search = $search; $this->temporaryStorageFactory = $temporaryStorageFactory; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->filterBuilder = $filterBuilder; parent::__construct( $entityFactory, $logger, @@ -140,19 +150,18 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection protected function _renderFiltersBefore() { if ($this->filters) { - $this->requestBuilder->bindDimension('scope', $this->getStoreId()); - $this->requestBuilder->setRequestName('advanced_search_container'); foreach ($this->filters as $attributes) { foreach ($attributes as $attributeCode => $attributeValue) { $attributeCode = $this->getAttributeCode($attributeCode); - $this->requestBuilder->bindRequestValue($attributeCode, $attributeValue); + $this->addAttributeToSearch($attributeCode, $attributeValue); } } - $queryRequest = $this->requestBuilder->create(); - $queryResponse = $this->searchEngine->search($queryRequest); + $searchCriteria = $this->searchCriteriaBuilder->create(); + $searchCriteria->setRequestName('advanced_search_container'); + $searchResult = $this->search->search($searchCriteria); $temporaryStorage = $this->temporaryStorageFactory->create(); - $table = $temporaryStorage->storeDocuments($queryResponse->getIterator()); + $table = $temporaryStorage->storeApiDocuments($searchResult->getItems()); $this->getSelect()->joinInner( [ @@ -162,7 +171,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection [] ); } - return parent::_renderFiltersBefore(); + parent::_renderFiltersBefore(); } /** @@ -178,4 +187,49 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection return $attributeCode; } + + /** + * Create a filter and add it to the SearchCriteriaBuilder. + * + * @param string $attributeCode + * @param array|string $attributeValue + * @return void + */ + private function addAttributeToSearch($attributeCode, $attributeValue) + { + if (isset($attributeValue['from']) || isset($attributeValue['to'])) { + $this->addRangeAttributeToSearch($attributeCode, $attributeValue); + } elseif (!is_array($attributeValue)) { + $this->filterBuilder->setField($attributeCode)->setValue($attributeValue); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } elseif (isset($attributeValue['like'])) { + $this->filterBuilder->setField($attributeCode)->setValue($attributeValue['like']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } elseif (isset($attributeValue['in'])) { + $this->filterBuilder->setField($attributeCode)->setValue($attributeValue['in']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } elseif (isset($attributeValue['in_set'])) { + $this->filterBuilder->setField($attributeCode)->setValue($attributeValue['in_set']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } + } + + /** + * Add attributes that have a range (from,to) to the SearchCriteriaBuilder. + * + * @param string $attributeCode + * @param array|string $attributeValue + * @return void + */ + private function addRangeAttributeToSearch($attributeCode, $attributeValue) + { + if (isset($attributeValue['from']) && '' !== $attributeValue['from']) { + $this->filterBuilder->setField("{$attributeCode}.from")->setValue($attributeValue['from']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } + if (isset($attributeValue['to']) && '' !== $attributeValue['to']) { + $this->filterBuilder->setField("{$attributeCode}.to")->setValue($attributeValue['to']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); + } + } } diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 9b2eb2876b403e1b7cd8ec2837af8cf3a93a6912..a3928cec1a0aaa3d34394caa279b38d05c9b4650 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -8,7 +8,6 @@ namespace Magento\CatalogSearch\Model\ResourceModel\Fulltext; use Magento\Framework\DB\Select; use Magento\Framework\Exception\StateException; use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage; -use Magento\Framework\Search\Response\QueryResponse; /** * Fulltext Collection @@ -16,45 +15,45 @@ use Magento\Framework\Search\Response\QueryResponse; */ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { - /** @var QueryResponse */ - protected $queryResponse; + /** + * @var string + */ + private $queryText; /** - * Catalog search data - * - * @var \Magento\Search\Model\QueryFactory + * @var string|null */ - protected $queryFactory = null; + private $order = null; /** - * @var \Magento\Framework\Search\Request\Builder + * @var string */ - private $requestBuilder; + private $searchRequestName; /** - * @var \Magento\Search\Model\SearchEngine + * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory */ - private $searchEngine; + private $temporaryStorageFactory; /** - * @var string + * @var \Magento\Search\Api\SearchInterface */ - private $queryText; + private $search; /** - * @var string|null + * @var \Magento\Framework\Api\Search\SearchCriteriaBuilder */ - private $order = null; + private $searchCriteriaBuilder; /** - * @var string + * @var \Magento\Framework\Api\Search\SearchResultInterface */ - private $searchRequestName; + private $searchResult; /** - * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory + * @var \Magento\Framework\Api\FilterBuilder */ - private $temporaryStorageFactory; + private $filterBuilder; /** * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory @@ -77,11 +76,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Framework\Stdlib\DateTime $dateTime * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement * @param \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation $productLimitation - * @param \Magento\Search\Model\QueryFactory $catalogSearchData - * @param \Magento\Framework\Search\Request\Builder $requestBuilder - * @param \Magento\Search\Model\SearchEngine $searchEngine * @param \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory - * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection + * @param \Magento\Search\Api\SearchInterface $search + * @param \Magento\Framework\Api\Search\SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Magento\Framework\Api\FilterBuilder $filterBuilder + * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection * @param string $searchRequestName * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -106,14 +105,13 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection \Magento\Framework\Stdlib\DateTime $dateTime, \Magento\Customer\Api\GroupManagementInterface $groupManagement, \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation $productLimitation, - \Magento\Search\Model\QueryFactory $catalogSearchData, - \Magento\Framework\Search\Request\Builder $requestBuilder, - \Magento\Search\Model\SearchEngine $searchEngine, \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory, + \Magento\Search\Api\SearchInterface $search, + \Magento\Framework\Api\Search\SearchCriteriaBuilder $searchCriteriaBuilder, + \Magento\Framework\Api\FilterBuilder $filterBuilder, \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, $searchRequestName = 'catalog_view_container' ) { - $this->queryFactory = $catalogSearchData; parent::__construct( $entityFactory, $logger, @@ -137,10 +135,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection $productLimitation, $connection ); - $this->requestBuilder = $requestBuilder; - $this->searchEngine = $searchEngine; $this->temporaryStorageFactory = $temporaryStorageFactory; $this->searchRequestName = $searchRequestName; + $this->search = $search; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->filterBuilder = $filterBuilder; } /** @@ -152,17 +151,24 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection */ public function addFieldToFilter($field, $condition = null) { - if ($this->queryResponse !== null) { + if ($this->searchResult !== null) { throw new \RuntimeException('Illegal state'); } + if (!is_array($condition) || !in_array(key($condition), ['from', 'to'])) { - $this->requestBuilder->bind($field, $condition); + $this->filterBuilder->setField($field); + $this->filterBuilder->setValue($condition); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } else { if (!empty($condition['from'])) { - $this->requestBuilder->bind("{$field}.from", $condition['from']); + $this->filterBuilder->setField("{$field}.from"); + $this->filterBuilder->setValue($condition['from']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } if (!empty($condition['to'])) { - $this->requestBuilder->bind("{$field}.to", $condition['to']); + $this->filterBuilder->setField("{$field}.to"); + $this->filterBuilder->setValue($condition['to']); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } } return $this; @@ -185,9 +191,10 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection */ protected function _renderFiltersBefore() { - $this->requestBuilder->bindDimension('scope', $this->getStoreId()); if ($this->queryText) { - $this->requestBuilder->bind('search_term', $this->queryText); + $this->filterBuilder->setField('search_term'); + $this->filterBuilder->setValue($this->queryText); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } $priceRangeCalculation = $this->_scopeConfig->getValue( @@ -195,16 +202,17 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); if ($priceRangeCalculation) { - $this->requestBuilder->bind('price_dynamic_algorithm', $priceRangeCalculation); + $this->filterBuilder->setField('price_dynamic_algorithm'); + $this->filterBuilder->setValue($priceRangeCalculation); + $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } - $this->requestBuilder->setRequestName($this->searchRequestName); - $queryRequest = $this->requestBuilder->create(); - - $this->queryResponse = $this->searchEngine->search($queryRequest); + $searchCriteria = $this->searchCriteriaBuilder->create(); + $searchCriteria->setRequestName($this->searchRequestName); + $this->searchResult = $this->search->search($searchCriteria); $temporaryStorage = $this->temporaryStorageFactory->create(); - $table = $temporaryStorage->storeDocuments($this->queryResponse->getIterator()); + $table = $temporaryStorage->storeApiDocuments($this->searchResult->getItems()); $this->getSelect()->joinInner( [ @@ -214,7 +222,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection [] ); - $this->_totalRecords = $this->queryResponse->count(); + $this->_totalRecords = $this->searchResult->getTotalCount(); if ($this->order && 'relevance' === $this->order['field']) { $this->getSelect()->order('search_result.'. TemporaryStorage::FIELD_SCORE . ' ' . $this->order['dir']); @@ -268,7 +276,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection { $this->_renderFilters(); $result = []; - $aggregations = $this->queryResponse->getAggregations(); + $aggregations = $this->searchResult->getAggregations(); $bucket = $aggregations->getBucket($field . '_bucket'); if ($bucket) { foreach ($bucket->getValues() as $value) { diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..353533b9c2e981ef717c3a5a7c6dfbb371c55b02 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php @@ -0,0 +1,145 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogSearch\Test\Unit\Model\ResourceModel\Advanced; + +use Magento\Catalog\Model\Product; +use Magento\CatalogSearch\Test\Unit\Model\ResourceModel\BaseCollectionTest; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +/** + * Tests Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection + */ +class CollectionTest extends BaseCollectionTest +{ + /** + * @var \Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection + */ + private $advancedCollection; + + /** + * @var \Magento\Framework\Api\FilterBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $filterBuilder; + + /** + * @var \Magento\Framework\Api\Search\SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $criteriaBuilder; + + /** + * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $temporaryStorageFactory; + + /** + * @var \Magento\Search\Api\SearchInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $search; + + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + /** + * setUp method for CollectionTest + */ + protected function setUp() + { + $helper = new ObjectManagerHelper($this); + + $this->eavConfig = $this->getMock('Magento\Eav\Model\Config', [], [], '', false); + $storeManager = $this->getStoreManager(); + $universalFactory = $this->getUniversalFactory(); + $this->criteriaBuilder = $this->getCriteriaBuilder(); + $this->filterBuilder = $this->getMock('Magento\Framework\Api\FilterBuilder', [], [], '', false); + $this->temporaryStorageFactory = $this->getMock( + 'Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory', + [], + [], + '', + false + ); + $this->search = $this->getMock('Magento\Search\Api\SearchInterface', [], [], '', false); + + $this->advancedCollection = $helper->getObject( + 'Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection', + [ + 'eavConfig' => $this->eavConfig, + 'storeManager' => $storeManager, + 'universalFactory' => $universalFactory, + 'searchCriteriaBuilder' => $this->criteriaBuilder, + 'filterBuilder' => $this->filterBuilder, + 'temporaryStorageFactory' => $this->temporaryStorageFactory, + 'search' => $this->search, + ] + ); + } + + public function testLoadWithFilterNoFilters() + { + $this->advancedCollection->loadWithFilter(); + } + + /** + * Test a search using 'like' condition + */ + public function testLike() + { + $attributeCode = 'description'; + $attributeCodeId = 42; + $attribute = $this->getMock('Magento\Catalog\Model\ResourceModel\Eav\Attribute', [], [], '', false); + $attribute->expects($this->once())->method('getAttributeCode')->willReturn($attributeCode); + $this->eavConfig->expects($this->once())->method('getAttribute')->with(Product::ENTITY, $attributeCodeId) + ->willReturn($attribute); + $filtersData = ['catalog_product_entity_text' => [$attributeCodeId => ['like' => 'search text']]]; + $this->filterBuilder->expects($this->once())->method('setField')->with($attributeCode) + ->willReturn($this->filterBuilder); + $this->filterBuilder->expects($this->once())->method('setValue')->with('search text') + ->willReturn($this->filterBuilder); + + $filter = $this->getMock('Magento\Framework\Api\Filter'); + $this->filterBuilder->expects($this->once())->method('create')->willReturn($filter); + + $criteria = $this->getMock('Magento\Framework\Api\Search\SearchCriteria', [], [], '', false); + $this->criteriaBuilder->expects($this->once())->method('create')->willReturn($criteria); + $criteria->expects($this->once()) + ->method('setRequestName') + ->with('advanced_search_container'); + + $tempTable = $this->getMock('Magento\Framework\DB\Ddl\Table', [], [], '', false); + $temporaryStorage = $this->getMock( + 'Magento\Framework\Search\Adapter\Mysql\TemporaryStorage', + [], + [], + '', + false + ); + $temporaryStorage->expects($this->once())->method('storeApiDocuments')->willReturn($tempTable); + $this->temporaryStorageFactory->expects($this->once())->method('create')->willReturn($temporaryStorage); + $searchResult = $this->getMock('Magento\Framework\Api\Search\SearchResultInterface', [], [], '', false); + $this->search->expects($this->once())->method('search')->willReturn($searchResult); + + // addFieldsToFilter will load filters, + // then loadWithFilter will trigger _renderFiltersBefore code in Advanced/Collection + $this->assertSame( + $this->advancedCollection, + $this->advancedCollection->addFieldsToFilter($filtersData)->loadWithFilter() + ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getCriteriaBuilder() + { + $criteriaBuilder = $this->getMockBuilder('Magento\Framework\Api\Search\SearchCriteriaBuilder') + ->setMethods(['addFilter', 'create', 'setRequestName']) + ->disableOriginalConstructor() + ->getMock(); + return $criteriaBuilder; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollectionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5d4ba4eef15f9a302ee547f31859fc0f2a90a8ff --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/BaseCollectionTest.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogSearch\Test\Unit\Model\ResourceModel; + +/** + * Base class for Collection tests. + * + * Contains helper methods to get commonly used mocks used for collection tests. + **/ +class BaseCollectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * Get Mocks for StoreManager so Collection can be used. + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getStoreManager() + { + $store = $this->getMockBuilder('Magento\Store\Model\Store') + ->setMethods(['getId']) + ->disableOriginalConstructor() + ->getMock(); + $store->expects($this->once()) + ->method('getId') + ->willReturn(1); + + $storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface') + ->setMethods(['getStore']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $storeManager->expects($this->once()) + ->method('getStore') + ->willReturn($store); + + return $storeManager; + } + + /** + * Get mock for UniversalFactory so Collection can be used. + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getUniversalFactory() + { + $connection = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql') + ->disableOriginalConstructor() + ->setMethods(['select']) + ->getMockForAbstractClass(); + $select = $this->getMockBuilder('Magento\Framework\DB\Select') + ->disableOriginalConstructor() + ->getMock(); + $connection->expects($this->any())->method('select')->willReturn($select); + + $entity = $this->getMockBuilder('Magento\Eav\Model\Entity\AbstractEntity') + ->setMethods(['getConnection', 'getTable', 'getDefaultAttributes', 'getEntityTable']) + ->disableOriginalConstructor() + ->getMock(); + $entity->expects($this->once()) + ->method('getConnection') + ->willReturn($connection); + $entity->expects($this->exactly(2)) + ->method('getTable') + ->willReturnArgument(0); + $entity->expects($this->once()) + ->method('getDefaultAttributes') + ->willReturn(['attr1', 'attr2']); + $entity->expects($this->once()) + ->method('getEntityTable') + ->willReturn('table'); + + $universalFactory = $this->getMockBuilder('Magento\Framework\Validator\UniversalFactory') + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $universalFactory->expects($this->once()) + ->method('create') + ->willReturn($entity); + + return $universalFactory; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php index 616fa2c937b637a9d07f1c62710ef89b3c92260d..ba48fb7c212b15d8f035a5e73d9275eb468299d2 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php @@ -5,16 +5,20 @@ */ namespace Magento\CatalogSearch\Test\Unit\Model\ResourceModel\Fulltext; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use PHPUnit_Framework_TestCase; +use Magento\CatalogSearch\Test\Unit\Model\ResourceModel\BaseCollectionTest; -class CollectionTest extends PHPUnit_Framework_TestCase +class CollectionTest extends BaseCollectionTest { /** * @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection */ private $model; + /** + * @var \Magento\Framework\Api\Filter + */ + private $filter; + /** * setUp method for CollectionTest */ @@ -25,7 +29,8 @@ class CollectionTest extends PHPUnit_Framework_TestCase $storeManager = $this->getStoreManager(); $universalFactory = $this->getUniversalFactory(); $scopeConfig = $this->getScopeConfig(); - $requestBuilder = $this->getRequestBuilder(); + $criteriaBuilder = $this->getCriteriaBuilder(); + $filterBuilder = $this->getFilterBuilder(); $this->model = $helper->getObject( 'Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection', @@ -33,7 +38,8 @@ class CollectionTest extends PHPUnit_Framework_TestCase 'storeManager' => $storeManager, 'universalFactory' => $universalFactory, 'scopeConfig' => $scopeConfig, - 'requestBuilder' => $requestBuilder + 'searchCriteriaBuilder' => $criteriaBuilder, + 'filterBuilder' => $filterBuilder, ] ); } @@ -48,72 +54,6 @@ class CollectionTest extends PHPUnit_Framework_TestCase $this->model->getFacetedData('field'); } - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - protected function getStoreManager() - { - $store = $this->getMockBuilder('Magento\Store\Model\Store') - ->setMethods(['getId']) - ->disableOriginalConstructor() - ->getMock(); - $store->expects($this->once()) - ->method('getId') - ->willReturn(1); - - $storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface') - ->setMethods(['getStore']) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - $storeManager->expects($this->once()) - ->method('getStore') - ->willReturn($store); - - return $storeManager; - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - protected function getUniversalFactory() - { - $connection = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql') - ->disableOriginalConstructor() - ->setMethods(['select']) - ->getMockForAbstractClass(); - $select = $this->getMockBuilder('Magento\Framework\DB\Select') - ->disableOriginalConstructor() - ->getMock(); - $connection->expects($this->any())->method('select')->willReturn($select); - - $entity = $this->getMockBuilder('Magento\Eav\Model\Entity\AbstractEntity') - ->setMethods(['getConnection', 'getTable', 'getDefaultAttributes', 'getEntityTable']) - ->disableOriginalConstructor() - ->getMock(); - $entity->expects($this->once()) - ->method('getConnection') - ->willReturn($connection); - $entity->expects($this->exactly(2)) - ->method('getTable') - ->willReturnArgument(0); - $entity->expects($this->once()) - ->method('getDefaultAttributes') - ->willReturn(['attr1', 'attr2']); - $entity->expects($this->once()) - ->method('getEntityTable') - ->willReturn('table'); - - $universalFactory = $this->getMockBuilder('Magento\Framework\Validator\UniversalFactory') - ->setMethods(['create']) - ->disableOriginalConstructor() - ->getMock(); - $universalFactory->expects($this->once()) - ->method('create') - ->willReturn($entity); - - return $universalFactory; - } - /** * @return \PHPUnit_Framework_MockObject_MockObject */ @@ -133,20 +73,37 @@ class CollectionTest extends PHPUnit_Framework_TestCase /** * @return \PHPUnit_Framework_MockObject_MockObject */ - protected function getRequestBuilder() + protected function getCriteriaBuilder() { - $requestBuilder = $this->getMockBuilder('Magento\Framework\Search\Request\Builder') - ->setMethods(['bind', 'setRequestName']) + $criteriaBuilder = $this->getMockBuilder('Magento\Framework\Api\Search\SearchCriteriaBuilder') + ->setMethods(['addFilter', 'create', 'setRequestName']) ->disableOriginalConstructor() ->getMock(); - $requestBuilder->expects($this->once()) - ->method('bind') - ->withConsecutive(['price_dynamic_algorithm', 1]); - $requestBuilder->expects($this->once()) + $this->filter = new \Magento\Framework\Api\Filter(); + $this->filter->setField('price_dynamic_algorithm'); + $this->filter->setValue(1); + $criteriaBuilder->expects($this->once()) + ->method('addFilter') + ->with($this->filter); + $criteria = $this->getMock('Magento\Framework\Api\Search\SearchCriteria', [], [], '', false); + $criteriaBuilder->expects($this->once())->method('create')->willReturn($criteria); + $criteria->expects($this->once()) ->method('setRequestName') ->withConsecutive(['catalog_view_container']) ->willThrowException(new \Exception('setRequestName', 333)); - return $requestBuilder; + return $criteriaBuilder; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function getFilterBuilder() + { + $filterBuilder = $this->getMock('Magento\Framework\Api\FilterBuilder', [], [], '', false); + $filterBuilder->expects($this->once())->method('setField')->with('price_dynamic_algorithm'); + $filterBuilder->expects($this->once())->method('setValue')->with(1); + $filterBuilder->expects($this->once())->method('create')->willReturn($this->filter); + return $filterBuilder; } } diff --git a/app/code/Magento/Search/Model/Query.php b/app/code/Magento/Search/Model/Query.php index 1cfe0855ba7ee031e24e04a50dfecfa9a6c81348..8caf25f5e3416652b715a534e3a8f1c0327cfac8 100644 --- a/app/code/Magento/Search/Model/Query.php +++ b/app/code/Magento/Search/Model/Query.php @@ -29,8 +29,6 @@ use Magento\Store\Model\StoreManagerInterface; * @method \Magento\Search\Model\Query setPopularity(int $value) * @method string getRedirect() * @method \Magento\Search\Model\Query setRedirect(string $value) - * @method string getSynonymFor() - * @method \Magento\Search\Model\Query setSynonymFor(string $value) * @method int getDisplayInTerms() * @method \Magento\Search\Model\Query setDisplayInTerms(int $value) * @method \Magento\Search\Model\Query setQueryNameExceeded(bool $value) diff --git a/app/code/Magento/Search/Model/SynonymAnalyzer.php b/app/code/Magento/Search/Model/SynonymAnalyzer.php index 65b4f313535af90e1a5b884d32988821ad5aa831..edf24c642dfd4ac27b3e2c12efa907d6f3ef007c 100644 --- a/app/code/Magento/Search/Model/SynonymAnalyzer.php +++ b/app/code/Magento/Search/Model/SynonymAnalyzer.php @@ -6,7 +6,6 @@ namespace Magento\Search\Model; use Magento\Search\Api\SynonymAnalyzerInterface; -use Magento\Search\Model\SynonymReader; class SynonymAnalyzer implements SynonymAnalyzerInterface { @@ -49,17 +48,6 @@ class SynonymAnalyzer implements SynonymAnalyzerInterface return $synGroups; } - // strip off all the white spaces, comma, semicolons, and other such - // "non-word" characters. Then implode it into a single string using white space as delimiter - //$words = preg_split('/\W+/', strtolower($phrase), -1, PREG_SPLIT_NO_EMPTY); - $words = preg_split( - '/[~`!@#$%^&*()_+={}\[\]:"\',\s\.<>?\/\;\\\]+/', - strtolower($phrase), - -1, - PREG_SPLIT_NO_EMPTY - ); - $phrase = implode(' ', $words); - $rows = $this->synReaderModel->loadByPhrase($phrase)->getData(); $synonyms = []; foreach ($rows as $row) { @@ -68,6 +56,7 @@ class SynonymAnalyzer implements SynonymAnalyzerInterface // Go through every returned record looking for presence of the actual phrase. If there were no matching // records found in DB then create a new entry for it in the returned array + $words = explode(' ', $phrase); foreach ($words as $w) { $position = $this->findInArray($w, $synonyms); if ($position !== false) { diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymMassActionNotOnFrontend.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymMassActionNotOnFrontend.php deleted file mode 100644 index f2c85da12c413462826727951c43315ae24d1c25..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymMassActionNotOnFrontend.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\CatalogSearch\Test\Constraint; - -use Magento\Cms\Test\Page\CmsIndex; -use Magento\Mtf\Client\BrowserInterface; -use Magento\Mtf\Constraint\AbstractConstraint; - -/** - * Class AssertSearchSynonymMassActionNotOnFrontend - * Assert that you will be not redirected to url from dataset after mass delete search term - */ -class AssertSearchSynonymMassActionNotOnFrontend extends AbstractConstraint -{ - /** - * Assert that you will be not redirected to url from dataset after mass delete search term - * - * @param array $searchTerms - * @param CmsIndex $cmsIndex - * @param BrowserInterface $browser - * @param AssertSearchSynonymNotOnFrontend $assertSearchSynonymNotOnFrontend - * @return void - */ - public function processAssert( - array $searchTerms, - CmsIndex $cmsIndex, - BrowserInterface $browser, - AssertSearchSynonymNotOnFrontend $assertSearchSynonymNotOnFrontend - ) { - foreach ($searchTerms as $term) { - $assertSearchSynonymNotOnFrontend->processAssert($cmsIndex, $browser, $term); - } - } - - /** - * Returns a string representation of the object - * - * @return string - */ - public function toString() - { - return 'All search terms were successfully removed (redirect by the synonym was not performed).'; - } -} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymNotOnFrontend.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymNotOnFrontend.php deleted file mode 100644 index 48560a9c3d99679016083d95ded520c13cf0cdf3..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchSynonymNotOnFrontend.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\CatalogSearch\Test\Constraint; - -use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; -use Magento\Cms\Test\Page\CmsIndex; -use Magento\Mtf\Client\BrowserInterface; -use Magento\Mtf\Constraint\AbstractConstraint; - -/** - * Class AssertSearchSynonymNotOnFrontend - * Assert that you will be not redirected to url from dataset - */ -class AssertSearchSynonymNotOnFrontend extends AbstractConstraint -{ - /** - * Assert that you will be not redirected to url from dataset - * - * @param CmsIndex $cmsIndex - * @param CatalogSearchQuery $searchTerm - * @param BrowserInterface $browser - * @return void - */ - public function processAssert(CmsIndex $cmsIndex, BrowserInterface $browser, CatalogSearchQuery $searchTerm) - { - $cmsIndex->open()->getSearchBlock()->search($searchTerm->getSynonymFor()); - \PHPUnit_Framework_Assert::assertNotEquals( - $browser->getUrl(), - $searchTerm->getRedirect(), - 'Url in the browser corresponds to Url in fixture (redirect has been performed).' - . PHP_EOL . 'Search term: "' . $searchTerm->getQueryText() . '"' - ); - } - - /** - * Returns a string representation of the object - * - * @return string - */ - public function toString() - { - return 'Search term was successfully removed (redirect by the synonym was not performed).'; - } -} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php deleted file mode 100644 index 50201b69a9246f69e3794785bce888759d0c94ec..0000000000000000000000000000000000000000 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSearchTermSynonymOnFrontend.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\CatalogSearch\Test\Constraint; - -use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery; -use Magento\Cms\Test\Page\CmsIndex; -use Magento\Mtf\Client\BrowserInterface; -use Magento\Mtf\Constraint\AbstractConstraint; - -/** - * Class AssertSearchTermSynonymOnFrontend - * Assert that you will be redirected to url from dataset - */ -class AssertSearchTermSynonymOnFrontend extends AbstractConstraint -{ - /** - * Assert that you will be redirected to url from dataset - * - * @param CmsIndex $cmsIndex - * @param BrowserInterface $browser - * @param CatalogSearchQuery $searchTerm - * @return void - */ - public function processAssert(CmsIndex $cmsIndex, BrowserInterface $browser, CatalogSearchQuery $searchTerm) - { - $cmsIndex->open()->getSearchBlock()->search($searchTerm->getSynonymFor()); - $windowUrl = $browser->getUrl(); - $redirectUrl = $searchTerm->getRedirect(); - \PHPUnit_Framework_Assert::assertEquals( - $windowUrl, - $redirectUrl, - 'Redirect by synonym was not executed.' - . PHP_EOL . "Expected: " . $redirectUrl - . PHP_EOL . "Actual: " . $windowUrl - ); - } - - /** - * Returns a string representation of the object - * - * @return string - */ - public function toString() - { - return 'Redirect by synonym executed successfully.'; - } -} diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml index 7e5c9ee780ea9e2b76488d5a61393d8581534b4b..b2f6ce23ed5bb20272a5ed2873f416ab6b49d426 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml @@ -16,7 +16,6 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermInGrid" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermForm" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermOnFrontend" /> - <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSynonymOnFrontend" /> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml index bf457cb2ecaacbb41d9362a25af3f186f8f0c889..60fdbd73dd2c7dd5714d293b583bc70372e43809 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml @@ -12,7 +12,6 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSuccessDeleteMessage" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermNotInGrid" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermNotOnFrontend" /> - <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchSynonymNotOnFrontend" /> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml index dd1256b01001bc42ffdb9091b3ca8516f857ced5..6353e384d2f959b7b6bcef511d1002d08d364d55 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml @@ -12,7 +12,6 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSuccessMassDeleteMessage" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermMassActionsNotInGrid" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermMassActionNotOnFrontend" /> - <constraint name="Magento\CatalogSearch\Test\Constraint\AssertSearchSynonymMassActionNotOnFrontend" /> </variation> </testCase> </config> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/di.xml index beffc1bab00bb5170cfc32aa5ec5fe509da6b3d1..d0a393aa01007c04efc304037c886818e5a06c5e 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/di.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/di.xml @@ -42,11 +42,6 @@ <argument name="severity" xsi:type="string">high</argument> </arguments> </type> - <type name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSynonymOnFrontend"> - <arguments> - <argument name="severity" xsi:type="string">high</argument> - </arguments> - </type> <type name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSuccessDeleteMessage"> <arguments> <argument name="severity" xsi:type="string">high</argument> @@ -62,11 +57,6 @@ <argument name="severity" xsi:type="string">high</argument> </arguments> </type> - <type name="Magento\CatalogSearch\Test\Constraint\AssertSearchSynonymNotOnFrontend"> - <arguments> - <argument name="severity" xsi:type="string">high</argument> - </arguments> - </type> <type name="Magento\CatalogSearch\Test\Constraint\AssertSearchTermSuccessMassDeleteMessage"> <arguments> <argument name="severity" xsi:type="string">high</argument> @@ -82,11 +72,6 @@ <argument name="severity" xsi:type="string">high</argument> </arguments> </type> - <type name="Magento\CatalogSearch\Test\Constraint\AssertSearchSynonymMassActionNotOnFrontend"> - <arguments> - <argument name="severity" xsi:type="string">high</argument> - </arguments> - </type> <type name="Magento\CatalogSearch\Test\Constraint\AssertProductCanBeOpenedFromSearchResult"> <arguments> <argument name="severity" xsi:type="string">high</argument> diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php index ef59ef422de2387583c7b21ae4b9e5368a0d642a..04c4002b971255e313b7ce7185816b3a20db5582 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/Builder/Query/MatchTest.php @@ -29,11 +29,11 @@ class MatchTest extends \PHPUnit_Framework_TestCase */ public function testBuildQuery($conditionType, $expectedSuffix) { - $conditionPattern = "(LEAST((MATCH (data_index) AGAINST ('%ssomevalue*' IN BOOLEAN MODE)), 1000000)" + $conditionPattern = "(LEAST((MATCH (data_index) AGAINST ('%ssomeValue*' IN BOOLEAN MODE)), 1000000)" . " * POW(2, %s)) AS score"; $expectedScoreCondition = sprintf($conditionPattern, $expectedSuffix, ScoreBuilder::WEIGHT_FIELD); $expectedSql = "SELECT `someTable`.* FROM `someTable` WHERE (MATCH (data_index) " . - "AGAINST ('{$expectedSuffix}somevalue*' IN BOOLEAN MODE))"; + "AGAINST ('{$expectedSuffix}someValue*' IN BOOLEAN MODE))"; /** @var \Magento\Framework\Search\Adapter\Mysql\ScoreBuilder $scoreBuilder */ $scoreBuilder = $this->objectManager->create('Magento\Framework\Search\Adapter\Mysql\ScoreBuilder'); diff --git a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php index 99aa10d6e7cd029b5db3a093da53d6fbf5fd535d..9980f94a92ab564f1c806f57e79199788be7139c 100644 --- a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php +++ b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php @@ -31,64 +31,25 @@ class SynonymAnalyzerTest extends \PHPUnit_Framework_TestCase { return [ 'WithSynonymsFromStoreViewScope' => [ - 'phrase' => 'Elizabeth is the English queen.', + 'phrase' => 'elizabeth is the english queen', 'expectedResult' => [['elizabeth'],['is'],['the'],['british', 'english'],['queen', 'monarch']] ], 'WithSynonymsFromWebsiteScope' => [ - 'phrase' => 'Orange hill', + 'phrase' => 'orange hill', 'expectedResult' => [['orange', 'magento'], ['hill', 'mountain', 'peak']] ], 'WithSynonymsFromDefaultScope' => [ - 'phrase' => 'universe is enormous.', + 'phrase' => 'universe is enormous', 'expectedResult' => [['universe', 'cosmos'], ['is'], ['big', 'huge', 'large', 'enormous']] ], 'noSynonyms' => [ - 'phrase' => 'This sentence has no synonyms', + 'phrase' => 'this sentence has no synonyms', 'expectedResult' => [['this'], ['sentence'], ['has'], ['no'], ['synonyms']] ], - 'specialCharacters' => [ - 'phrase' => '~tilde`backtic! exclamation@ at#hash\$dollar%percent^carat&ersand*star(leftparan' - . ')rightparan_underscore+plus=equal{leftcurly}rightcurly[leftbracket]rightbracket:colon' - . '"doublequote\'singlequote,comma space.period<leftangle>rightangle?questionmark\\backslash' - . '/forwardslash tab;semicolon', - 'expectedResult' => [ - ['tilde'], - ['backtic'], - ['exclamation'], - ['at'], - ['hash'], - ['dollar'], - ['percent'], - ['carat'], - ['ampersand'], - ['star'], - ['leftparan'], - ['rightparan'], - ['underscore'], - ['plus'], - ['equal'], - ['leftcurly'], - ['rightcurly'], - ['leftbracket'], - ['rightbracket'], - ['colon'], - ['doublequote'], - ['singlequote'], - ['comma'], - ['space'], - ['period'], - ['leftangle'], - ['rightangle'], - ['questionmark'], - ['backslash'], - ['forwardslash'], - ['tab'], - ['semicolon'] - ] - ], 'oneMoreTest' => [ 'phrase' => 'schlicht', - 'expectedResult' => [['schlicht', 'natürlich']]] + 'expectedResult' => [['schlicht', 'natürlich']] + ], ]; } diff --git a/lib/internal/Magento/Framework/App/Config/Data.php b/lib/internal/Magento/Framework/App/Config/Data.php index 38389e71e40aaf297d4983bdde8377db615d5493..6409f53f98106e88e19a5f36cf3e0d9d3470201e 100644 --- a/lib/internal/Magento/Framework/App/Config/Data.php +++ b/lib/internal/Magento/Framework/App/Config/Data.php @@ -29,7 +29,8 @@ class Data implements DataInterface */ public function __construct(MetadataProcessor $processor, array $data) { - $this->_data = $processor->process($data); + /** Clone the array to work around a kink in php7 that modifies the argument by reference */ + $this->_data = $processor->process($this->arrayClone($data)); $this->_source = $data; } @@ -77,4 +78,19 @@ class Data implements DataInterface } $currentElement[$lastKey] = $value; } + + /** + * Copy array by value + * + * @param array $data + * @return array + */ + private function arrayClone(array $data) + { + $clone = []; + foreach ($data as $key => $value) { + $clone[$key]= $value; + } + return $clone; + } } diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php index a01690cf580d03ec7824301412913a75cfc161ed..8a9e28c7d13a8f9cf8559d041b6698fde4ff3a5c 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/TemporaryStorage.php @@ -31,6 +31,8 @@ class TemporaryStorage } /** + * Stores Documents + * * @param \ArrayIterator|\Magento\Framework\Search\Document[] $documents * @return Table */ @@ -44,7 +46,38 @@ class TemporaryStorage ]; } - $table = $this->createTemporaryTable(); + return $this->populateTemporaryTable($this->createTemporaryTable(), $data); + } + + /** + * Stores Api type Documents + * + * @param \Magento\Framework\Api\Search\DocumentInterface[] $documents + * @return Table + */ + public function storeApiDocuments($documents) + { + $data = []; + foreach ($documents as $document) { + $data[] = [ + $document->getId(), + $document->getCustomAttribute('score')->getValue(), + ]; + } + + return $this->populateTemporaryTable($this->createTemporaryTable(), $data); + } + + /** + * Populates temporary table + * + * @param Table $table + * @param array $data + * @return Table + * @throws \Zend_Db_Exception + */ + private function populateTemporaryTable(Table $table, $data) + { if (count($data)) { $this->getConnection()->insertArray( $table->getName(), diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/TemporaryStorageTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/TemporaryStorageTest.php index cdbcd2e2c47fbcf3ccfa38fd3bb93b49bd03d21c..4a3421a5ffaab995010cde5bfed98dfec76a8401 100644 --- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/TemporaryStorageTest.php +++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/TemporaryStorageTest.php @@ -108,6 +108,36 @@ class TemporaryStorageTest extends \PHPUnit_Framework_TestCase $this->assertEquals($result, $table); } + public function testStoreApiDocuments() + { + $documentId = 312432; + $documentValue = 1.235123; + + $attributeValue = $this->getMockBuilder('Magento\Framework\Api\AttributeValue') + ->disableOriginalConstructor() + ->getMock(); + $attributeValue->expects($this->once()) + ->method('getValue') + ->willReturn($documentValue); + + $document = $this->getMockBuilder('Magento\Framework\Api\Search\Document') + ->disableOriginalConstructor() + ->getMock(); + $document->expects($this->once()) + ->method('getId') + ->willReturn($documentId); + $document->expects($this->once()) + ->method('getCustomAttribute') + ->with('score') + ->willReturn($attributeValue); + + $table = $this->createTemporaryTable(); + + $result = $this->model->storeApiDocuments([$document]); + + $this->assertEquals($result, $table); + } + /** * @return \Magento\Framework\DB\Ddl\Table|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/InterceptorSubstitution.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/InterceptorSubstitution.php index 324a7724702249636f737011142a2f8db0c95c09..32d0ced001000699e9a10175ce99f1679c00f5a3 100644 --- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/InterceptorSubstitution.php +++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/InterceptorSubstitution.php @@ -38,12 +38,9 @@ class InterceptorSubstitution implements ModificationInterface } $config['preferences'] = $this->resolvePreferences($config['preferences'], $interceptors); - - $config['preferences'] = array_merge($config['preferences'], $interceptors); + $config['preferences'] = array_merge($interceptors, $config['preferences']); $config['instanceTypes'] = $this->resolvePreferences($config['instanceTypes'], $interceptors); - - return $config; } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/InterceptorSubstitutionTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/InterceptorSubstitutionTest.php index 9376f8334a02dcb0455581513d591ff17a628c48..1a757c47b8c163117342f43c391023050200bd53 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/InterceptorSubstitutionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/InterceptorSubstitutionTest.php @@ -24,6 +24,36 @@ class InterceptorSubstitutionTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->getOutputConfig(), $modifier->modify($this->getInputConfig())); } + public function testModifyPreferences() + { + $inputConfig = [ + 'arguments' => [ + 'ClassReplaced' => [], + 'ClassReplacement' => [], + 'ClassReplaced\Interceptor' => [], + 'ClassReplacement\Interceptor' => [] + ], + 'preferences' => [ + 'ClassReplaced' => 'ClassReplacement' + ], + 'instanceTypes' => [] + ]; + + $outputConfig = [ + 'arguments' => [ + 'ClassReplaced\Interceptor' => [], + 'ClassReplacement\Interceptor' => [] + ], + 'preferences' => [ + 'ClassReplaced' => 'ClassReplacement\Interceptor', + 'ClassReplacement' => 'ClassReplacement\Interceptor' + ], + 'instanceTypes' => [] + ]; + + $modifier = new InterceptorSubstitution(); + $this->assertEquals($outputConfig, $modifier->modify($inputConfig)); + } /** * Input config